Как развернуть сценарии SQL через CI / CD Azure? - PullRequest
0 голосов
/ 10 апреля 2019

У нас есть набор сценариев SQL (файлы .sql), которые мы вручную внедряем с одного сервера на другой сервер.

Все сценарии SQL управляются с помощью проекта SQL в Azure.

Как развернуть сценарии SQL через CI / CD Azure?

1 Ответ

1 голос
/ 10 апреля 2019

При управлении схемами баз данных и способах их продвижения в ваших средах следует одинаково учитывать развертывание приложений и инфраструктуры. Вот несколько рекомендаций высокого уровня.

  1. Контроль версий - Вам нужно будет поставить свои скрипты в систему контроля версий. Если вы используете DevOps Azure, используйте Git-репозиторий для хранения всех созданных скриптов. Более того, они нужны нам для контроля исходного кода, чтобы наши инструменты CI / CD могли справиться с этим. Если вы администратор, и это звучит странно для вас, извините, вам придется к этому привыкнуть.

    1b. Включить Pull Requests - Сконфигурируйте ваш исходный репозиторий так, чтобы он принимал изменения только из Pull-запроса. Это гарантирует, что изменения вашей схемы проверяются до того, как они будут приняты в хранилище. Улучшает обмен знаниями для группы и улучшает общее качество, так как она может ловить ошибки до того, как они будут развернуты.

  2. Безопасность - заблокируйте базу данных, чтобы случайные пользователи не могли развертывать случайные изменения. Создайте отдельную учетную запись для применения изменений схемы базы данных и предоставьте только учетные данные для инструмента непрерывной доставки. Согласно этой модели, если она не находится в управлении исходным кодом, она не существует. Наш инструмент CI / CD будет отвечать за развертывание этих изменений для нас.

  3. Используйте инструмент - и прекратите делать это вручную! Наша команда выбрала инфраструктуру с открытым исходным кодом под названием db-migrate , которая управляет изменениями в схемах базы данных. Мы выбрали db-migrate, потому что он с открытым исходным кодом и работает на разных платформах. Microsoft использует EntryFramework Code-First Migrations , на котором основана db-migrate.

    Как работают миграции: по сути, каждый раз, когда вам нужно изменить базу данных, вы создаете «миграцию», которая включает изменения вашего сценария SQL. Когда инструмент запускается для вашей базы данных, он создает таблицу в базе данных, чтобы отслеживать, какие миграции были выполнены ранее, поэтому он запускает только новые миграции. Короче говоря, миграция должна быть неразрушающей, чтобы предотвратить потерю данных, и сценарии следует считать доступными только для чтения после их применения к любой базе данных. (Вы никогда не должны изменять sql-скрипт миграции после его использования; вместо этого создайте новую миграцию)

  4. Непрерывная интеграция - каждый раз, когда новая миграция регистрируется в системе контроля версий, ваш сервер CI упаковывает сценарии как артефакт для следующего этапа.

  5. Непрерывная доставка - Система непрерывной доставки берет артефакт сборки и запускает инструмент db-migrate (node.js) для каждой целевой среды. Инструмент CD использует специальную учетную запись пользователя SQL, которой разрешено вносить изменения в схему базы данных. Как показано в # 2, это должен быть единственный способ развертывания изменений.

ОБНОВЛЕНИЕ: Использование Entity Framework

Как вы можете заметить из подхода, перечисленного выше, я, очевидно, очень заинтересован, чтобы изменения схемы базы данных были ограничены определенной учетной записью пользователя, чтобы предотвратить случайное развертывание приложения с учетной записью пользователя, которая имеет неограниченный доступ. Ваш пробег может отличаться, но есть несколько подходов, которые вы можете использовать:

  1. Используйте migrate.exe для выполнения миграций - Этот инструмент поставляется с EntityFramework, и было бы возможно вызвать ваши миграции с кодом в качестве шага развертывания. Это было бы очень похоже на то, как я использую db-migrate выше.

  2. Сценарий миграции во время запуска приложения - Вы можете написать код в логике инициализации веб-приложения для выполнить любые ожидающие миграции . Это, возможно, проще всего реализовать, но требует, чтобы вы запускали приложение с учетной записью базы данных, которая имеет неограниченный доступ. Кроме того, если есть проблема с миграцией базы данных, вы не будете знать, пока приложение не будет развернуто. С точки зрения CI / CD, я хотел бы прервать развертывание и, возможно, выполнить откат, прежде чем полностью испортить сайт.

  3. Настройка профиля публикации - Вы можете настроить профиль публикации как , описанный в этой статье для «Обновления базы данных». Это эффективно добавляет databaseInitializer в web.config для обновления базы данных при запуске приложения. Это имеет аналогичные недостатки, но, по крайней мере, позволяет использовать другую учетную запись пользователя для применения изменений базы данных.

enter image description here

Обратите внимание, что вполне возможно встроить ваши хранимые процедуры в качестве ресурсов в ваши миграции, а затем просто вызвать необработанные операторы sql из миграции:

Базовая миграция:

/// <summary>
/// Custom DbMigration with helper methods
/// </summary>
public abstract class BaseDbMigration : DbMigration
{
    /// <summary>
    /// Apply a SQL statement stored in an embedded resource
    /// </summary>
    /// <param name="resourceName"></param>
    protected void SqlFromEmbeddedResource(string resourceName)
    {
        Assembly assembly = typeof(BaseDbMigration).Assembly;

        string baseNamespace = typeof(BaseDbMigration).Namespace;

        resourceName = baseNamespace + "." + resourceName;

        bool exists = assembly.GetManifestResourceNames().Where(r => r == resourceName).SingleOrDefault() != null;

        if (exists)
        {
            string sql = null;

            using (var stream = assembly.GetManifestResourceStream(resourceName))
            {
                var reader = new StreamReader(stream);
                sql = reader.ReadToEnd();
            }

            base.Sql(sql);
        }
    }
}

Пример миграции:

/// <summary>
/// Migration: Deploy Stored Proc
/// </summary>
public partial class CalculateTotalsV1 : BaseDbMigration
{
    /// <summary>
    /// </summary>
    public override void Up()
    {
        base.SqlFromEmbeddedResource("sp_CalculateTotals.v1.Up.sql");
    }

    /// <summary>
    /// </summary>
    public override void Down()
    {
        base.SqlFromEmbeddedResource("sp_CalculateTotals.v1.Down.sql");
    }
}

Кроме того, если вы хотите отделить миграцию базы данных от развертывания приложения, то само собой разумеется, что вы захотите разделить миграции с первым кодом в их собственную сборку .net. Это облегчает вызов миграции.

...