CDK中如何让两个不同CodeBuild项目共享同一IAM角色?
解决方案
问题根源在于你每个codeBuildProject实例都在内部创建了一个同名IAM角色,即使角色名称相同,CDK会将它们视为两个独立的资源(因为它们属于不同的子构造),部署时AWS会拒绝创建重复名称的IAM角色。
解决步骤如下:
1. 调整codeBuildProject的Props和构造逻辑
修改PipelineCodeBuildprops接口,允许传入已有的IAM角色对象,同时保留创建新角色的选项:
interface PipelineCodeBuildprops { projectName: string; description: string; buildspec: codebuild.BuildSpec; role?: iam.Role; // 新增:支持传入已创建的角色 roleName?: string; // 保留:未传入角色时,用此名称创建新角色 }
更新构造函数,优先使用传入的角色,否则再创建新角色:
constructor(scope: Construct, id: string, props: PipelineCodeBuildprops) { super(scope, id, props); let buildRole: iam.Role; if (props.role) { buildRole = props.role; } else { if (!props.roleName) { throw new Error('Either role or roleName must be provided'); } buildRole = new iam.Role(this, 'codebuild-iam-role', { roleName: props.roleName, assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com'), description: 'some desc' }); } this.project = new codebuild.PipelineProject(this, 'codebuild-project', { projectName: props.projectName, description: props.description, environment: { computeType: ComputeType.SMALL, buildImage: LinuxBuildImage.AMAZON_LINUX_2_4, }, buildSpec: props.buildspec, role: buildRole }); }
2. 在父Stack中创建共享IAM角色并传递给两个项目
修改CodeBuildProjects类,先创建一次共享角色,再将其传递给两个CodeBuild项目:
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); // 创建一次共享的IAM角色 const sharedCodeBuildRole = new iam.Role(this, 'shared-codebuild-role', { roleName: props.sharedRoleName, assumedBy: new iam.ServicePrincipal('codebuild.amazonaws.com'), description: 'Shared role for CodeBuild plan and deploy projects' }); // 传递共享角色给plan项目 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: sharedCodeBuildRole }); // 传递同一个共享角色给deploy项目 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: sharedCodeBuildRole }); }; }
3. 更新Stack实例化代码
调整传入的Props,使用统一的共享角色名称参数:
const codeBuildProject = new CodeBuildProjects(this, 'pipelineCodeBuildProjects', { oneProjectName: 'one-project', twoProjectName: 'second-project', sharedRoleName: 'iam-role' });
这样整个Stack中只会创建一个名为iam-role的IAM角色,两个CodeBuild项目共用该角色,避免了重复创建的冲突。
内容的提问来源于stack exchange,提问作者Jatin Mehrotra
相关产品推荐
相关产品推荐

