LoginSignup
1
0

More than 5 years have passed since last update.

CodeBuildでSpecify either 'DefinitionUri' or 'DefinitionBody' property and not both

Posted at

DefinitionBodyは書いているのに怒られた

AWS SAMを使用したデプロイを行っていて、ドハマリしたのでメモを共有します

前提環境

  • クロスリージョン&クロスアカウントなサーバレスアプリケーションのデプロイをSAMで行う
    • CodeCommit
    • CodePipeline
    • CodeBuild
      • AmazonLinux node4.4.6 (eb-nodejs-4.4.6-amazonlinux-64:2.1.3)

現象

CloudFormationテンプレート

下記のようなCloudFormationテンプレートを作成

template.yaml
  HelloFunction:
    Type: AWS::Serverless::Function
    Properties:
      Handler: hello.handler
      Runtime: nodejs6.10
      CodeUri: ./src/
  Api:
    Type: AWS::Serverless::Api
    Properties:
      StageName: !Ref Stage
      DefinitionBody:
        swagger: "2.0"
        info:
          version: "1.0"
          title: "HelloApi"
        schemes:
        - https
        basePath: !Sub /${Stage}
        paths:
          /hello:
            get:
              x-amazon-apigateway-integration:
                uri: !Sub  "arn:aws:apigateway:${AWS::Region}:lambda:path/2015-03-31/functions/${HelloFunction.Arn}/invocations"
                passthroughBehavior: "when_no_match"
                httpMethod: "POST"
                type: "aws_proxy"

CodeBuild

CodeBuildでテスト&デプロイを行う

buildspec.yml
version: 0.1

phases:
  install:
    commands:
      - curl -o /usr/local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && chmod +x /usr/local/bin/jq
      - mkdir ~/.aws
      - aws sts assume-role --role-arn ${DEV_CFN_ROLE} --role-session-name codebuild | jq -r '"[default]\naws_access_key_id = \(.Credentials.AccessKeyId)\naws_secret_access_key = \(.Credentials.SecretAccessKey)\naws_session_token = \(.Credentials.SessionToken)\n"' >> ~/.aws/credentials
      - cd test && npm install && npm install -g mocha
  pre_build:
    commands:
      - echo Test Started on `date`
      - cd test && mocha test.js | tee test.log
  build:
    commands:
      - echo Build started on `date`
      - aws cloudformation --region ap-northeast-1 package --template-file template.yaml --s3-bucket ${DEV_SAM_BUCKET} --output-template-file outputTemplate.yaml
      - aws cloudformation --region ap-northeast-1 deploy --template-file outputTemplate.yaml --stack-name ${PROJECT_ID} --capabilities CAPABILITY_IAM --parameter-overrides Stage=${STAGE}
  post_build:
    commands:
      - echo Build completed on `date`
artifacts:
  files:
    - '**/*'

実行結果

[Container] 2017/04/29 02:07:51 Waiting for changeset to be created..
[Container] 2017/04/29 02:08:02 Failed to create the changeset: Waiter ChangeSetCreateComplete failed: Waiter encountered a terminal failure state Status: FAILED. Reason: Transform AWS::Serverless-2016-10-31 failed with: Invalid Serverless Application Specification document. Number of errors found: 1. Resource with id [Api] is invalid. Specify either 'DefinitionUri' or 'DefinitionBody' property and not both

template.yamlにはDefinitionBodyが正しく入っているのに怒られた!

解決

aws-cliのバグだったΣ(゚Д゚)

buildspec.ymlの修正

使っていたCodeBuildコンテナのaws-cliが古いことが原因だったようなので、上記issueにも記載の通り、aws-cliをアップデートしてあげる

buildspec.yml
version: 0.1

phases:
  install:
    commands:
      - pip install --upgrade awscli
      - curl -o /usr/local/bin/jq -L https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64 && chmod +x /usr/local/bin/jq
      - mkdir ~/.aws
      - aws sts assume-role --role-arn ${DEV_CFN_ROLE} --role-session-name codebuild | jq -r '"[default]\naws_access_key_id = \(.Credentials.AccessKeyId)\naws_secret_access_key = \(.Credentials.SecretAccessKey)\naws_session_token = \(.Credentials.SessionToken)\n"' >> ~/.aws/credentials
      - cd test && npm install && npm install -g mocha
  pre_build:
    commands:
      - echo Test Started on `date`
      - cd test && mocha test.js | tee test.log
  build:
    commands:
      - echo Build started on `date`
      - aws cloudformation --region ap-northeast-1 package --template-file template.yaml --s3-bucket ${DEV_SAM_BUCKET} --output-template-file outputTemplate.yaml
      - aws cloudformation --region ap-northeast-1 deploy --template-file outputTemplate.yaml --stack-name ${PROJECT_ID} --capabilities CAPABILITY_IAM --parameter-overrides Stage=${STAGE}
  post_build:
    commands:
      - echo Build completed on `date`
artifacts:
  files:
    - '**/*'

実行結果

[Container] 2017/04/29 04:03:34 Waiting for changeset to be created..
[Container] 2017/04/29 04:03:45 Waiting for stack create/update to complete
[Container] 2017/04/29 04:04:16 Successfully created/updated stack - helloproject

無事デプロイ出来ました

教訓

パッケージはアップデートしてから使いましょう。。。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0