【发布时间】:2020-11-13 17:14:14
【问题描述】:
我正在探索 CDK 应用程序的可重构性。假设我定义了一个自定义构造(堆栈)来创建一个 EKS 集群。我们称之为EksStack。理想情况下,我将创建与集群和 EKS 集群本身关联的角色,如下面的 sn-p 所述(我使用的是 Scala 而不是 Java,因此 sn-ps 将采用 Scala 语法):
class EksStack (scope: Construct, id: String, props: StackProps) extends Stack(scope, id, props) {
private val role = new Role(this, "eks-role", RoleProps.builder()
.description(...)
.managedPolicies(...)
.assumedBy(...)
.build()
)
private val cluster = new Cluster(this, "eks-cluster", ClusterProps.builder()
.version(...)
.role(role)
.defaultCapacityType(DefaultCapacityType.EC2)
.build()
)
}
当我合成应用程序时,我可以看到生成的模板包含 VPC 的定义,以及弹性 IP、NAT、Internet 网关等。
现在假设我想重构 EksStack 并使用不同的堆栈,比如 VpcStack,显式创建 VPC:
class VpcStack (scope: Construct, id: String, props: StackProps) extends Stack(scope, id, props) {
val vpc = new Vpc(this, VpcId, VpcProps.builder()
.cidr(...)
.enableDnsSupport(true)
.enableDnsHostnames(true)
.maxAzs(...)
.build()
)
}
理想情况下,EksStack 中的集群将只使用对 VpcStack 创建的 VPC 的引用,类似于(注意集群构建器中对 vpc() 的新调用):
class EksStack (scope: Construct, id: String, props: StackProps, vpc: IVpc) extends Stack(scope, id, props) {
private val role = new Role(this, "eks-role", RoleProps.builder()
.description(...)
.managedPolicies(...)
.assumedBy(...)
.build()
)
private val cluster = new Cluster(this, "eks-cluster", ClusterProps.builder()
.version(...)
.role(role)
.vpc(vpc)
.defaultCapacityType(DefaultCapacityType.EC2)
.build()
)
}
这显然行不通,因为 CloudFormation 会删除 EksStack 创建的 VPC,转而使用 VpcStack 创建的 VPC。我在这里和那里阅读并尝试在EksStack 中添加保留策略,并使用我最初在EksStack 的CloudFormation 模板中看到的ID 覆盖VpcStack 中VPC 的逻辑ID:
val cfnVpc = cluster.getVpc.getNode.getDefaultChild.asInstanceOf[CfnVPC]
cfnVpc.applyRemovalPolicy(RemovalPolicy.RETAIN)
和
val cfnVpc = vpc.getNode.getDefaultChild.asInstanceOf[CfnVPC]
cfnVpc.overrideLogicalId("LogicalID")
然后重试diff。再次,似乎 VPC 被删除并重新创建。
现在,我看到可以使用“将资源导入堆栈”操作迁移 CloudFormation 资源 (https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/refactor-stacks.html)。我的问题是:我可以在 CDK 中将资源的创建从堆栈移动到另一个堆栈而不重新创建它吗?
编辑:
为了详细说明我的问题,当我在 VpcStack 中定义 VPC 时,我希望 CDK 认为资源是由 VpcStack 创建的,而不是 EksStack。类似于将其定义从一个堆栈移动到另一个堆栈,而无需 CloudFormation 删除原始堆栈以重新创建它。在我的用例中,我将有一个堆栈定义一个最初的创建(显式或隐式,例如我的 VPC),但是在一段时间之后,我可能想要重构我的应用程序,将该资源的创建移动到专用堆栈。我试图了解这种移动是否总是导致资源被重新创建,如果有任何方法可以避免它。
【问题讨论】:
标签: amazon-web-services amazon-cloudformation aws-cdk infrastructure-as-code