question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[@aws-cdk/pipelines] Source (branch) mapping to account/stage

See original GitHub issue

❓ General Issue

The Question

Is it possible, using the new CDKPipeline (preview) library @aws-cdk/pipelines to have a specify a different source action for each stage/account? This could be a usage failing, but my scenario looks like this:

We are using GitFlow- so we have develop, release and master branches. Each one of these branches should deploys to a different AWS account. Let’s assume that develop is a develop account, release is a release account and master is a master account.

In this scenario, if I use a GitHub action for my source, I don’t appear to have a way to filter the GitHub action’s branch to which stage (account) this should deploy to?

Our pipeline process is essentially the same in each of these branches - albeit with a few bits turned on or off at each stage (I know that the Context lookup isn’t yet available, but we should be able to map those settings appropriately when it is).

We have a build, deploy and test action in our pipeline, and that pipeline is currently created 3 times (3 pipeline stacks deployed separately) for each branch we want to map to an AWS Account… so it feels like this should be something I use CdkPipelines for.

Any recommended usage patterns, questions, or documentation would be helpful if I’m going about this the wrong way - equally I thought as this is in Preview and this (may) be a valuable feature I should raise it.

Environment

  • CDK CLI Version: 1.56.0
  • Module Version: 1.56.0
  • Node.js Version: 12.4.0
  • OS: Ubuntu (WSL)
  • Language (Version): TypeScript (3.9.7)

Other information

If this is within the scope of CdkPipelines, An example of what I might expect this to look like:

    const devStage = pipeline.addApplicationStage(new MyApplication(this, 'Dev', {
      env: {
        account: '123456789012',
        region: 'eu-west-1',
      },
      // sourceAction is a new paramter we can pass to the applicationStage? 
      sourceAction: new GitHubSourceAction({ 
         repo: "somerepo",
         actionName: "source",
         oauthToken: new SecretValue(""),
         owner: "someowner",
         branch: "develop",
         output: devArtifact
       });
    }));

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:1
  • Comments:7 (1 by maintainers)

github_iconTop GitHub Comments

7reactions
MarcoAlessandroRiggiocommented, Dec 9, 2020

A single pipeline is just not able to express that logic, so you will have to resort to multiple pipelines. Fortunately, since this is code you should be able to make 3 similar pipelines easily enough with a for loop.

Hi @rix0rrr, we’ve tried to create two CdkPipeline in a for loop like you suggested but in UpdatePipeline Stage one of the two pipelines always fails with the following error: Call failed: describeChangeSet({"StackName":"<pipeline-stack-id>","ChangeSetName":"<change-set-name>"}) => ChangeSet [<change-set-name>] does not exist

 ["development", "production"].forEach(environment => {
            process.env.NODE_ENV = environment;
            delete require.cache[require.resolve("config")];
            const config = require('config');  // reload module for change configuration file based on environment 

            new CdkPipeline(this, `${environment}-cloud-pipeline`, {
                pipelineName: `${environment}-cloud-pipeline`,
                cloudAssemblyArtifact,
                sourceAction: new codepipeline_actions.CodeCommitSourceAction({
                    actionName: 'CodeCommit_Source',
                    repository: Repository.fromRepositoryName(this, `${environment}-repository`, config.repositoryName),
                    output: sourceArtifact,
                    branch: config.branch
                }),
                synthAction: SimpleSynthAction.standardNpmSynth({
                    sourceArtifact,
                    cloudAssemblyArtifact,
                    buildCommand: 'npm run build'
                })
            }).addApplicationStage(new CdkInfrastructureStage(this, environment, environment, {
                env: {account: config.account, region: config.region}
            }));
        });

How should it work? Do you have any suggestions?

Thanks Best Regards

4reactions
BrianFarnhillcommented, Aug 6, 2020

@AlanChauchet Yep, the codes on an private repo but here is the class that sets up the two pipelines:

const sourceArtifact = new codepipeline.Artifact();
const cloudAssemblyArtifact = new codepipeline.Artifact();

const synthParams = {
    buildCommand: 'npm run build --prefix ../../ && npm run test --prefix ../../',
    installCommand: 'npm run bootstrap --prefix ../../',
    subdirectory: 'packages/infrastructure',
}

function CreatePipeline(stack: cdk.Stack, sourceRepo: codecommit.IRepository, branchName: string) {

    const pipeline = new pipelines.CdkPipeline(stack, `${branchName}Pipeline`, {
        cloudAssemblyArtifact,
        sourceAction: new actions.CodeCommitSourceAction({
            actionName: 'CodeCommit',
            output: sourceArtifact,
            repository: sourceRepo,
            branch: branchName
        }),
        synthAction: pipelines.SimpleSynthAction.standardNpmSynth({
            ...synthParams, sourceArtifact, cloudAssemblyArtifact
        })
    })

    const stageName = (branchName === 'master' ? 'prod' : 'dev')
    const accountId = (branchName === 'master' ? 'ACCOUNTID-PROD' : 'ACCOUNTID-DEV')

    pipeline.addApplicationStage(new CloudshotStage(stack, stageName, {
        env: { account: accountId, region: 'ap-southeast-2' }
    }))

    return pipeline
}

export class MyPipelines extends cdk.Stack {

    constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
        super(scope, id, props)
        
        const sourceRepo = codecommit.Repository.fromRepositoryName(this, "SourceRepo", 'MyRepoName')

        CreatePipeline(this, sourceRepo, 'dev')
        CreatePipeline(this, sourceRepo, 'master')
    }

}

Tweak the approach to putting in your branch names or account IDs to suit however you want to do that, but that’s the basic premise to how it works.

Read more comments on GitHub >

github_iconTop Results From Across the Web

aws-cdk/pipelines module - AWS Documentation - Amazon.com
CDK Pipelines will automatically discover all Stacks in the given Stage object, determine their dependency order, and add appropriate actions to the pipeline...
Read more >
Continuous integration and delivery (CI/CD) using CDK ...
CDK Pipelines is a construct library module for painless continuous delivery of AWS CDK applications. Whenever you check your AWS CDK app's source...
Read more >
Multi-branch pipeline management and infrastructure ...
The following solution creates a new AWS CDK Pipeline within a development account for every new branch created in the source repository ...
Read more >
class Pipeline (construct) · AWS CDK
Create KMS keys for cross-account deployments. crossRegionReplicationBuckets? { [string]: IBucket }, A map of region to S3 bucket name used for cross- ...
Read more >
class CodePipelineSource · AWS CDK
static ecr(repository, props?) Returns an ECR source. ; static gitHub(repoString, branch, props?) Returns a GitHub source, using OAuth tokens to authenticate ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found