Resolution error: Cannot use resource 'x' in a cross-environment fashion, the resource's physical name must be explicit set

Resolution error: Cannot use resource 'x' in a cross-environment fashion, the resource's physical name must be explicit set

我正在尝试将 ecs 集群从一个堆栈传递到另一个堆栈。

我收到这个错误: Error: Resolution error: Resolution error: Resolution error: Cannot use resource 'BackendAPIStack/BackendAPICluster' in a cross-environment fashion, the resource's physical name must be explicit set or use `PhysicalName.GENERATE_IF_NEEDED`.

集群在BackendAPIStack中定义如下:

this.cluster = new ecs.Cluster(this, 'BackendAPICluster', {
   vpc: this.vpc
});

堆栈定义如下:

 const backendAPIStack = new BackendAPIStack(app, `BackendAPIStack${settingsForThisEnv.stackVersion}`, {
    env: {
      account: process.env.CDK_DEFAULT_ACCOUNT,
      region: process.env.CDK_DEFAULT_REGION
    },
    digicallPolicyQueue: digicallPolicyQueue,
    environmentName,
    ...settingsForThisEnv
  });

  const metabaseStack = new MetabaseStack(app, 'MetabaseStack', backendAPIStack.vpc, backendAPIStack.cluster, {
    vpc: backendAPIStack.vpc,
    cluster: backendAPIStack.cluster
  });

  metabaseStack.addDependency(backendAPIStack);

这是 metabaseStack 的构造函数:

constructor(scope: cdk.Construct, id: string, vpc: ec2.Vpc, cluster: ecs.Cluster, props: MetabaseStackProps) {
        super(scope, id, props);

        console.log('cluster', cluster)

        this.vpc = vpc;
        this.cluster = cluster;

        this.setupMetabase()
    }

然后我在这里使用集群:

      const metabaseService = new ecs_patterns.ApplicationLoadBalancedFargateService(this, 'Metabase', {
            assignPublicIp: false,
            cluster: this.cluster,
...

我找不到关于如何做我想做的事情的文档。

您正在使用 BackendAPIStack 创建 Region/Account-specific Stack,因为您通过 env 属性值将堆栈绑定到特定帐户和区域。

然后你通过创建没有任何 env 属性值的 MetabaseStack 来创建一个 Region/Account- 不可知的 堆栈。

一般来说,有两个像这样的 independent 堆栈很好,但在这里你通过将引用从 BackendAPIStack 传递到 MetabaseStack,这是行不通的。

This is a problem because CDK normally links Stacks together by performing Stack Exports and Imports of values, but CloudFormation does not support cross-region or cross-account Stack references

因此,您可能的解决方案是:

  • (A) 将您的 MetabaseStack 设置为使用与 BackendAPIStack 相同的 account/region
    • 在底层,这会将集群的 ARN 设置为从 BackendAPICluster 导出的堆栈,然后 MetabaseStack 将能够导入它。
  • (B1) 使用您选择的 clusterName 创建 BackendAPICluster
    • new Cluster(..., {vpc: this.vpc, clusterName: 'backendCluster' })
    • 如果不提供名称,您将使用默认值 “CloudFormation 生成的名称”,这是 CDK 报告的问题的基础,尽管它在令人困惑的方式。
    • 当您提供名称时,集群的 ARN 是确定性的(不是由 CloudFormation 在部署时选择的)因此 CDK 在构建时有足够的信息来确定集群的 ARN 是什么,并且可以提供到你的 MetabaseStack.
  • (B2) 使用 clusterNamelet CDK pick 创建 BackendAPICluster
    • 这是通过将 clusterName 设置为 PhysicalName.GENERATE_IF_NEEDED 来完成的
      • new Cluster(..., {clusterName: PhysicalName.GENERATE_IF_NEEDED })
    • PhysicalName.GENERATE_IF_NEEDED是一个标记,表示物理(名称)只有在交叉需要时才会由CDK生成环境参考。否则,它将由 CloudFormation 分配。
    • 这就是错误所在告诉你,但我也没看懂...

如果可能的话,我会选择(A)。我怀疑这只是一个疏忽,您没有将相同的 env 值传递给 MetabaseStack 并且您可能希望同一区域中的这两个堆栈减少延迟等等。

如果没有,那么我个人会选择 (B2) 接下来,因为我尽量不给我的任何资源提供明确的名称,除非它们是与另一组签订的合同的一部分。 IE。 在帐户 XYZ 中担任名为 'ServiceWorker' 的角色或 从 Bucket 'ABC'.

下载数据