I try to use codebuild with compose docker in docker and deploy to ECR hub.
While using buildSpec: BuildSpec.fromSourceFilename I encountered this error:
If the Project's source is NoSource, you need to provide a concrete buildSpec
xxxProject/node_modules/constructs/lib/construct.ts:407
throw new Error(`Validation failed with the following errors:\n ${errorList}`);
^
Error: Validation failed with the following errors:
[Bob-Pipeline-dev] Stage 'Build' must have at least one action
If I use buildSpec: BuildSpec.fromObject, it works @@, no idea
File structure:

File: pipeline.ts
const pipeline = new Pipeline(
this,
`Pipeline-${environment.ENV}`,
{
pipelineName: `pipeline-${environment.ENV}`,
},
)
const sourceStage = pipeline.addStage({
stageName: 'Source',
})
const buildStage = pipeline.addStage({
stageName: 'Build',
placement: {
justAfter: sourceStage,
},
})
const sourceOutput = new Artifact()
const sourceAction = new GitHubSourceAction({
actionName: `codebuild-action-${environment.ENV}`,
owner: 'xxx,
repo: 'xxx',
oauthToken: cdk.SecretValue.secretsManager('tGitHubToken'),
output: sourceOutput,
branch: `${environment.branch}`,
trigger: GitHubTrigger.WEBHOOK,
})
sourceStage.addAction(sourceAction)
const buildRole = new iam.Role(
this,
`IamRole-${environment.ENV}`,
{
assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com'),
},
)
const codeBuild = new Project(
this,
`CodeBuildProject-${environment.ENV}`,
{
role: buildRole,
environment: {
buildImage: LinuxBuildImage.fromDockerRegistry('docker:dind')
},
buildSpec: BuildSpec.fromSourceFilename('./buidspec.yml')
const buildAction = new CodeBuildAction({
actionName: 'Build',
input: sourceOutput,
project: codeBuild,
})
buildStage.addAction(buildAction)
}
File: buildspec.yml
version: 0.2
phases:
install:
runtime-versions:
nodejs: 12
python: 3.8
commands:
- apk add --no-cache python py-pip jq
- pip install awscli
- echo $AWS_ACCESS_KEY_ID
- echo $AWS_SECRET_ACCESS_KEY
build:
commands:
- $(aws ecr get-login --no-include-email --region ${AWS_REGION_ECR})
- |
for dir in `find packages -type d -mindepth 1 -maxdepth 1 -not -name utils -not -name types -exec basename {} \;`;
do
docker build -f Dockerfile.${dir} -t ${REPOSITORY_URL}:${dir} .
docker push ${REPOSITORY_URL}:${dir}
done
post_build:
commands:
- i=1
- CURRENT_SERVICE_COUNT=`aws ecs list-services --region ${AWS_REGION_ECS} --cluster ${CLUSTER_NAME} | jq --raw-output ".serviceArns" | jq length`
- CURRENT_SERVICES=`aws ecs list-services --region ${AWS_REGION_ECS} --cluster ${CLUSTER_NAME} | jq --raw-output ".serviceArns"`
- |
while [ "$i" -le "$CURRENT_SERVICE_COUNT" ]; do
SERVICE=`echo $CURRENT_SERVICES | jq --raw-output ".[$i-1]"`
aws ecs update-service --region ${AWS_REGION_ECS} --service ${SERVICE} --cluster ${CLUSTER_NAME} --force-new-deployment
i=$(( i + 1 ))
done
Hey @ookangzheng ,
change Project to PipelineProject in your code, and everything will work again.
Thanks,
Adam
I got this error when I put buildspec.yml under root directory of my cdk project, I think when I exec cdk synth it doesnt upload my buildspec.yml to S3
2020/04/15 06:14:31 CODEBUILD_SRC_DIR=/codebuild/output/src356100413/src
2020/04/15 06:14:31 Phase complete: DOWNLOAD_SOURCE State: FAILED
2020/04/15 06:14:31 Phase context status code: YAML_FILE_ERROR Message: stat /codebuild/output/src356100413/buildspec.yml: no such file or directory
Screenshot:

Of course - you put your buildspec in the root of your project, which corresponds to codebuild.BuildSpec. fromSourceFilename('buildspec.yml'), but in your code you have codebuild.BuildSpec. fromSourceFilename('../buildspec.yml').
BTW - buildspec.yml in the root of your project is the default, so just get rid of the buildSpec property completely in PipelineProject.
Nope, this wont work either.
Changed code to : codebuild.BuildSpec. fromSourceFilename('buildspec.yml')
and place buildspec.yml under cdk root dir, still not working.
How can I make sure when execute cdk synth and cdk deploy will automatic sync buildspec.yml to AWS Codebuild? , cuz under cdk.out/ doesn't seem to have any buildspec.yml or xxx.zip file.

I comment out buildSpec completely in PipelineProject. still not found...

The BuildSpec path is relative to the root of the project, not relative to the directory the CDK code is in. So, since its in lib in your project, you need codebuild.BuildSpec.fromSourceFilename('lib/buildspec.yml').
Actually I realized that I split CDK and my code into 2 different separate Github Repositories. While I use codebuild.BuildSpec. fromSourceFilename('buildspec.yml'), I have to put buildspec.yml under my code repo.
Great, glad you got it resolved!
Most helpful comment
Hey @ookangzheng ,
change
ProjecttoPipelineProjectin your code, and everything will work again.Thanks,
Adam