如何将环境变量添加到CodeBuild buildspec.yml?

时间:2018-10-09 04:53:12

标签: amazon-web-services amazon-cloudformation hugo aws-codepipeline aws-codebuild

我正在尝试使用CloudFormation模板来定义CodeBuild和CodePipeline,以自动部署S3存储桶中托管的静态网站。为了在应得的信用额中给予荣誉,我主要遵循https://dzone.com/articles/continuous-delivery-to-s3-via-codepipeline-and-cod中的模板。

我无法解决的问题是,在添加了要用于创建静态站点文件的Hugo版本的环境变量之后,我从AWS控制台收到一条错误消息,内容为:“模板验证错误:模板格式错误:模板的“资源”块中存在未解决的资源依赖性[HUGO_VERSION]。“

为什么它不接受我在environment_variables下定义的HUGO_VERSION环境变量?这是该格式的版本0.1,因此与当前版本0.2略有不同,但是我已阅读以下链接:https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html#build-spec-ref-syntax

确实让我感到困惑的是,如果我删除了带有$ {HUGO_VERSION}的行,模板就可以接受了-在构建显示之后检查CloudWatch日志(因为printenv命令)HUGO_VERSION = 0.49!有什么作用?

最初,模板看起来像这样。

---
AWSTemplateFormatVersion: '2010-09-09'
Description: Pipeline using CodePipeline and CodeBuild for continuous delivery of a single-page application to S3
Parameters:
  SiteBucketName:
    Type: String
    Description: Name of bucket to create to host the website
  GitHubUser:
    Type: String
    Description: GitHub User
    Default: "stelligent"
  GitHubRepo:
    Type: String
    Description: GitHub Repo to pull from. Only the Name. not the URL
    Default: "devops-essentials"
  GitHubBranch:
    Type: String
    Description: GitHub Branch
    Default: "master"
  GitHubToken:
    NoEcho: true
    Type: String
    Description: Secret. It might look something like 9b189a1654643522561f7b3ebd44a1531a4287af OAuthToken with access to Repo. Go to https://github.com/settings/tokens
  BuildType:
    Type: String
    Default: "LINUX_CONTAINER"
    Description: The build container type to use for building the app
  BuildComputeType:
    Type: String
    Default: "BUILD_GENERAL1_SMALL"
    Description: The build compute type to use for building the app
  BuildImage:
    Type: String
    Default: "aws/codebuild/ubuntu-base:14.04"
    Description: The build image to use for building the app
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Site Configuration"
        Parameters:
          - SiteBucketName
      - Label:
          default: "GitHub Configuration"
        Parameters:
          - GitHubToken
          - GitHubUser
          - GitHubRepo
          - GitHubBranch
      - Label:
          default: "Build Configuration"
        Parameters:
          - BuildType
          - BuildComputeType
          - BuildImage
    ParameterLabels:
      SiteBucketName:
        default: Name of S3 Bucket to create for website hosting
      GitHubToken:
        default: GitHub OAuth2 Token
      GitHubUser: 
        default: GitHub User/Org Name
      GitHubRepo: 
        default: GitHub Repository Name
      GitHubBranch: 
        default: GitHub Branch Name
      BuildType: 
        default: CodeBuild type
      BuildComputeType: 
        default: CodeBuild instance type
      BuildImage: 
        default: CodeBuild image
Resources:
  CodeBuildRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - codebuild.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: codebuild-service
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action: "*"
            Resource: "*"
          Version: '2012-10-17'
  CodePipelineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - codepipeline.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: codepipeline-service
        PolicyDocument:
          Statement:
          - Action:
            - codebuild:*
            Resource: "*"
            Effect: Allow
          - Action:
            - s3:GetObject
            - s3:GetObjectVersion
            - s3:GetBucketVersioning
            Resource: "*"
            Effect: Allow
          - Action:
            - s3:PutObject
            Resource:
            - arn:aws:s3:::codepipeline*
            Effect: Allow
          - Action:
            - s3:*
            - cloudformation:*
            - iam:PassRole
            Resource: "*"
            Effect: Allow
          Version: '2012-10-17'
  SiteBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Delete
    Properties:
      AccessControl: PublicRead
      BucketName: !Ref SiteBucketName
      WebsiteConfiguration:
        IndexDocument: index.html
  PipelineBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Delete
  CodeBuildDeploySite:
    Type: AWS::CodeBuild::Project
    DependsOn: CodeBuildRole
    Properties:
      Name: !Sub ${AWS::StackName}-DeploySite
      Description: Deploy site to S3
      ServiceRole: !GetAtt CodeBuildRole.Arn
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        Type: !Ref BuildType
        ComputeType: !Ref BuildComputeType
        Image: !Sub ${BuildImage}
      Source:
        Type: CODEPIPELINE
        BuildSpec: !Sub |
          version: 0.1
          phases:
            post_build:
              commands:
                - aws s3 cp --recursive --acl public-read ./samples s3://${SiteBucketName}/samples 
                - aws s3 cp --recursive --acl public-read ./html s3://${SiteBucketName}/ 
          artifacts:
            type: zip
            files:
              - ./html/index.html
      TimeoutInMinutes: 10
  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !GetAtt CodePipelineRole.Arn
      Stages:
      - Name: Source
        Actions:
        - InputArtifacts: []
          Name: Source
          ActionTypeId:
            Category: Source
            Owner: ThirdParty
            Version: '1'
            Provider: GitHub
          OutputArtifacts:
          - Name: SourceArtifacts
          Configuration:
            Owner: !Ref GitHubUser
            Repo: !Ref GitHubRepo
            Branch: !Ref GitHubBranch
            OAuthToken: !Ref GitHubToken
          RunOrder: 1
      - Name: Deploy
        Actions:
        - Name: Artifact
          ActionTypeId:
            Category: Build
            Owner: AWS
            Version: '1'
            Provider: CodeBuild
          InputArtifacts:
          - Name: SourceArtifacts
          OutputArtifacts:
          - Name: DeploymentArtifacts
          Configuration:
            ProjectName: !Ref CodeBuildDeploySite
          RunOrder: 1
      ArtifactStore:
        Type: S3
        Location: !Ref PipelineBucket
Outputs:
  PipelineUrl:
    Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline}
    Description: CodePipeline URL
  SiteUrl:
    Value: !GetAtt [SiteBucket, WebsiteURL]
    Description: S3 Website URL

现在,在尝试添加环境变量以在管道中使用Hugo之后,模板看起来像这样。

---
AWSTemplateFormatVersion: '2010-09-09'
Description: Pipeline using CodePipeline and CodeBuild for continuous delivery of a single-page application to S3
Parameters:
  SiteBucketName:
    Type: String
    Description: Name of bucket to create to host the website
  GitHubUser:
    Type: String
    Description: GitHub User
    Default: "stelligent"
  GitHubRepo:
    Type: String
    Description: GitHub Repo to pull from. Only the Name. not the URL
    Default: "devops-essentials"
  GitHubBranch:
    Type: String
    Description: GitHub Branch
    Default: "master"
  GitHubToken:
    NoEcho: true
    Type: String
    Description: Secret. It might look something like 9b189a1654643522561f7b3ebd44a1531a4287af OAuthToken with access to Repo. Go to https://github.com/settings/tokens
  BuildType:
    Type: String
    Default: "LINUX_CONTAINER"
    Description: The build container type to use for building the app
  BuildComputeType:
    Type: String
    Default: "BUILD_GENERAL1_SMALL"
    Description: The build compute type to use for building the app
  BuildImage:
    Type: String
    Default: "aws/codebuild/ubuntu-base:14.04"
    Description: The build image to use for building the app
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Site Configuration"
        Parameters:
          - SiteBucketName
      - Label:
          default: "GitHub Configuration"
        Parameters:
          - GitHubToken
          - GitHubUser
          - GitHubRepo
          - GitHubBranch
      - Label:
          default: "Build Configuration"
        Parameters:
          - BuildType
          - BuildComputeType
          - BuildImage
    ParameterLabels:
      SiteBucketName:
        default: Name of S3 Bucket to create for website hosting
      GitHubToken:
        default: GitHub OAuth2 Token
      GitHubUser: 
        default: GitHub User/Org Name
      GitHubRepo: 
        default: GitHub Repository Name
      GitHubBranch: 
        default: GitHub Branch Name
      BuildType: 
        default: CodeBuild type
      BuildComputeType: 
        default: CodeBuild instance type
      BuildImage: 
        default: CodeBuild image
Resources:
  CodeBuildRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - codebuild.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: codebuild-service
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action: "*"
            Resource: "*"
          Version: '2012-10-17'
  CodePipelineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - codepipeline.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: codepipeline-service
        PolicyDocument:
          Statement:
          - Action:
            - codebuild:*
            Resource: "*"
            Effect: Allow
          - Action:
            - s3:GetObject
            - s3:GetObjectVersion
            - s3:GetBucketVersioning
            Resource: "*"
            Effect: Allow
          - Action:
            - s3:PutObject
            Resource:
            - arn:aws:s3:::codepipeline*
            Effect: Allow
          - Action:
            - s3:*
            - cloudformation:*
            - iam:PassRole
            Resource: "*"
            Effect: Allow
          Version: '2012-10-17'
  SiteBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Delete
    Properties:
      AccessControl: PublicRead
      BucketName: !Ref SiteBucketName
      WebsiteConfiguration:
        IndexDocument: index.html
  PipelineBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Delete
  CodeBuildDeploySite:
    Type: AWS::CodeBuild::Project
    DependsOn: CodeBuildRole
    Properties:
      Name: !Sub ${AWS::StackName}-DeploySite
      Description: Deploy site to S3
      ServiceRole: !GetAtt CodeBuildRole.Arn
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        Type: !Ref BuildType
        ComputeType: !Ref BuildComputeType
        Image: !Sub ${BuildImage}
      Source:
        Type: CODEPIPELINE
        BuildSpec: !Sub |
          version: 0.1
          environment_variables:
            plaintext:
              AWS_DEFAULT_REGION: "US-WEST-2"
              HUGO_VERSION: "0.49"
          phases:
            install:
              commands:
                - printenv
                - echo "Install step..."
                - curl -Ls https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz -o /tmp/hugo.tar.gz
                - tar xf /tmp/hugo.tar.gz -C /tmp
                - mv /tmp/hugo_${HUGO_VERSION}_linux_amd64/hugo_${HUGO_VERSION}_linux_amd64 /usr/bin/hugo
                - rm -rf /tmp/hugo*
            build:
              commands:
                - hugo
            post_build:
              commands:
                - aws s3 cp --recursive --acl public-read ./public s3://${SiteBucketName}
          artifacts:
            type: zip
            files:
              - ./html/index.html
      TimeoutInMinutes: 10
  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !GetAtt CodePipelineRole.Arn
      Stages:
      - Name: Source
        Actions:
        - InputArtifacts: []
          Name: Source
          ActionTypeId:
            Category: Source
            Owner: ThirdParty
            Version: '1'
            Provider: GitHub
          OutputArtifacts:
          - Name: SourceArtifacts
          Configuration:
            Owner: !Ref GitHubUser
            Repo: !Ref GitHubRepo
            Branch: !Ref GitHubBranch
            OAuthToken: !Ref GitHubToken
          RunOrder: 1
      - Name: Deploy
        Actions:
        - Name: Artifact
          ActionTypeId:
            Category: Build
            Owner: AWS
            Version: '1'
            Provider: CodeBuild
          InputArtifacts:
          - Name: SourceArtifacts
          OutputArtifacts:
          - Name: DeploymentArtifacts
          Configuration:
            ProjectName: !Ref CodeBuildDeploySite
          RunOrder: 1
      ArtifactStore:
        Type: S3
        Location: !Ref PipelineBucket
Outputs:
  PipelineUrl:
    Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline}
    Description: CodePipeline URL
  SiteUrl:
    Value: !GetAtt [SiteBucket, WebsiteURL]
    Description: S3 Website URL

修改10/20

还没有解决这个问题。我尝试遵循matsev给出的建议,但仍然收到相同的验证错误。为了完整起见,我尝试使用的最新模板是


AWSTemplateFormatVersion: '2010-09-09'
Description: Pipeline using CodePipeline and CodeBuild for continuous delivery of a single-page application to S3
Parameters:
  SiteBucketName:
    Type: String
    Description: Name of bucket to create to host the website
  GitHubUser:
    Type: String
    Description: GitHub User
    Default: "stelligent"
  GitHubRepo:
    Type: String
    Description: GitHub Repo to pull from. Only the Name. not the URL
    Default: "devops-essentials"
  GitHubBranch:
    Type: String
    Description: GitHub Branch
    Default: "master"
  GitHubToken:
    NoEcho: true
    Type: String
    Description: Secret. It might look something like 9b189a1654643522561f7b3ebd44a1531a4287af OAuthToken with access to Repo. Go to https://github.com/settings/tokens
  BuildType:
    Type: String
    Default: "LINUX_CONTAINER"
    Description: The build container type to use for building the app
  BuildComputeType:
    Type: String
    Default: "BUILD_GENERAL1_SMALL"
    Description: The build compute type to use for building the app
  BuildImage:
    Type: String
    Default: "aws/codebuild/ubuntu-base:14.04"
    Description: The build image to use for building the app
Metadata:
  AWS::CloudFormation::Interface:
    ParameterGroups:
      - Label:
          default: "Site Configuration"
        Parameters:
          - SiteBucketName
      - Label:
          default: "GitHub Configuration"
        Parameters:
          - GitHubToken
          - GitHubUser
          - GitHubRepo
          - GitHubBranch
      - Label:
          default: "Build Configuration"
        Parameters:
          - BuildType
          - BuildComputeType
          - BuildImage
    ParameterLabels:
      SiteBucketName:
        default: Name of S3 Bucket to create for website hosting
      GitHubToken:
        default: GitHub OAuth2 Token
      GitHubUser: 
        default: GitHub User/Org Name
      GitHubRepo: 
        default: GitHub Repository Name
      GitHubBranch: 
        default: GitHub Branch Name
      BuildType: 
        default: CodeBuild type
      BuildComputeType: 
        default: CodeBuild instance type
      BuildImage: 
        default: CodeBuild image
Resources:
  CodeBuildRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - codebuild.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: codebuild-service
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action: "*"
            Resource: "*"
          Version: '2012-10-17'
  CodePipelineRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - codepipeline.amazonaws.com
          Action:
          - sts:AssumeRole
      Path: "/"
      Policies:
      - PolicyName: codepipeline-service
        PolicyDocument:
          Statement:
          - Action:
            - codebuild:*
            Resource: "*"
            Effect: Allow
          - Action:
            - s3:GetObject
            - s3:GetObjectVersion
            - s3:GetBucketVersioning
            Resource: "*"
            Effect: Allow
          - Action:
            - s3:PutObject
            Resource:
            - arn:aws:s3:::codepipeline*
            Effect: Allow
          - Action:
            - s3:*
            - cloudformation:*
            - iam:PassRole
            Resource: "*"
            Effect: Allow
          Version: '2012-10-17'
  SiteBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Delete
    Properties:
      AccessControl: PublicRead
      BucketName: !Ref SiteBucketName
      WebsiteConfiguration:
        IndexDocument: index.html
  PipelineBucket:
    Type: AWS::S3::Bucket
    DeletionPolicy: Delete
  CodeBuildDeploySite:
    Type: AWS::CodeBuild::Project
    DependsOn: CodeBuildRole
    Properties:
      Name: !Sub ${AWS::StackName}-DeploySite
      Description: Deploy site to S3
      ServiceRole: !GetAtt CodeBuildRole.Arn
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        Type: !Ref BuildType
        ComputeType: !Ref BuildComputeType
        Image: !Sub ${BuildImage}
        EnvironmentVariables:
          - Name: HUGO_VERSION
            Value: '0.49'
            Type: PLAINTEXT
      Source:
        Type: CODEPIPELINE
        BuildSpec: !Sub |
          version: 0.2
          env:
            variables:
              AWS_DEFAULT_REGION: "US-WEST-2"
          phases:
            install:
              commands:
                - printenv
                - curl -Ls https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/hugo_${HUGO_VERSION}_Linux-64bit.tar.gz -o /tmp/hugo.tar.gz
                - tar xf /tmp/hugo.tar.gz -C /tmp
                - mv /tmp/hugo_${HUGO_VERSION}_linux_amd64/hugo_${HUGO_VERSION}_linux_amd64 /usr/bin/hugo
                - rm -rf /tmp/hugo*
            build:
              commands:
                - hugo
            post_build:
              commands:
                - aws s3 cp --recursive --acl public-read ./samples s3://${SiteBucketName}/samples 
                - aws s3 cp --recursive --acl public-read ./html s3://${SiteBucketName}/ 
          artifacts:
            type: zip
            files:
              - ./html/index.html
      TimeoutInMinutes: 10
  Pipeline:
    Type: AWS::CodePipeline::Pipeline
    Properties:
      RoleArn: !GetAtt CodePipelineRole.Arn
      Stages:
      - Name: Source
        Actions:
        - InputArtifacts: []
          Name: Source
          ActionTypeId:
            Category: Source
            Owner: ThirdParty
            Version: '1'
            Provider: GitHub
          OutputArtifacts:
          - Name: SourceArtifacts
          Configuration:
            Owner: !Ref GitHubUser
            Repo: !Ref GitHubRepo
            Branch: !Ref GitHubBranch
            OAuthToken: !Ref GitHubToken
          RunOrder: 1
      - Name: Deploy
        Actions:
        - Name: Artifact
          ActionTypeId:
            Category: Build
            Owner: AWS
            Version: '1'
            Provider: CodeBuild
          InputArtifacts:
          - Name: SourceArtifacts
          OutputArtifacts:
          - Name: DeploymentArtifacts
          Configuration:
            ProjectName: !Ref CodeBuildDeploySite
          RunOrder: 1
      ArtifactStore:
        Type: S3
        Location: !Ref PipelineBucket
Outputs:
  PipelineUrl:
    Value: !Sub https://console.aws.amazon.com/codepipeline/home?region=${AWS::Region}#/view/${Pipeline}
    Description: CodePipeline URL
  SiteUrl:
    Value: !GetAtt [SiteBucket, WebsiteURL]
    Description: S3 Website URL

2 个答案:

答案 0 :(得分:3)

我相信会发生以下情况: CloudFormation尝试将${HUGO_VERSION}解析为Cloudformation模板的Parameter,因为它位于“!Sub”函数中。

有关子功能的AWS文档

  

要在字面上写一个美元符号和大括号($ {}),请在打开的大括号后添加一个感叹号(!),例如$ {!Literal}。 AWS CloudFormation将此文本解析为$ {Literal}。

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html#w2ab1c21c28c59b7

因此,您的构建规范阶段应类似于:

      phases:
        install:
          commands:
            - printenv
            - echo "Install step..."
            - curl -Ls https://github.com/gohugoio/hugo/releases/download/v${!HUGO_VERSION}/hugo_${!HUGO_VERSION}_Linux-64bit.tar.gz -o /tmp/hugo.tar.gz
            - tar xf /tmp/hugo.tar.gz -C /tmp
            - mv /tmp/hugo_${!HUGO_VERSION}_linux_amd64/hugo_${!HUGO_VERSION}_linux_amd64 /usr/bin/hugo
            - rm -rf /tmp/hugo*

希望这会有所帮助!

答案 1 :(得分:2)

请检查CloudFormation模板中AWS::CodeBuild::Project的{​​{3}}属性。具体来说,EnvironmentVariables允许您指定环境变量,例如

  CodeBuildDeploySite:
    Type: AWS::CodeBuild::Project
    DependsOn: CodeBuildRole
    Properties:
      Name: !Sub ${AWS::StackName}-DeploySite
      Description: Deploy site to S3
      ServiceRole: !GetAtt CodeBuildRole.Arn
      Artifacts:
        Type: CODEPIPELINE
      Environment:
        Type: !Ref BuildType
        ComputeType: !Ref BuildComputeType
        Image: !Sub ${BuildImage}
        EnvironmentVariables:
          - Name: HUGO_VERSION
            Value: '0.49'
            Type: PLAINTEXT

# More properties...

现在,您可以在HUGO_VERSION文件中将buildspec.yml引用为环境变量,例如

pre_build:    
  commands:
    - echo HUGO_VERSION $HUGO_VERSION