Close

Использование флажков возможностей LaunchDarkly в конвейерах Bitbucket

Фото Уоррена Марусяка
Уоррен Марусяк

Старший технический эксперт

Развертывать новый код в рабочей среде всегда рискованно. Баги могут проникнуть в нее даже после модульного, интеграционного и системного тестирования кода в тестовой и промежуточной среде. Как правило, у разработчиков есть два варианта, когда баг попадает в рабочую версию и затрагивает пользователей. Можно откатить код с багом или исправить его в следующей версии. Оба этих решения требуют времени. Теперь разработчики могут включать или выключать возможности в среде одним нажатием кнопки, поместив соответствующие изменения кода во флажок возможности. Воздействие кода с багами на пользователей можно немедленно смягчить, а исправление — безопасно разработать и внедрить. В этой статье данный подход показан на примере конвейеров Bitbucket и флажков возможностей LaunchDarkly в демонстрационном приложении ImageLabeller.

Демонстрация флажков возможностей для ImageLabeller

ImageLabeller — это небольшое приложение, которое использует машинное обучение для маркировки изображений. ImageLabeller развертывается в пяти средах: Test, Staging, Production-us-west-2, Production-us-east-1 и Production-ca-central-1. В этой статье показано, как управлять изменениями в компоненте SubmitImage приложения ImageLabeller с помощью флажков возможностей. SubmitImage — это программа AWS Lambda, написанная на языке Go. Вы будете использовать LaunchDarkly для управления флажками возможностей, Bitbucket — для управления исходным кодом и Bitbucket Pipelines — для работы с функциями CI/CD.

Использование флажков возможностей LaunchDarkly с конвейерами Bitbucket

Попросите локального администратора LaunchDarkly создать проект и среду. На снимке экрана ниже представлен проект PMMimageLabellerDemo с пятью средами. Test и Staging — это тестовая и промежуточная среды, используемые перед рабочими средами. Обратите внимание на ключ SDK для каждой среды. В дальнейшем эти ключи SDK будут добавлены в качестве переменных репозитория в Bitbucket.

В этом примере конвейеры Bitbucket выполняют развертывание в этих средах при коммитах кода в функциональную ветку. Production-US-West-2, Production-US-East-1 и Production-CA-Central-1 — это рабочие среды, соответствующие средам AWS. Конвейеры Bitbucket выполняют развертывание в этих средах при слиянии кода в основной ветке с кодом из функциональной ветки с помощью запроса pull.

Снимок экрана: Bitbucket Pipelines

В LaunchDarkly создайте флажок возможности для проекта. Выберите тестовую среду и задайте настройки флажка возможности. На снимке экрана ниже флажок возможности по умолчанию возвращает значение true в тестовом регионе. Если запрос подает конкретный пользователь AtlassianTestUser@atlassian.com, флажок возможности вернет значение false. Таким образом, для пользователя с конкретным именем, например для тестовых пользователей в пакете системных тестов, код будет выполняться одним образом, а для обычных пользователей в той же среде — другим.

Это поведение можно настраивать отдельно для каждой среды. Флажки возможностей позволяют разработчику развертывать новый код во всех регионах, но при этом выполняться он будет только в определенных средах. Для этого демонстрационного приложения флажок возвращает значение false в среде Staging и во всех трех рабочих средах. Новый код будет выполняться только в тестовой среде.

Снимок экрана: выбор пользователей

Найдите ключи SDK для каждой среды в LaunchDarkly. Затем перейдите в Bitbucket и добавьте переменные репозитория в каждый репозиторий, который будет использовать этот флажок. На снимке экрана ниже добавлено пять переменных репозитория. ld_test_env содержит ключ SDK LaunchDarkly для тестовой среды. ld_staging_env содержит ключ SDK LaunchDarkly для промежуточной среды. В дальнейшем эти переменные будут использоваться в качестве ссылок в файле bitbucket-pipelines.yml для репозитория.

Ключи SDK

Значения ключей SDK могут использоваться как ссылки в файле bitbucket-pipeline.yml после добавления ключей SDK в качестве переменных репозитория. В приведенном ниже фрагменте в шаг развертывания для среды production-ca-central-1 добавлена переменная STACK_PARAMETERS. STACK_PARAMETERS отправляет значение соответствующего ключа SDK в файл AWS CloudFormation template.yml в виде параметра.

- pipe: atlassian/aws-sam-deploy:1.2.0
  variables:
    AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
    AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
    AWS_DEFAULT_REGION: 'ca-central-1'
    STACK_NAME: 'OpenDevOpsSubmitImage'
    CAPABILITIES: [ 'CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND' ]
    TEMPLATE: 'https://s3.amazonaws.com/open-devops-code-ca-central-1-${AWS_ACCOUNT_ID}/submit-image-packaged.yml'
    WAIT: 'true'
    DEBUG: 'true'
    S3_BUCKET: 'open-devops-code-ca-central-1-${AWS_ACCOUNT_ID}'
    SAM_TEMPLATE: 'build/template.yaml'
    STACK_PARAMETERS: '[{
      "ParameterKey": "LaunchDarklySDKKey",
      "ParameterValue": "${ld_prod_cac1_env}"
    }]'

Добавьте параметр LaunchDarklySDKKey типа String в раздел Parameters файла template.yml для репозитория. Он получает значение параметра STACK_PARAMETER для LaunchDarklySDKKey, заданного в файле bitbucket-pipelines.yml.

Parameters:
  LaunchDarklySDKKey:
    Type: String

Кроме того, обновите ресурс AWS Lambda для функции SubmitImageFunction в разделе Resources файла template.yml. Добавьте переменную среды LaunchDarklySDKKey в разделе Environment > Variables.

Resources:
  SubmitImageFunction:
    Type: AWS::Serverless::Function # More info about Function Resource: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#awsserverlessfunction
    Properties:
      CodeUri: submitImage/
      Handler: submit-image
      Runtime: go1.x
      Tracing: Active # https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
      Policies:
        - AmazonDynamoDBFullAccess
        - AmazonS3FullAccess
      Events:
        CatchAll:
          Type: Api # More info about API Event Source: https://github.com/awslabs/serverless-application-model/blob/master/versions/2016-10-31.md#api
          Properties:
            Path: /submit-image
            Method: GET
      Environment:
        Variables:
          LaunchDarklySDKKey:
            Ref: LaunchDarklySDKKey

Переменную среды LaunchDarklySDKKey можно будет увидеть в консоли AWS Lambda после развертывания конвейерами BitBucket в среде. Значение этого ключа уникально для каждой среды. Например, переменная среды LaunchDarklySDKKey в среде Test будет отличаться от переменной в Production-us-west-2.

Снимок экрана: конфигурации среды

SubmitImage — это программа AWS Lambda, написанная на языке Go. Чтобы использовать LaunchDarkly в Go, импортируйте следующие зависимости.

"gopkg.in/launchdarkly/go-sdk-common.v2/lduser"
ld "gopkg.in/launchdarkly/go-server-sdk.v5"

Добавьте функцию для получения значения флажка возможности из LaunchDarkly во время выполнения.

func getLaunchDarklyFlags(username string) (bool, error) {
  client, _ := ld.MakeClient(os.Getenv("LaunchDarklySDKKey"), 5 * time.Second)
  flagKey := "SubmitImageDemoFeature"

  userUuid, uuidErr := uuid.NewRandom()
  if uuidErr != nil {
    return false, uuidErr
  }

  var user lduser.User
  if(username == "") {
    user = lduser.NewAnonymousUser(userUuid.String())
  } else {
    user = lduser.NewUser(username)
  }

  showFeature, _ := client.BoolVariation(flagKey, user, false)

  if showFeature {
    return true, nil
  } else {
    return false, nil
  }
}

Передайте функции пустую строку, чтобы получить значение флажка по умолчанию, или электронную почту пользователя, чтобы получить соответствующее значение. С приведенной выше конфигурацией для анонимного пользователя должно возвращаться значение true, а для пользователя AtlasianTestUser@atlassian.com — значение false.

flagVal, flagErr  := getLaunchDarklyFlags("")
  if flagErr != nil {
    return "", flagErr
  }
  fmt.Println("DEMO flagVal for anonymous user: ", flagVal)

  flagVal, flagErr  = getLaunchDarklyFlags("AtlassianTestUser@atlassian.com")
  if flagErr != nil {
    return "", flagErr
  }
  fmt.Println("DEMO flagVal for AtlassianTestUser@atlassian.com: ", flagVal)

После выполнения кода перейдите в журналы AWS CloudWatch, чтобы убедиться, что для флажка возвращаются правильные значения.

Снимок экрана: события в журнале
Копирование правил выбора

Перейдите в раздел Admin settings (Настройки администратора), а затем выберите API keys (Ключи API), чтобы получить список ключей API для каждой среды. Эти ключи API отправляются обратно в Split во время вызовов API в коде, чтобы получить правильную версию Split. В этом руководстве для каждой среды используются ключи Server-side.

Настройки администратора

Перейдите в свой репозиторий Bitbucket, затем нажмите Repository settings (Настройки репозитория), после чего выберите Repository variables (Переменные репозитория) и добавьте переменные для каждого ключа API.

Переменные в настройках репозитория

Отредактируйте файл bitbucket-pipelines.yml и добавьте переменную STACK_PARAMETERS в шаг развертывания AWS SAM. Это делается отдельно для каждой среды. В приведенном ниже фрагменте YAML показан этап развертывания в регионе для тестирования (в данном случае это AWS US-WEST-1). Поэтому в данном шаге указана ссылка на настроенную выше переменную репозитория split_test_env. Используйте соответствующую переменную репозитория для каждой среды.

- pipe: atlassian/aws-sam-deploy:1.2.0
  variables:
    AWS_ACCESS_KEY_ID: ${AWS_ACCESS_KEY_ID}
    AWS_SECRET_ACCESS_KEY: ${AWS_SECRET_ACCESS_KEY}
    AWS_DEFAULT_REGION: 'us-west-1'
    STACK_NAME: 'OpenDevOpsSubmitImage'
    CAPABILITIES: [ 'CAPABILITY_IAM', 'CAPABILITY_NAMED_IAM', 'CAPABILITY_AUTO_EXPAND' ]
    TEMPLATE: 'https://s3.amazonaws.com/open-devops-code-us-west-1-${AWS_ACCOUNT_ID}/submit-image-packaged.yml'
    WAIT: 'true'
    DEBUG: 'true'
    S3_BUCKET: 'open-devops-code-us-west-1-${AWS_ACCOUNT_ID}'
    SAM_TEMPLATE: 'build/template.yaml'
    STACK_PARAMETERS: '[{
      "ParameterKey": "SplitIOSDKKey",
      "ParameterValue": "${split_test_env}"
    }]'

Отредактируйте файл template.yml для AWS CloudFormation и добавьте раздел Parameters со ссылкой на ключ Split SDK.

Parameters:
  SplitIOSDKKey:
    Type: String

В файле template.yml добавьте раздел Environment для каждого ресурса AWS Lambda, которому требуется доступ к Split. В этом руководстве показано

Environment:
  Variables:
    SplitIOSDKKey:
      Ref: SplitIOSDKKey

Импортируйте следующие зависимости в файл Go, в котором будет использоваться Split SDK.

"github.com/splitio/go-client/v6/splitio/client"
"github.com/splitio/go-client/v6/splitio/conf"

Эта функция создает клиент и извлекает значение флажка возможности для параметра SubmitImageDemoSplit, созданного в пользовательском интерфейсе Split. Она принимает один аргумент — имя пользователя.

func getSplitIOFlag(username string) (string, error) {
  splitIOSDKKey := os.Getenv("SplitIOSDKKey")

  cfg := conf.Default()
  factory, err := client.NewSplitFactory(splitIOSDKKey, cfg)
  if err != nil {
    fmt.Printf("SDK init error: %s\n", err)
    return "", err
  }

  splitClient := factory.Client()
  err = splitClient.BlockUntilReady(10)
  if err != nil {
    fmt.Printf("SDK timeout: %s\n", err)
    return "", err
  }

  treatment := splitClient.Treatment(username, "SubmitImageDemoSplit", nil)
  fmt.Printf("SPLIT_DEMO treatment is %s, username is %s\n", treatment, username)

  return treatment, nil
}

Вызовите функцию, передав ей адрес электронной почты. В этом случае для адреса someRandomUser@atlassian.com функция вернет значение по умолчанию, поскольку он не входит в список разрешенных адресов для флажка возможности. Для AtlassianTestUser@atlassian.com функция вернет значение из списка разрешенных адресов для этого флажка возможности.

Просмотрите выходные данные в журналах AWS CloudWatch после выполнения кода. Обратите внимание, что для флажка возможности указано off (отключено) при обращении с адресом someRandomUser@atlassian.com и on (включено) — при обращении с адресом AtlassianTestUser@atlassian.com.

Журнал событий

Заключение

Флажки возможностей LaunchDarkly можно легко интегрировать в приложение, развертываемое с помощью конвейеров Bitbucket. Они позволяют разработчикам контролировать выполнение развернутого кода. Это может ускорить реагирование на баги при развертывании и снизить воздействие на пользователей. Потратьте немного времени, чтобы запустить экземпляр Bitbucket с LaunchDarkly и протестировать возможности для вашей команды.

Warren Marusiak
Warren Marusiak

Warren is a Canadian developer from Vancouver, BC with over 10 years of experience. He came to Atlassian from AWS in January of 2021.


Поделитесь этой статьей

Рекомендуемые статьи

Добавьте эти ресурсы в закладки, чтобы изучить типы команд DevOps или получать регулярные обновления по DevOps в Atlassian.

Рисунок: DevOps

Сообщество DevOps

Рисунок: DevOps

Образовательные программы DevOps

Рисунок: карта

Начните работу бесплатно

Подпишитесь на информационную рассылку по DevOps

Thank you for signing up