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.

CodeCommit and CodePipeline in different stacks leads to circular dependency

See original GitHub issue

❓ General Issue

I want to have a CodeCommit repository in one stack triggering a CodePipeline in another stack, both stacks being deployed to the same region.

When passing the repo as a prop to the stack containing the pipeline, I get a circular dependency error: 'RepoStack' depends on 'PipelineStack' (RepoStack -> PipelineStack/Pipeline/Resource.Ref, RepoStack -> PipelineStack/Pipeline/EventsRole/Resource.Arn). Adding this dependency (PipelineStack -> RepoStack/Repository/Resource.Name) would create a cyclic reference.

My code looks as follows:

const repoStack = new RepoStack(app, 'RepoStack', {
  env: envDevOps,
});
new PipelineStack(app, 'PipelineStack', {
  env: envDevOps,
  repo: repoStack.repo,
});
export class RepoStack extends cdk.Stack {
  public readonly repo: codecommit.Repository;

  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    this.repo = new codecommit.Repository(this, 'Repository', {
      repositoryName: 'MyRepo',
    });
  }
}
export class PipelineStack extends cdk.Stack {
  constructor(scope: cdk.Construct, id: string, props: PipelineStackProps) {
    super(scope, id, props);

    const sourceAction = new codepipeline_actions.CodeCommitSourceAction({
      actionName: 'CodeCommit_Source',
      repository: props.repo,
      output: sourceOutput,
    });
    
    // ...
  }
}

The Question

How can I have a CodeCommit repository in one stack triggering a CodePipeline in another stack without introducing a circular dependency (both in the same account/region)?

When the RepoStack is deployed to another account, everything works fine. I suspect that, in this case, the cross-account support stacks do the magic. Still, it comes to a surprise that support for cross-references across accounts is better than support for cross-references within the same account.

I think this problem can be generalized to many scenarios with circular dependencies.

Environment

  • CDK CLI Version: 1.39.0 (build 5d727c1)
  • OS: MacOS Catalina
  • Language: all

Issue Analytics

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

github_iconTop GitHub Comments

3reactions
brendonmathesoncommented, Jun 4, 2020

I’ve also hit this issue in the past few days with more or less the same configuration as in the original post while attempting to migrate a plain CloudFormation implementation that also had these resources split into separate stacks.

I dug into the CDK code a bit to try to understand the root cause and one of the causes appears to be the auto-created IAM resources such as the statement created in CodeCommitSourceAction.bound() as well as the auto-created CW Event - these end up being dependencies of the repo.

Agree with the comment by @asterikx that this is probably a generalizable issue. Anywhere that a construct makes changes to a resource that it does not directly own, there is potential for this to arise. There should be a clear rule enforced that constructs can only make changes to their own resources otherwise the dependencies will never be manageable. If you search for “cyclic” in the open issues you’ll see a number of variants of this problem.

In this case it’s convenient that the Pipeline constructs try to auto-create policies for me but I’d rather it fail fast and tell me I have to compose in another construct that creates the role so that I have more control and more transparency and so we don’t get phantom dependencies.

2reactions
flashflexprocommented, Aug 31, 2020

Yeah ,this is a bug, in root_stack:

                        new pipelineActions.CloudFormationCreateUpdateStackAction({
                            actionName: 'deploy_child_stack',
                            stackName: 'child_stack'
                        }),

will be recognized as a dependency root_stack -> child_stack, throw root_stackDeploychild_stackPipelineActionRole with policy:

            Action:
              - 'cloudformation:CreateStack'
....
              - 'cloudformation:ValidateTemplate'
            Effect: Allow
            Resource: !Join
              - ''
              - - 'arn:'
                - !Ref 'AWS::Partition'
                - ':cloudformation:'
                - !Ref 'AWS::Region'
                - ':'
                - !Ref 'AWS::AccountId'
                - ':stack/child_stack/*'`

then you can’t reference from child_stack to root_stack anymore

This is definitely a bug, because root_stack does NOT really depend on child_stack here!

Read more comments on GitHub >

github_iconTop Results From Across the Web

Resolving cyclical dependencies between AWS CDK ...
Create a custom resource to tie things together. If you have a true circular dependency that cannot be resolved (even in the same...
Read more >
Automatically detect changes and initiate different ...
This pattern helps you automatically detect changes to the source code of a monorepo-based application in AWS CodeCommit and then initiate a pipeline...
Read more >
CDK Cross-Account Pipelines - AWS in Plain English
A circular dependency, which is always fun. In addition, we want code updates in CodeCommit in Dev to trigger CodePipeline in Tools.
Read more >
What is a circular dependency in AWS CloudFormation? - Quora
Stack Alpha creates its own set of AWS components but also refers to another component that is created in stack beta. Beta too...
Read more >
CodePipeline for Serverless Applications With ... - Medium
Simple Codepipeline using CloudFormation, The Serverless Framework, ... any of the templates, since this would lead to a circular reference.
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 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