两个GitHub仓库CDK部署AWS复用同一OIDC提供商URL的问题咨询
问题解答
这种配置完全可行,报错的原因是你当前的代码会在每个CDK栈中重复创建同一个URL的OIDC提供商,而AWS账户中同一个OIDC提供商URL只能存在一个,因此触发了重复创建的错误。
核心解决思路
在AWS账户中只创建一次GitHub OIDC提供商,然后在两个仓库对应的CDK栈中复用这个已存在的提供商,分别为每个仓库创建独立的IAM角色即可。
具体实现方案
1. 单独创建OIDC提供商栈
先新建一个专门用于部署OIDC提供商的栈,确保整个账户只创建一次该提供商:
import { GithubActionsIdentityProvider } from 'aws-cdk-github-oidc'; import * as cdk from 'aws-cdk-lib'; export class OidcProviderStack extends cdk.Stack { public readonly githubOidcProvider: GithubActionsIdentityProvider; constructor(scope: cdk.App, id: string, props: cdk.StackProps) { super(scope, id, props); // 仅创建一次GitHub OIDC提供商 this.githubOidcProvider = new GithubActionsIdentityProvider(this, 'GithubOidcProvider'); } }
2. 修改原栈代码,复用提供商
更新GITHUB_STACK_CONFIG接口,增加接收外部OIDC提供商的属性,同时移除栈内创建提供商的逻辑:
import { GithubActionsIdentityProvider, GithubActionsRole } from 'aws-cdk-github-oidc'; import * as cdk from 'aws-cdk-lib'; import * as iam from 'aws-cdk-lib/aws-iam'; export interface GITHUB_STACK_CONFIG { owner: string; repo: string; stage: string; policy?: iam.IManagedPolicy; githubOidcProvider: GithubActionsIdentityProvider; // 新增:接收外部提供商 } export class GithubStack extends cdk.Stack { constructor(scope: cdk.App, id: string, props: cdk.StackProps & GITHUB_STACK_CONFIG) { super(scope, id, props); const { owner, repo, stage, githubOidcProvider } = props; let { policy } = props; if (!policy) { policy = iam.ManagedPolicy.fromAwsManagedPolicyName('AdministratorAccess'); } // 使用传入的通用OIDC提供商,为当前仓库创建专属角色 const deployRole = new GithubActionsRole(this, `DeployRole-${repo}`, { provider: githubOidcProvider, owner, repo, filter: `ref:refs/heads/env/${stage}`, roleName: `IAC-${repo}-DeployRole`, // 确保角色名唯一,避免冲突 description: `部署角色:用于GitHub仓库 ${repo} 向本AWS账户推送部署`, maxSessionDuration: cdk.Duration.hours(2), }); deployRole.addManagedPolicy(policy); } }
3. 在应用入口中关联栈
在CDK应用的入口文件中,先初始化OIDC提供商栈,再将提供商传递给两个仓库对应的业务栈:
const app = new cdk.App(); // 初始化OIDC提供商栈(仅部署一次) const oidcProviderStack = new OidcProviderStack(app, 'OidcProviderStack', { env: { account: '你的AWS账户ID', region: '你的AWS区域' } }); // 第一个仓库的部署栈 new GithubStack(app, 'Repo1-DeployStack', { env: { account: '你的AWS账户ID', region: '你的AWS区域' }, owner: '你的GitHub用户名', repo: '仓库1名称', stage: 'prod', githubOidcProvider: oidcProviderStack.githubOidcProvider }); // 第二个仓库的部署栈 new GithubStack(app, 'Repo2-DeployStack', { env: { account: '你的AWS账户ID', region: '你的AWS区域' }, owner: '你的GitHub用户名', repo: '仓库2名称', stage: 'prod', githubOidcProvider: oidcProviderStack.githubOidcProvider }); app.synth();
替代方案(快速临时修复)
如果不想拆分栈,也可以通过ARN直接引用已存在的OIDC提供商(需要先手动部署一次创建提供商的栈,获取其ARN):
const provider = GithubActionsIdentityProvider.fromGithubActionsIdentityProviderArn( this, 'ExistingGithubProvider', 'arn:aws:iam::你的AWS账户ID:oidc-provider/token.actions.githubusercontent.com' );
这种方式需要硬编码ARN,灵活性较差,仅推荐临时使用。
内容的提问来源于stack exchange,提问作者Karim Chaari
相关产品推荐
相关产品推荐

