繁体   English   中英

AWS CDK Python - 在堆栈之间传递多个变量

[英]AWS CDK Python - Passing multiple variables between Stacks

背景

我的 CDK 应用程序中有两个堆栈。 一种是定义网络结构(例如 VPC、安全组等)的 Stack,一种是负责创建 EKS 集群的 Stack。 作为集群配置过程的一部分,EKS 集群需要能够使用网络堆栈中的变量和 output。 以下示例:

网络栈:

class NetworkingStack(Stack):
   def __init__(self, scope: Construct, id: str, MyCidr,**kwargs) -> None:
       super().__init__(scope, id)

       subnet_count = range(1,3)
       public_subnets = []
       worker_subnets = []
       control_subnets = []

       for x in subnet_count:
           x = str(x)
           control_subnets.append(ec2.SubnetConfiguration(
               name = 'Control-0{}'.format(x),
               cidr_mask=28,
               subnet_type = ec2.SubnetType.PRIVATE_WITH_NAT,
               reserved = False
           ))
           worker_subnets.append(ec2.SubnetConfiguration(
               name = 'Worker-0{}'.format(x),
               cidr_mask=24,
               subnet_type = ec2.SubnetType.PRIVATE_WITH_NAT,
               reserved = False
           ))
           public_subnets.append(ec2.SubnetConfiguration(
               name = 'Public-0{}'.format(x),
               cidr_mask=27,
               map_public_ip_on_launch=True,
               subnet_type = ec2.SubnetType.PUBLIC,
               reserved = False
           ))

       kubernetes_vpc = ec2.Vpc(self, 
       "Kubernetes", 
       cidr=MyCidr,
       default_instance_tenancy=ec2.DefaultInstanceTenancy.DEFAULT,
       enable_dns_hostnames=True,
       enable_dns_support=True,
       flow_logs=None,
       gateway_endpoints=None,
       max_azs=2,
       nat_gateway_provider=ec2.NatProvider.gateway(),
       nat_gateways=1, # this is 1 PER AZ
       subnet_configuration=[*public_subnets,*control_subnets,*worker_subnets],
       vpc_name="Kubernetes",
       vpn_connections=None
       )
       

       controlplane_security_group = ec2.SecurityGroup(self, "ControlPlaneSecurityGroup", vpc=kubernetes_vpc)
       workerplane_security_group = ec2.SecurityGroup(self, "WorkerPlaneSecurityGroup", vpc=kubernetes_vpc) 
       public_security_group = ec2.SecurityGroup(self, "PublicPlaneSecurityGroup", vpc=kubernetes_vpc)

现在,Cluster Stack 需要使用这里创建的几个变量。 具体来说,它需要能够访问kubernetes_vpcpublic/control/worker subnetspublic/control/workerplane security groups

在同一个区域,同一个账户,同一个 CDK environment我有另一个 Stack,Cluster Stack:

集群堆栈:

        cluster = eks.Cluster(
            self,
            "InfrastructureCluster",
            default_capacity_type=eks.DefaultCapacityType.NODEGROUP,
            alb_controller=eks.AlbControllerOptions(version="latest"),
            endpoint_access=eks.EndpointAccess.PUBLIC_AND_PRIVATE,
            version=eks.KubernetesVersion.V1_21,
            cluster_name="InfrastructureCluster",
            security_group=MyNetworkStack.controlplane_security_group,
            vpc=MyNetworkStack.kubernetes_vpc,
            vpc_subnets=ec2.SubnetSelection(
                subnets=[*MyNetworkStack.control_subnets, *MyNetworkStack.worker_subnets, *MyNetworkStack.public_subnets],
            )
        )

官方文档使用了在 Stacks 之间共享存储桶的示例,以便从 StackB 访问 StackA 存储桶。 他们通过在堆栈之间传递 object 来做到这一点。 这意味着我需要为要在堆栈之间传递的每个变量创建一个参数。 有没有更简单的方法?

我尝试将实际的 NetworkingStack 传递给 ClusterStack,如下所示:

class ClusterStack(Stack):
    def __init__(self, scope: Construct, id: str, MyNetworkStack, **kwargs) -> None:
        super().__init__(scope, id, **kwargs)

然后在 app.py 中:

NetworkingStack(app, "NetworkingStack", MyCidr="10.40.0.0/16")
ClusterStack(app, "ClusterStack", MyNetworkStack=NetworkingStack)

但是当我将 NetworkingStack 中的变量引用为属性时,这似乎不起作用,例如security_group=MyNetworkStack.controlplane_security_group 我得到的错误通常与这个变量有关,特别是AttributeError: type object 'NetworkingStack' has no attribute 'controlplane_security_group'

问题:

在堆栈之间传递多个变量的最佳方法是什么,而不必将每个变量定义为参数?

步骤1

将要引用的任何变量更改为 NetworkStack class 的属性。

所以,而不是:

controlplane_security_group = ec2.SecurityGroup(self, "ControlPlaneSecurityGroup", vpc=kubernetes_vpc)

你应该做:

self.controlplane_security_group = ec2.SecurityGroup(self, "ControlPlaneSecurityGroup", vpc=kubernetes_vpc)

第2步

您需要通过 object,而不是通过 class。

所以,而不是:

NetworkingStack(app, "NetworkingStack", MyCidr="10.40.0.0/16")
ClusterStack(app, "ClusterStack", MyNetworkStack=NetworkingStack)

你应该做:

networking_stack = NetworkingStack(app, "NetworkingStack", MyCidr="10.40.0.0/16")
ClusterStack(app, "ClusterStack", MyNetworkStack=networking_stack)

现在MyNetworkStack.controlplane_security_group可以正常工作了。

我还建议进行另一项更改,即将名称MyNetworkStack更改为my_network_stack因为这是根据PEP8方法参数名称的一般 Python 约定。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM