Skip to content
Advertisement

SelfMutate stage failing with CodePipeline

I’m trying to create a CI/CD using CDK pipeline with the import software.amazon.awscdk.pipelines.CodePipeline in Java. This pipeline creates another stack named xxxJavaxxxStack. The pipeline is able to connect to external github, which, when change is detected, triggers the pipeline.

In the class xxxPipelinexxxApp.java I’m calling both the stacks xxxJavaxxxStack and xxxPipelinexxxStack. I have successfully been able to cdk synth both separately and cdk deploy them separately.

This creates 2 different cloudformation templates, it also creates the pipeline and the first 2 stages go through. However, the pipeline is failing at SelfMutate stage.

The pipeline stages are:

  • Source – Success
  • Build – Success
    • Synth – Success
  • SelfMutate – Failed

The error:

Error: No stacks match the name(s) xxxPipelinexxxStack

at CdkToolkit.validateStacksSelected (/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:545:13)
    at CdkToolkit.selectStacksForDeploy (/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:492:10)
    at CdkToolkit.deploy (/usr/local/lib/node_modules/aws-cdk/lib/cdk-toolkit.ts:120:20)
    at initCommandLine (/usr/local/lib/node_modules/aws-cdk/bin/cdk.ts:267:9)

Command did not exit successfully cdk -a . deploy xxxPipelinexxxStack --require-approval=never --verbose exit status 1
Phase complete: BUILD State: FAILED
Phase context status code: COMMAND_EXECUTION_ERROR Message: Error while executing command: cdk -a . deploy xxxPipelinexxxStack --require-approval=never --verbose. Reason: exit status 1

Command: sudo cdk bootstrap Result:

@aws-cdk/core:newStyleStackSynthesis' context set, using new-style bootstrapping  ⏳  Bootstrapping environment aws://xxxxxx729/us-east-1... Trusted accounts for deployment: xxxxxx729 Trusted accounts for lookup: (none) Execution policies: arn:aws:iam::aws:policy/AdministratorAccess  Environment aws://xxxxxx729/us-east-1 bootstrapped (no changes).

App Code –

public class xxxxPipelinexxxApp {
    public static void main(final String[] args) {
        App app = new App();
        final xxxJavaxxxStack javaStack = new xxxJavaxxxStack(
            app,
            "xxxJavaxxxStack",
            StackProps.builder()
                .env(
                    new Environment.Builder()
                        .account("xxxxxx5729")
                        .region("us-east-1")
                        .build()
                )
                .build()
        );
        final xxxPipelinexxxStack pipelineStack = new xxxPipelinexxxStack(
                app,
                "xxxPipelinexxxStack",
                StackProps.builder()
                    .env(
                        new Environment.Builder()
                            .account("xxxxxx5729")
                            .region("us-east-1")
                            .build()
                    )
                    .build()
        );
        app.synth();
    }
}

Stack code –

public class xxxPipelinexxxStack extends Stack {
    public xxxPipelinexxxStack(final Construct scope, final String id) {
        this(scope, id, null);
    }

    public xxxPipelinexxxStack(final Construct scope, final String id, final StackProps props) {
        super(scope, id, props);
        CodePipeline pipeline = CodePipeline.Builder
                .create(this, "pipeline")
                .pipelineName("xxxPipelineXXX")
                .synth(
                        ShellStep.Builder.create("Synth")
                            .input(
                                    CodePipelineSource.connection("<git-owner>/<git-repo>", "main",
                                        ConnectionSourceOptions.builder().connectionArn("<git-repo-connection-arn>").build()
                                    )
                            )
                            .commands(
                                    Arrays.asList("mvn clean install", "npx cdk synth")
                            ).build()
                ).build();
        final xxxPipelineXXXStage deploy = new xxxPipelineXXXStage(this, "Deploy");
        pipeline.addStage(deploy);
    }
}

P.S: I’m using a different IAM user, to deploy, than the root user as apparently there are issues when trying to deploy the pipeline using root user.

Any help is much appreciated.

Advertisement

Answer

The problem existed as I used 2 different github repositories (repos). The first was xxxJava repo which had xxxJavaxxxApp.java and xxxJavaxxxStack.java classes along with other necessary files. The second was a xxxPipeline repo which had xxxPipelinexxxApp.java and xxxPipelinexxxStack.java along with other necessary files.

Initially I was wrong in using xxxJava repo in git-repo for the code <git-owner>/<git-repo> which was synthesising the xxxJavaxxxStack and the pipeline was expecting xxxPipelinexxxStack to deploy it. The solution was to add the pipeline repo while creating the connection to github. since the stage was unable to find this stack, it was failing at the ‘selfmutate’ stage.

I struck gold when @gshpychka mentioned to add the cdk ls to my synth step to see what stack was getting synth-ed! commands(Arrays.asList("mvn clean install", "npx cdk synth", "npx cdk ls"))

The point to remember – till the ‘selfmutate’ stage, the pipeline related changes get deployed, and any stages added after, the actual stack/AWS-services get deployed.

User contributions licensed under: CC BY-SA
8 People found this is helpful
Advertisement