如何从CloudFormation中的父模板“导出”子网和VPCId

时间:2019-08-04 18:00:34

标签: amazon-web-services amazon-cloudformation

我正在使用AWS CloudFormation。我有3个模板:一个用于EKS(Kubernetes集群)“父模板”,两个用于组节点的子模板。我正在父模板中创建VPC,子网,安全组,并且需要在每个子模板中使用它们。

我不能使用嵌套堆栈,因为我不需要新的EKS实例。如果我使用Output.export.name,我会得到:

  

“导出”的“名称”字段不得依赖于任何资源,导入的值或Fn :: GetAZ。

这是父级(EKS)模板的简化版本:

Resources:
  InternetGateway:
    Type: "AWS::EC2::InternetGateway"
  KubeRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: Kubernetes-Role
      AssumeRolePolicyDocument: {
        "Version": "2012-10-17",
        "Statement": [
          {
            "Effect": "Allow",
            "Principal": {
              "Service": "eks.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
          }
        ]
      }
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEKSClusterPolicy
        - arn:aws:iam::aws:policy/AmazonEKSServicePolicy

  VPC:
    Type: AWS::EC2::VPC
    Properties:
      CidrBlock:  !Ref VpcBlock
      EnableDnsSupport: true
      EnableDnsHostnames: true

  Subnet01:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: us-east-2a
      CidrBlock: !Ref Subnet01Block
      VpcId: !Ref VPC

  Subnet02:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: us-east-2b
      CidrBlock: !Ref Subnet02Block
      VpcId: !Ref VPC

  Subnet03:
    Type: AWS::EC2::Subnet
    Properties:
      AvailabilityZone: us-east-2c
      CidrBlock: !Ref Subnet03Block
      VpcId: !Ref VPC

  VPCGatewayAttachment:
    Type: AWS::EC2::VPCGatewayAttachment
    Properties:
      InternetGatewayId: !Ref InternetGateway
      VpcId: !Ref VPC

  RouteTable:
    Type: AWS::EC2::RouteTable
    Properties:
      VpcId: !Ref VPC

  Route:
    DependsOn: VPCGatewayAttachment
    Type: AWS::EC2::Route
    Properties:
      RouteTableId: !Ref RouteTable
      DestinationCidrBlock: 0.0.0.0/0
      GatewayId: !Ref InternetGateway

  Subnet01RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref Subnet01
      RouteTableId: !Ref RouteTable

  Subnet02RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref Subnet02
      RouteTableId: !Ref RouteTable

  Subnet03RouteTableAssociation:
    Type: AWS::EC2::SubnetRouteTableAssociation
    Properties:
      SubnetId: !Ref Subnet03
      RouteTableId: !Ref RouteTable

  ControlPlaneSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Cluster communication with worker nodes
      VpcId: !Ref VPC

  KubeCluster:
    Type: AWS::EKS::Cluster
    Properties:
      Name: !Ref ClusterName
      ResourcesVpcConfig:
        SecurityGroupIds:
          - !GetAtt ControlPlaneSecurityGroup.GroupId
        SubnetIds: 
          - !Ref Subnet01
          - !Ref Subnet02
          - !Ref Subnet03
      RoleArn: !GetAtt KubeRole.Arn

Outputs:
  KubeName:
    Description: Kubernetes Cluster name just created
    Value: KubeName
    Export:
      Name: !Ref KubeCluster

  SubnetIds1:
    Description: Subnet01 in the VPC
    Value: SubnetIds1
    Export:
      Name: !Ref Subnet01

  SubnetIds2:
    Description: Subnet02 in the VPC
    Value: SubnetIds2
    Export:
      Name: !Ref Subnet02

  SubnetIds3:
    Description: Subnet03 in the VPC
    Value: SubnetIds3
    Export:
      Name: !Ref Subnet03

  SecurityGroups:
    Description: Security group for the cluster control plane communication with worker nodes
    Value: SecurityGroups
    Export:
      Name: !Ref ControlPlaneSecurityGroup

  VpcId:
    Description: The VPC Id
    Value: VpcId
    Export:
      Name: !Ref VPC

是否有解决此问题的方法?我不想“输出”值,然后依靠一个人来复制它们,然后将其粘贴为子模板的参数。我们有很多子网,VPC和安全组,因此选择错误值的机会非常高。

1 个答案:

答案 0 :(得分:1)

在CloudFormation "Outputs section structure"文档中,它说:

  

对于输出,导出的Name属性的值不能使用依赖于资源的Ref或GetAtt函数。

您可以做的是:

  

您可以使用内部函数来自定义导出的Name值。

如示例中所示:

Export:
  Name: !Join [ ":", [ !Ref "AWS::StackName", AccountVPC ] ]

现在,在您的template中,我认为您正在将名称传递到Value的{​​{1}}键中,并在Outputs属性中引用了资源。反转这两个应该可以解决您当前的问题。

希望对您有帮助。