AWS CDK-来自其他堆栈的访问资源

问题描述

假设我在一个堆栈中有一个资源,例如stepfunction活动。我如何在其他堆栈中访问它的arn?

我发现CfnConstruct适合导出(https://docs.aws.amazon.com/cdk/api/latest/docs/@aws-cdk_core.CfnOutput.html)。到目前为止,我已经使用CfnConstruct导出它了:

this.initiateValidationActivityArn = new cdk.CfnOutput(this,'InitiateValidationActivityArn',{
      value: igvsstateMachine.initiateValidationActivity.activityArn
    });

现在如何在其他文件中访问它。我已经尝试过了:

ecsService.initiateValidationActivityArn.value

但是值是私有的,因此无法使用。

解决方法

如果您将堆栈放在一个可部署的cdk-app 中,则可以通过从外部/非私有位置访问它来访问堆栈中的属性值。 我建议做的是保留它readonly,以使它不能从堆栈外部重新初始化。

// file: ./lib/first-stack.ts

// import statements

export class FirstStack extends Stack {
  readonly vpc: IVpc;
  
  constructor(...) {
     // setup
     this.vpc = new Vpc(this,"VPC",{...});
  }
}

在依赖堆栈中,您可以通过(自定义)道具传递它。

// file: ./lib/second-stack.ts

export interface SecondStackProps extends StackProps {
   importedVpc: IVpc;
}

export class SecondStack extends Stack {
  constructor(scope: cdk.Construct,id: string,props: SecondStackProps) {
    super(scope,id,props);
    const importedVpc = props.importedVpc;

    // do sth. with your imported resource
  }
}

为什么您可能会问... 之所以可以使用CDK,是因为CDK生成了资源ID,并且在合成阶段可以将资源的令牌放入所生成的模板中。

当您将cdk-apps /堆栈部署分开时,这不起作用,因为CDK无法在cdk-synth期间解析(现有的)资源ID令牌。 这样,您需要采用另一种方法:

// file: ./lib/first-stack-separated-deployment.ts

// import statements

export class FirstStackSeparatedDeployment extends Stack {
  cfnVpcId: CfnOutput;
  
  constructor(...) {
     // setup
     const vpc = new Vpc(this,{...});
     this.cfnVpcId= new cdk.CfnOutput(this,"FirstStackCfnVpcId",{
      value: vpc.vpcId,exportName: "UniqueNameForYourVpcId"
    });
  }
}

在另一个需要已部署资源的堆栈中,请执行以下操作:

// file: ./lib/second-stack-separated-deployment.ts
export class SecondStackSeparatedDeployment extends Stack {
  constructor(...) {
    // setup
    const vpcId = Fn.importValue("UniqueNameForYourVpcId")
    const importedVpc = ec2.Vpc.fromVpcAttributes(this,"ImportedVpc",{
      vpcId: vpcId,availabilityZones: [this.region],})

    // proceed further...
  }
}

基本上,您从exportName构造中获取CfnOutput作为标识符,并通过核心Fn.importValue进行导入。 通过这种方法,已经需要部署第一个堆栈。