You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决AWS CDK部署EKS集群时的资源循环依赖问题?

问题描述

我基于K8s搭建自动代码流水线,选用CodePipeline和AWS CDK。初始化CDK项目并编写代码后,CodePipeline已正常生成,结构为Source -> Build -> UpdatePipeLine -> Assets -> EksDeploymentStage。前几步执行正常,但进入EksDeploymentStage时出现循环依赖错误:

Circular dependency between resources: [My Resources list~~~~~~~~~~~~] (Service: AmazonCloudFormation; Status Code: 400; Error Code: ValidationError; Request ID: ~~~~~~~~~~-3ffc3b280a8a; Proxy: null)

请问代码哪里出问题了?

相关代码

/bin/my-project-k8s-cdk.ts

import 'source-map-support/register';
import * as cdk from 'aws-cdk-lib';
import {DeploymentStack} from "../lib/kubeflow-helm-deployment-stack";

const app = new cdk.App();
new DeploymentStack(app, "DeploymentStack", {
  env: { account: '~~~~~~~~', region: 'ap-northeast-2' },
});

app.synth();

/lib/kubeflow-helm-deployment-stack.ts

export class DeploymentStack extends Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const pipeline = new CodePipeline(this, "EksDeploymentPipeline", {
      pipelineName: "EksDeploymentPipeline",
      synth: new CodeBuildStep("Synth", {
        input: CodePipelineSource.connection(GithubConfig.GITHUB_REPO, "main", {
          connectionArn: GithubConfig.GITHUB_CODESTAR_CONNECTION_ARN
        }),
        commands: [
          "npm install",
          "npm run build",
          "npx cdk synth"
        ],
        rolePolicyStatements: [
          new PolicyStatement({
            actions: ['sts:AssumeRole'],
            resources: ['*'],
            conditions: {
              StringEquals: {
                'iam:ResourceTag/aws-cdk:bootstrap-role': 'lookup',
              },
            },
          }),
        ],
      }),
    });

    const eksDeploymentStage = new EksDeploymentStage(this, "EksDeploymentStage", {
      env: { account: this.account, region: this.region }
    });

    pipeline.addStage(eksDeploymentStage);
  }
}

/lib/kubeflow-helm-eks-deployment-stage.ts

export class EksDeploymentStage extends Stage {

  constructor(scope: Construct, id: string, props?: StageProps) {
    super(scope, id, props);

    new MyEksStack(this, 'MyEksStack')
  }
}

/lib/my-eks-stack.ts

export class MyEksStack extends cdk.Stack {
  constructor(scope: Construct, id: string, props?: cdk.StackProps) {
    super(scope, id, props);

    const accountId = this.account;
    const clusterName = 'MyKubeFlowCluster';
    const kubernetesVersion = KubernetesVersion.V1_21;
    const albControllerVersion = AlbControllerVersion.V2_4_1;

    const kubernetesApiAccessPolicy = new PolicyStatement({
      actions: [
        'eks:DescribeCluster',
        'eks:AccessKubernetesApi',
        'cloudformation:DescribeStacks',
      ],
      resources: [
        `arn:aws:eks:*:${accountId}:cluster/*`,
      ]
    });

    const eksClusterMasterRole = new Role(this, "EksClusterMasterRole", {
      assumedBy: new AccountPrincipal(accountId),
      roleName: "EksClusterMasterRole",
      inlinePolicies: {
        "KubernetesApiAccess": new PolicyDocument({
          statements: [kubernetesApiAccessPolicy]
        })
      }
    });

    const kubeflowVpc = new Vpc(this, "KubeflowVpc", {
      vpcName: "KubeflowVpc",
      ipAddresses: IpAddresses.cidr("10.1.0.0/16"),
      maxAzs: 2,
      natGateways: 1,
      subnetConfiguration: [
        {
          name: "PrivateSubnet",
          subnetType: SubnetType.PRIVATE_WITH_EGRESS,
        },
        {
          name: "PublicSubnet",
          subnetType: SubnetType.PUBLIC
        }
      ]
    });

    const cluster = new Cluster(this, "KubeflowCluster", {
      clusterName: clusterName,
      version: kubernetesVersion,
      vpc: kubeflowVpc,
      defaultCapacity: 1,
      defaultCapacityInstance: new InstanceType("t2.small"),
      mastersRole: eksClusterMasterRole,
      albController: {
        version: albControllerVersion
      },
      outputClusterName: true
    });

    kubeflowVpc.publicSubnets.forEach(subnet => {
      Tags.of(subnet).add(`kubernetes.io/cluster/${cluster.clusterName}`, "owned")
    });

    kubeflowVpc.privateSubnets.forEach(subnet => {
      Tags.of(subnet).add(`kubernetes.io/cluster/${cluster.clusterName}`, "owned")
    });
  }
}

内容的提问来源于stack exchange,提问作者Jun

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:25:16