AWS передать переменную в buildspec.yml из CodePipeline
У меня есть AWS CodePipeline, которая вызывает CodeBuild на этапе сборки.
Вопрос в том, как передать переменную окружения из CodePipeline, которую можно прочитать в buildspec.yml CodeBuild?
Я знаю, что могу устанавливать переменные среды в CodeBuild, но я хочу использовать один и тот же проект CodeBuild для сред dev, qa и prod. Я не понимаю, как я могу передать переменную окружения из CodePipeline, которая делает его полностью в buildspec.yml
Пример buildspec.yml
version: 0.1
phases:
build:
commands:
- npm install
- npm build -- --env ${CURRENT_ENVIRONMENT}
Где CURRENT_ENVIRONMENT будет переменной, которую я установил в действии Этапа CodePipeline.
10 ответов
На сегодняшний день вы можете устанавливать переменные среды для заданий сборки CodeBuild в своем конвейере. Это улучшение позволяет повторно использовать один и тот же проект сборки для нескольких действий и упростить развертывание в промежуточной и производственной средах в вашем конвейере.
name: Build
actions:
- name: MyBuildJob
actionTypeId:
category: Build
owner: AWS
provider: CodeBuild
version: '1'
runOrder: 1
configuration:
ProjectName: my-build-project
PrimarySource: MyApplicationSource1
EnvironmentVariables: '[{"name":"CURRENT_ENVIRONMENT","value":"Production","type":"PLAINTEXT"},
{"name":"UseParamStore","value":"CURRENT_ENVIRONMENT","type":"PARAMETER_STORE"}]'
https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodeBuild.html
На самом деле вы можете передавать переменные среды в облачной информации CodeBuild, как показано ниже:
Build:
Type: AWS::CodeBuild::Project
Properties:
Name:
!Sub Build-${AWS::StackName}
Description: Build your project
Environment:
Type: LINUX_CONTAINER
ComputeType: BUILD_GENERAL1_SMALL
Image: node8
EnvironmentVariables:
- Name: CURRENT_ENVIRONMENT
Type: PLAINTEXT
Value: staging
И в твоем buildspec.yml
Вы можете ссылаться на окружающую среду, как это,
version: 0.2
phases:
install:
commands:
- npm install
build:
commands:
- npm build -- --env ${CURRENT_ENVIRONMENT}
Эта функция не доступна сегодня.
Обходной путь должен был бы создать различный проект CodeBuild для каждого этапа с различными переменными среды.
Вы можете найти подробную информацию об использовании переменной окружения в ваших командах builspec.yml здесь: http://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html
- Создайте проект сборки кода.
- Создайте проект конвейера внутри Codepipline.
- Добавьте действие CodeBuild и определите свои переменные в этом действии.
Например:
Имя переменной:TAG
Значение переменной:staging
Используя переменную, которую вы определили в файле Codepipline Buildspec в проекте Codebuild:
Вы можете использовать переменные среды сборки для условного перехода от buildspec к npm build
определив, какое задание CodeBuild или CodePipeline выполняется. Например, если у вас есть одна CodePipeline, которая прослушивает / dev, а другая - / master, это работает отлично.
Вот пример, который запускает другую сборку PROD vs DEV:
build:
commands:
- |
if expr "${CODEBUILD_BUILD_ARN}" : ".*build/MyProjectDev-" >/dev/null; then
yarn run build-dev;
fi
- |
if expr "${CODEBUILD_BUILD_ARN}" : ".*build/MyProject-" >/dev/null; then
yarn run build-prod;
fi
Если вы не хотите использовать CF, вы можете установить переменные ENV в своем проекте CodeBuild в пользовательском интерфейсе AWS.
В AWS перейдите к проекту компоновщика кода, в правом верхнем углу нажмите "изменить" и выберите "среда". На странице редактирования среды щелкните раскрывающийся список "Дополнительная конфигурация". Там вы увидите входные данные для "имени" и "значения". "Имя" - это то, где вы устанавливаете свой ENV, а "значение" - это то, где вы устанавливаете свое значение для этой переменной.
Пример: набор API_ENV
в "имя" и development
в цене." Затем в вашем buildspec.yml вы можете использовать $API_ENV.
Я уверен, что выше опубликовано много ответов, но есть дополнительная информация, которую я нашел полезной.
CodePipeline начал поддерживать переменную среды на уровне конвейера, где некоторые из них имеют встроенную поддержку через конвейер (переменные конвейера, созданные CodePipeline)
Так, например, если нам нужно получить CommitId на любом этапе, мы можем объявить переменную среды, как показано ниже.
- Дайте любое имя пространству имен переменных на исходной сцене, например "SourceVariables"
- Используйте это пространство имен на любом этапе как "#{SourceVariables.CommitId}", в этом случае оно будет использоваться на этапе сборки.
Также мы можем сгенерировать нашу собственную переменную среды на любом этапе, которая будет доступна для использования на следующих этапах. Более подробная информация доступна здесь.
Возвращаясь к исходному вопросу, мы можем установить переменную среды для действия сборки, которая поможет нам использовать ее вместе с файлом спецификации сборки. Но все же это не позволит нам динамически передавать его при каждом нажатии кода из источника. И из-за этого требуется два шага, такие как конвейер обновления, а затем запуск конвейера, чтобы он мог перейти на соответствующий этап.
Я создал небольшой скрипт на Python для анализа $CODEBUILD_INITIATOR
переданная переменная. Ниже находится buildspec.yml, а ниже - скрипт python, который я включаю в сборку и вызов.
build:
commands:
- |
PIPELINE_ENV=$(python3 codebuild_env_parser.py $CODEBUILD_INITIATOR)
OUTPUT_STATUS=$?
if [ "$OUTPUT_STATUS" = "0" ]; then
echo "Success finding a valid environment from codebuild_env_parser.py."
else
echo "Failure finding a valid environment from codebuild_env_parser.py. Check the script to see if the codepipeline env was passed correctly."
fi
Скрипт Python (codebuild_env_parser.py
):
import sys
def main():
args = sys.argv
if len(args) == 2:
env_list = ["dev", "prod"]
pipeline_invoker = args[1].lower()
code_pipeline_name = pipeline_invoker.split("codepipeline/")[1]
env_name = code_pipeline_name.split("-project-name")[0]
if env_name in env_list:
print("{}".format(env_name))
sys.exit(0)
else:
sys.exit(1)
else:
sys.exit(1)
main()
Вам придется настроить здесь некоторые значения переменных, если вы хотите, чтобы это работало. А именно,"-project-name"
.
Инициатор CodeBuild - это переменная среды в CodeBuild, которую можно использовать для чтения имени CodePipeline.
Поэтому, если вы включите свою среду в свое имя CodePipeline в качестве суффикса (например, -dev или -prod), вы можете проанализировать ее таким образом.
version: 0.2
phases:
build:
commands:
- CURRENT_ENVIRONMENT=`echo $CODEBUILD_INITIATOR | cut -d '-' -f2 | tr '[:upper:]' '[:lower:]'`
- echo "My env is $CURRENT_ENVIRONMENT"
Я создал лямбда-функцию, которая обновляет переменные среды существующего проекта сборки кода. Вы можете запустить сборку (codebuild.start) после обновления переменных. Выглядит примерно так (nodejs):
var params = {
"name": "Build-project-name",
"description": "Build this project.",
"environment": {
"type": "LINUX_CONTAINER",
"image": "aws/codebuild/standard:1.0",
"computeType": "BUILD_GENERAL1_LARGE",
"environmentVariables": [
{
"name": "MY_ENVIRONMENT_VARIABLE",
"value": "VALUE_OF_ENVIRONMENT_VARIABLE",
"type": "PLAINTEXT"
}]
}
}
codebuild.updateProject(params, function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
}
else {
console.log(data); // successful response
}
});