1

we are trying to migrate from the v1 CdkPipeline to the v2 CodePipelin. In v1 there was this manualApproval attribute, which one had to set to true and then you had the manual approval after the changeset creation. This doesn't seem to exist anymore, so I tried to follow the new way but for some unknown reason I get this error when trying to create a cdk diff:

Deployment step 'ManualApprovalStep(ChangeSet Approval)' is not supported for CodePipeline-backed pipelines

This is the actual code:

    const jfrogSsm = StringParameter.fromSecureStringParameterAttributes(this, 'ssm', {
      parameterName: '/some-key',
      version: 1,
    });
    const additionalPermissions = new PolicyStatement();
    additionalPermissions.addActions('ssm:GetParameters');
    additionalPermissions.addResources(ssm.parameterArn);

    const pipeline = new OrgCodePipeline(this, 'Pipeline', {
      pipelineName: 'pipeline',
      stage: 'prd',
      github: {
        repo: 'repo-name',
        branch: 'master',
      },
      synthAction: {
        subdirectory: 'infrastructure',
        jfrogApiKey: {
          type: BuildEnvironmentVariableType.PARAMETER_STORE,
          value: jfrogSsm.parameterName,
        },
        buildCommand: 'npx run build',
        rolePolicyStatements: [additionalPermissions],
      },
    });


pipeline.addStage(new MyStage(this, 'MyInfra'), {
  pre: [new ManualApprovalStep('ManualApproval')],
});

pipeline.attachSlackHook({
  emoji: ':frog:',
  mention: '@team-name',
});

attachSlackHook: creates a Notification Lambda which sends a message to slack and is connected to the onStateChange method of the aws-codepipeline inside of cdks pipeline. To accomplish this in v2 we needed to have it as an additional call at the end because we need to call buildPipeline first to access the internal aws-codepipeline inside.

we have an internal construct library, which sets some defaults (called OrgCodePipeline here), which is constructed like this:

export class OrgCodePipeline extends Construct {
  public readonly pipelineName: string;
  public readonly pipeline: CodePipeline;
  private readonly stage: string;

  public constructor(scope: Construct, id: string, props: OrgCodePipelineProps) {
    super(scope, id);

    this.pipelineName = props.pipelineName;
    this.stage = props.stage;

    const commands = createCommands(
      props.stage,
      props.synthAction.subdirectory,
      props.synthAction.synthCommand,
      props.synthAction.buildCommand,
    );

    const input = this.createCodeStarConnection(props.github);

    const synth = new CodeBuildStep('Synth', {
      installCommands: createInstallCommand(props.synthAction.synthType),
      commands,
      input,
      env: {
        JFROG_API_KEY: props.synthAction.jfrogApiKey.value,
      },
      rolePolicyStatements: props.synthAction.rolePolicyStatements,
      primaryOutputDirectory: 'cdk.out',
      buildEnvironment: {
        buildImage: LinuxBuildImage.STANDARD_5_0,
      },
    });

    this.pipeline = new CodePipeline(this, id, {
      pipelineName: props.pipelineName,
      crossAccountKeys: false,
      synth,
    });
  }

createCommands: takes all the commands and concatenates them. In v1 they were splitted between synth and build commands.

createCodeStarConnection: creates a CfnConnection for the given repo and branch inside of our github org and returns the CodePipelineSource.

createInstallCommand: creates the install command for eithe npm or yarn. Also makes sure that our private jfrog artifactory is used

Thanks in advance for the help!

snowiow
  • 65
  • 8
  • What's `OrgCodePipeline`? What does its `addStage` do? – gshpychka Dec 17 '21 at 16:28
  • Are you sure you're using the right ManualApprovalStep? Code suggests it should work -- https://github.com/aws/aws-cdk/blob/dcc9e59d55d17dd71217659573d5f1879295eb1b/packages/%40aws-cdk/pipelines/lib/codepipeline/codepipeline.ts#L524-L537 – kichik Dec 17 '21 at 21:13
  • @kichik they're calling `addStage` on their own custom class, not `pipelines.CodePipeline`, so who knows what their implementation is. – gshpychka Dec 17 '21 at 23:25
  • it just forwards the call to the real CodePipelines addStage function, so you don't need to call pipeline.pipeline.addStage(). This is the implementation: ``` public addStage(stage: Stage, options?: AddStageOpts): StageDeployment { return this.pipeline.addStage(stage, options); } ``` and both ways give the same error – snowiow Dec 18 '21 at 19:48

0 Answers0