aws-cdk: Got weird error while referencing from Codebuild source = buildspec.yml

❓ General Issue

The Question

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

Environment

  • CDK CLI Version: 1.32.1
  • OS: : OSX Catalina
  • Language: Typescript

Sample code with buildspec.yml

File structure: image

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

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 19 (10 by maintainers)

Most upvoted comments

Hey @ookangzheng ,

change Project to PipelineProject in your code, and everything will work again.

Thanks, Adam

@skinny85 Great thread, thank you. Could I ask for a little more clarification on the difference between Project and PipelineProject in the context of a CodeBuild deployed and ran under a pipeline ? What does PipelineProject have that Project doesn’t ?

The only difference is that PipelineProject sets the sourceType property of the Project correctly. That’s the only difference between the two.

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.

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.