AWS Pass in variable into buildspec.yml from CodePipeline

二次信任 提交于 2019-12-03 04:15:20

This feature isn't available today.

A workaround would be to create a different CodeBuild project for each stage with different environment variables.

You can find details on using an environment variable in your builspec.yml commands here: http://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html

You can actually pass environment variables in CodeBuild cloudformation as below:

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

And in your buildspec.yml you can reference the environment like this,

version: 0.2

phases:
  install:
    commands:
      - npm install

  build:
    commands:
      - npm build -- --env ${CURRENT_ENVIRONMENT}

If you don't want to use CF, you can set ENV vars on your CodeBuild project in the AWS UI.

In AWS, go to your code builder project, in the top right corner click "edit" and select "environment." On the edit environment page, click the "Additional Configuration" drop down. In there you will see inputs for "name" and "value." "Name" is where you set your ENV and "value" is where you set your value for that variable.

Example: set API_ENV in "name" and development in "value." Then, in your buildspec.yml, you can use $API_ENV.

You can use build environment variables to conditionally pass from buildspec to npm build by detecting which CodeBuild job or CodePipeline job is running. If you have one CodePipeline listening to /dev commits and another listening to /master commits, for example, this works perfectly.

Here's an example which runs a different PROD vs DEV build:

  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
drew

I've created a lambda function that updates an existing codebuild project's environment variables. You can the start the build (codebuild.start) after updating the variables. Looks something like this (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
    }
});

The CodeBuild initiator is an environment variable in CodeBuild and this can be used to read in the CodePipeline name.

So if you include your environment in your CodePipeline name as a suffix (-dev or -prod, for instance), then you can parse it out like so.

version: 0.2
phases:
  build:
    commands:
      - CURRENT_ENVIRONMENT=`echo $CODEBUILD_INITIATOR | cut -d '-' -f2 | tr '[:upper:]' '[:lower:]'`
      - echo "My env is $CURRENT_ENVIRONMENT"


I created a small python script to parse the $CODEBUILD_INITIATOR variable that is passed. Below is the buildspec.yml and below that is the python script that I include with the build and call.

  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 script (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()

You'll have to tweak some variable values here if you want this to work. Namely, "-project-name".

As of today, you can set environment variables for CodeBuild build jobs in your pipeline. This improvement makes it possible to reuse the same build project for multiple actions and simplify deployments to staging and production environments in your pipeline.

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#action-reference-CodeBuild-config

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!