Search code examples
amazon-web-servicesaws-cloudformationaws-cdkaws-codebuild

CDK: How to use same Iam role between 2 different stacks?


I have a stack which creates 2 different codebuild projects.

const codeBuildProject = new CodeBuildProjects(this, 
    'pipelineCodeBuildProjects', {
          PlanProjectName: 'one-project',
          DeployProjectName: 'second-project'
          OneProjectIamRoleName: 'iam-role',
          twoProjectIamRoleName: 'iam-role'
        }) 

This is stack class

export class CodeBuildProjects extends cdk.Stack {
    public readonly plan: codeBuildProject;
    public readonly deploy: codeBuildProject;

    constructor(scope: Construct, id: string, props: CodeBuildProjectProps) {

        super(scope, id, props);


        this.plan = new codeBuildProject(this, 'one-project', {
            projectName: props.oneProjectName,
            description: 'some desc',
            buildspec: codebuild.BuildSpec.fromObject(yaml.parse(fs.readFileSync('codebuild-buildspec/plan.yml', 'utf8'))),
            roleName: props.projectOneIamRoleName
        })

        this.deploy = new codeBuildProject(this, 'two-project', {
            projectName: props.twoProjectName,
            description: 'some desc',
            buildspec: codebuild.BuildSpec.fromObject(yaml.parse(fs.readFileSync('codebuild-buildspec/apply.yml', 'utf8'))),
            roleName: props.projectTwoIamRoleName
        })

    };

}

Both the roleName are same as I want to share the use the same Iam Roles for both the code build projects.

Here is my constructor for the codebuild project

 constructor(scope: Construct, id: string, props: PipelineCodeBuildprops) {

        super(scope, id, props);

        this.project = new codebuild.PipelineProject(this, 'codebuild-project', {
            projectName: props.projectName,
            description: props.description, // a Bucket used as a source in CodePipeline must be versioned
            environment: {
                computeType: ComputeType.SMALL,
                buildImage: LinuxBuildImage.AMAZON_LINUX_2_4,
            },
            buildSpec: props.buildspec,
            role: new iam.Role(this, 'codebuild-iam-role', {
                roleName: props.roleName,
                assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com'),
                description: 'some desc'
            })
        });
    }

Upon deploying it throws an error in plan project that iam role already exists in deploy project stack


Solution

  • @Augunrik Answer is the motivation for this answer. I fixed my problem by

    Creating role as seperate stack and importing the role in each codebuild project

    role stack

    const manualRole = new IamRole(app, 'iam-role', {
      ServiceRoleName: getResourceName(app, 'role', 'role-name', env),
    })
    

    Importing role

    this.plan = new codeBuildProject(this, 'one-project', {
                projectName: props.oneProjectName,
                description: 'some desc',
                buildspec: codebuild.BuildSpec.fromObject(yaml.parse(fs.readFileSync('codebuild-buildspec/plan.yml', 'utf8'))),
                role: Role.fromRoleName(this, 'import', manualRole.codeBuildIamRole.role.roleName),
    
        })
    
        this.deploy = new codeBuildProject(this, 'two-project', {
            projectName: props.twoProjectName,
            description: 'some desc',
            buildspec: codebuild.BuildSpec.fromObject(yaml.parse(fs.readFileSync('codebuild-buildspec/apply.yml', 'utf8'))),
          role: Role.fromRoleName(this, 'import', manualRole.codeBuildIamRole.role.roleName),
    
        })