aws-quickstart / cdk-eks-blueprints

AWS Quick Start Team
Apache License 2.0
446 stars 198 forks source link

CodePipelineStack: Relative path argument generates broken buildspec.yml #913

Open EandrewJones opened 7 months ago

EandrewJones commented 7 months ago

Describe the bug

I am trying to use a monorepo approach where I store the EKS IaC in one directory alongside various application config directories. The repository method allows users to define a relative path that points to a sub-directory containing their EKS blueprint stack. However, this feature does not work.

My codepipeline repository is defined as follows:

CodePipelineStack.builder()
...[methods continue]
.repository({
        repoUrl: "odni-seedlings",
        credentialsSecretName: credentialsSecretName,
        targetRevision: "main",
        path: "./eks",
      })
...[methods continue]

Expected Behavior

I expect for the pipeline to successfully navigate to the relative path and build.

Current Behavior

The the stack generates a faulty buildspec.yml that tries to cd into the relative path twice causing a failed build.

Faulty buildspec:

{
  "version": "0.2",
  "phases": {
    "install": {
      "commands": [
        "n stable",
        "npm install -g aws-cdk@2.115.0",
        "cd ./eks && npm install"
      ]
    },
    "build": {
      "commands": [
        "cd ./eks",
        "npm run build",
        "npx cdk synth --app 'npx ts-node bin/odni-eks.ts'"
      ]
    }
  },
  "artifacts": {
    "base-directory": "cdk.out",
    "files": "**/*"
  }
}

Logs from failed build:

[Container] 2024/01/27 20:51:00.790232 Waiting for agent ping
[Container] 2024/01/27 20:51:00.991629 Waiting for DOWNLOAD_SOURCE
[Container] 2024/01/27 20:51:01.919739 Phase is DOWNLOAD_SOURCE
[Container] 2024/01/27 20:51:01.920805 CODEBUILD_SRC_DIR=/codebuild/output/src3066254282/src
[Container] 2024/01/27 20:51:01.921269 YAML location is /codebuild/readonly/buildspec.yml
[Container] 2024/01/27 20:51:01.922977 Setting HTTP client timeout to higher timeout for S3 source
[Container] 2024/01/27 20:51:01.923152 Processing environment variables
[Container] 2024/01/27 20:51:02.145137 No runtime version selected in buildspec.
[Container] 2024/01/27 20:51:02.192497 Moving to directory /codebuild/output/src3066254282/src
[Container] 2024/01/27 20:51:02.194067 Unable to initialize cache download: no paths specified to be cached
[Container] 2024/01/27 20:51:02.286841 Configuring ssm agent with target id: codebuild:d7753531-6826-42ef-b937-9d6a56f7f8b1
[Container] 2024/01/27 20:51:02.323204 Successfully updated ssm agent configuration
[Container] 2024/01/27 20:51:02.323576 Registering with agent
[Container] 2024/01/27 20:51:02.323590 Phases found in YAML: 2
[Container] 2024/01/27 20:51:02.323595  INSTALL: 3 commands
[Container] 2024/01/27 20:51:02.323598  BUILD: 3 commands
[Container] 2024/01/27 20:51:02.323894 Phase complete: DOWNLOAD_SOURCE State: SUCCEEDED
[Container] 2024/01/27 20:51:02.323908 Phase context status code:  Message: 
[Container] 2024/01/27 20:51:02.408798 Entering phase INSTALL
[Container] 2024/01/27 20:51:02.409298 Running command n stable
  installing : node-v20.11.0
       mkdir : /usr/local/n/versions/node/20.11.0
       fetch : https://nodejs.org/dist/v20.11.0/node-v20.11.0-linux-x64.tar.xz
     copying : node/20.11.0
   installed : v20.11.0 (with npm 10.2.4)
[Container] 2024/01/27 20:51:24.722008 Running command npm install -g aws-cdk@2.115.0 added 1 package in 1s
[Container] 2024/01/27 20:51:26.282711 Running command cd ./eks && npm install
added 520 packages, and audited 555 packages in 14s
52 packages are looking for funding
  run `npm fund` for details
found 0 vulnerabilities
[Container] 2024/01/27 20:51:40.374238 Phase complete: INSTALL State: SUCCEEDED
[Container] 2024/01/27 20:51:40.374258 Phase context status code:  Message: 
[Container] 2024/01/27 20:51:40.408181 Entering phase PRE_BUILD
[Container] 2024/01/27 20:51:40.409819 Phase complete: PRE_BUILD State: SUCCEEDED
[Container] 2024/01/27 20:51:40.409832 Phase context status code:  Message: 
[Container] 2024/01/27 20:51:40.441956 Entering phase BUILD
[Container] 2024/01/27 20:51:40.442495 Running command cd ./eks
/codebuild/output/tmp/script.sh: 4: cd: can't cd to ./eks
[Container] 2024/01/27 20:51:40.456830 Command did not exit successfully cd ./eks exit status 2
[Container] 2024/01/27 20:51:40.490547 Phase complete: BUILD State: FAILED
[Container] 2024/01/27 20:51:40.490566 Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: cd ./eks. Reason: exit status 2
[Container] 2024/01/27 20:51:40.520448 Entering phase POST_BUILD
[Container] 2024/01/27 20:51:40.522003 Phase complete: POST_BUILD State: SUCCEEDED
[Container] 2024/01/27 20:51:40.522017 Phase context status code:  Message: 
[Container] 2024/01/27 20:51:40.596243 Expanding base directory path: cdk.out
[Container] 2024/01/27 20:51:40.598130 Assembling file list
[Container] 2024/01/27 20:51:40.598145 Expanding cdk.out
[Container] 2024/01/27 20:51:40.599821 Skipping invalid file path cdk.out
[Container] 2024/01/27 20:51:40.599914 Phase complete: UPLOAD_ARTIFACTS State: FAILED
[Container] 2024/01/27 20:51:40.599924 Phase context status code: CLIENT_ERROR Message: no matching base directory path found for cdk.out

Reproduction Steps

You should be able to reproduce this with an minimal example of a blueprint that uses a code pipeline deployed from a repo with a relative path.

Possible Solution

Remove the cd into the relative path from the build phase of the buildspec.

Additional Information/Context

No response

CDK CLI Version

2.115.0

EKS Blueprints Version

1.13.1

Node.js Version

20.11.0

Environment details (OS name and version, etc.)

Linux EC2

Other information

No response

AmmarRahman commented 7 months ago

I have gone around that by using the absolute path with codebuild builtin variable:

.repository({
        repoUrl: "odni-seedlings",
        credentialsSecretName: credentialsSecretName,
        targetRevision: "main",
        path: "$CODEBUILD_SRC_DIR/eks",
      })

However, It does fail in the artifact upload stage as cdk.out is assuming the output directory is at the root

This can be rectified by either passing the path as primaryOutputDirectory parameter to CDK pipeline or setting an -o flag to explicityl generate cdk.out at the root of the build instance

EandrewJones commented 7 months ago

Thanks. I was considering an absolute path, but wasn't sure what the codebuild working directory was. Good to know you can access it via that builtin variable.

However, as you note, it still fails later. I'd like to see a permanent fix for this. It should be a tiny change.

Best

Evan Jones Website: www.ea-jones.com

On Mon, Jan 29, 2024 at 6:56 AM Ammar Rahman @.***> wrote:

I have gone around that by using the absolute path with codebuild builtin variable:

.repository({ repoUrl: "odni-seedlings", credentialsSecretName: credentialsSecretName, targetRevision: "main", path: "$CODEBUILD_SRC_DIR/eks", })

However, It does fail in the artifact upload stage as cdk.out is assuming the output directory is at the root

— Reply to this email directly, view it on GitHub https://github.com/aws-quickstart/cdk-eks-blueprints/issues/913#issuecomment-1914543580, or unsubscribe https://github.com/notifications/unsubscribe-auth/AJ2T6AOZSPAQO3B36S2QRGTYQ6FAPAVCNFSM6AAAAABCNUG2YGVHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMJUGU2DGNJYGA . You are receiving this because you authored the thread.Message ID: @.***>

shapirov103 commented 6 months ago

One potential and fairly complex workaround (if the customer cannot wait for the PR linked here to be merged and released): Assign the stack that is produced by the pipeline builder to a const, then iterate over the child nodes or use find APIs. There will be a cdkpipelines.CodePipeline construct in the list with id set to the name that you gave to the pipeline. if you get it, you can invoke (construct.synth as cdkpipelines.ShellStep).primaryOutputDirectory("path-to-cdk.out");

EandrewJones commented 6 months ago

One potential and fairly complex workaround (if the customer cannot wait for the PR linked here to be merged and released): Assign the stack that is produced by the pipeline builder to a const, then iterate over the child nodes or use find APIs. There will be a cdkpipelines.CodePipeline construct in the list with id set to the name that you gave to the pipeline. if you get it, you can invoke (construct.synth as cdkpipelines.ShellStep).primaryOutputDirectory("path-to-cdk.out");

Thanks, Mikhail. I can wait for now.

shapirov103 commented 6 months ago

This is now in 1.14.0 release. Please let me know if it addressed your issue. https://aws-quickstart.github.io/cdk-eks-blueprints/pipelines/#monorepo-support