Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

codepipeline-slack usage with multiple pipelines in a single stack #63

Open
ChristopheBougere opened this issue Dec 16, 2020 · 0 comments

Comments

@ChristopheBougere
Copy link

Context

I'm following this tutorial to setup a CDK pipeline.
As I want to follow a gitflow like workflow (develop deploying to Staging and main deploying to Prod), I am creating multiple CDK pipelines within a single CDK stack.
And for each pipeline, I would like to setup a slack notifier and in some case a slack approval action.
However when deploying, I am facing this error:

[Container] 2020/12/16 11:09:22 Running command npx cdk synth
Bundling asset MyProjectPipelineStack/Staging/MyStack/MyLambda/Code/Stage...
There is already a Construct with name 'SlackNotifierFunction' in MyProjectPipelineStack [MyProjectPipelineStack]
Subprocess exited with error 1

This is due to the fact that all the resources in @cloudcomponents/cdk-codepipeline-slack have static names, widh prevent from deploying multiple instances in the same stack, in this case SlackNotifierFunction.

My first thought was that we should add the construct ID to the resources it creates. However, that means it would create multiples lambda and API gateway endpoints, which would mean creating multiple slack apps (one for each endpoints) and wouldn't be convenient.

What is, in your opinion, the best way to allow deploying multiple pipelines with slack in a single stack?

Code of the pipeline stack

import * as codepipeline from '@aws-cdk/aws-codepipeline';
import * as codepipeline_actions from '@aws-cdk/aws-codepipeline-actions';
import { Construct, SecretValue, Stack, StackProps } from '@aws-cdk/core';
import { CdkPipeline, SimpleSynthAction } from '@aws-cdk/pipelines';
import { SlackApprovalAction, SlackNotifier } from '@cloudcomponents/cdk-codepipeline-slack';
import { MyProjectStage } from './my-project-stage';

export class MyProjectPipelineStack extends Stack {
  constructor(scope: Construct, id: string, props?: StackProps) {
    super(scope, id, props);

    this.createPipeline('develop', 'Staging');
    this.createPipeline('main', 'Prod', true);
  }

  createPipeline(branch: string, stage: string, slack=false) {
    const sourceArtifact = new codepipeline.Artifact();
    const cloudAssemblyArtifact = new codepipeline.Artifact();
    const pipeline = new CdkPipeline(this, `${stage}-Pipeline`, {
      // The pipeline name
      pipelineName: `${stage}-MyProjectPipeline`,
      cloudAssemblyArtifact,

      // Where the source can be found
      sourceAction: new codepipeline_actions.GitHubSourceAction({
        actionName: 'GitHub',
        output: sourceArtifact,
        oauthToken: SecretValue.secretsManager('github-token'),
        owner: '<GITHUB_OWNER>',
        repo: '<GITHUB_REPO>',
        branch,
      }),

      // How it will be built and synthesized
      synthAction: SimpleSynthAction.standardNpmSynth({
        sourceArtifact,
        cloudAssemblyArtifact,

        // We need a build step to compile the TypeScript Lambda
        buildCommand: 'npm run build',
      }),
    });

    const slackBotToken = SecretValue.secretsManager('slack-bot-token').toString();
    const slackSigningSecret = SecretValue.secretsManager('slack-signing-secret').toString();
    const slackChannel = 'notifications-aws';

    const applicationStage = pipeline.addApplicationStage(new MyProjectStage(this, stage, {
      env: { account: '<AWS_ACCOUNT_ID>', region: '<AWS_REGION>' },
    }));
    if (slack) {
      applicationStage.addActions(new SlackApprovalAction({
        actionName: `${stage}-SlackApproval`,
        slackBotToken,
        slackSigningSecret,
        slackChannel,
        // externalEntityLink: 'http://cloudcomponents.org',
        additionalInformation: `Would you like to promote the build to ${stage}?`,
      }));
      new SlackNotifier(this, `${stage}-SlackNotifier`, {
        pipeline: pipeline.codePipeline,
        slackBotToken,
        slackSigningSecret,
        slackChannel,
      });
    }

    return pipeline;
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant