Problem
When passing S3 artifacts to a AWS CodeBuild project through AWS CodePipeline, you might receive the error "Error calling startBuild: Source version should be empty for S3 folder source location" (CodeBuild, 400, InputValidationException). The error can be reproduced with the following CloudFormation definition:
MyCodeBuild:
Type: AWS::CodeBuild::Project
Properties:
Name: "MyCodeBuild"
Artifacts:
Type: S3
# ...
Source:
Type: S3
BuildSpec: buildspec.yaml
Location: !Join ["", [!GetAtt [CodeBuildBucket, Arn], "/"]]
# ...
MyCodePipeline:
Type: AWS::CodePipeline::Pipeline
Properties:
Name: "MyCodePipeline"
Stages:
- Actions:
- ActionTypeId:
Category: Source
Owner: "AWS"
Provider: "S3"
Version: "1"
Name: PULL_CODEBUILD_SOURCES
RunOrder: 1
Configuration:
PollForSourceChanges: false
S3Bucket: !Ref CodeBuildBucket
S3ObjectKey: "buildspec.yaml"
OutputArtifacts:
- Name: CODEBUILD_SOURCES
The reason for the issue is, that MyCodeBuild
does not declare any S3 object version for the primary source artifact. For a immutable file, this might be okay. But when having a dynamic input file with changing values, this is not a feasible way. A manual build of MyCodeBuild
through the UI or CLI can be triggered without any problems.
But as soon as the MyCodePipeline
triggers the build after the buildspec.yaml
has changed, CodePipeline automatically pass the object version of the buildspec.yaml
to CodeBuild's inputArtifacts
definition.
Solution
Using some sort of SourceVersion to MyCodeBuild
does not work. You have to change the Source.Type
from S3
to CODEBUILD
. The drawback for this solution is, that you can no longer trigger the CodeBuild project manually:
MyCodeBuild:
Type: AWS::CodeBuild::Project
Properties:
Name: "MyCodeBuild"
Artifacts:
Type: CODEBUILD
# ...
Source:
Type: CODEBUILD
BuildSpec: buildspec.yaml
Location: !Join ["", [!GetAtt [CodeBuildBucket, Arn], "/"]]