skip to Main Content

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

2

Answers


  1. Chosen as BEST ANSWER

    @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),
    
        })
    

  2. The role is created twice and needs to be shared between them. This can simply done by caching the role.

    Example:

    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);
    
            //
            var role = // CREATE ROLE HERE
    
            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
            })
    
            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
            })
    
        };
    
    }
    

    If you really want to share a role between two stacks then this can also be done. One stack create the role, the other one imports it again via:

    var role = iam.fromRoleArn(this, id, roleArn)
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search