使VPC创建为可选

时间:2019-03-26 15:26:34

标签: amazon-web-services amazon-cloudformation amazon-vpc

我正在尝试以cloudformation脚本为条件创建VPC。例如,如果参数中提供了VPC ID,则我要在此VPC中创建所有资源,否则要创建一个新资源。

当我想重用现有的VPC时,问题就开始了,但是我无法推断出子网,这是我的一种资源。所以我想,我必须提供它们作为参数。但是,如果我将它们作为参数提供,则在要创建新的VPC的情况下,它会抱怨,因为子网ID列表为空,并且该列表必须是有效的。

错误是Parameter validation failed: parameter value for parameter name VpcPrivateSubnetIds does not exist. Rollback requested by user.无法给出任何虚拟值。任何想法如何实现这一目标?

这是我的CF脚本:

VpcId:
  Type: String
  Description: Give the VPC id if you want to use an existing one. Leave empty for creating a new one.

VpcPublicSubnetIds:
  Type: List<AWS::EC2::Subnet::Id>
  Description: List of 3 public SubnetIds for the given VPC. 

VpcPrivateSubnetIds:
  Type: List<AWS::EC2::Subnet::Id>
  Description: List of 3 private SubnetIds for the given VPC. 


Conditions:
  CreateVPC: !Equals [ !Ref VpcId, ""]


Resources: 
  (...)
    Properties:
      PrivateSubnetIds: !If
        - CreateVPC
        - !GetAtt VPCStack.Outputs.PrivateSubnets
        - !Join [',', [!Select [0, !Ref VpcPrivateSubnetIds], !Select [1, !Ref VpcPrivateSubnetIds], !Select [2, !Ref VpcPrivateSubnetIds]]]
      PublicSubnetIds: !If
        - CreateVPC
        - !GetAtt VPCStack.Outputs.PublicSubnets
        - !Join [',', [!Select [0, !Ref VpcPublicSubnetIds], !Select [1, !Ref VpcPublicSubnetIds], !Select [2, !Ref VpcPublicSubnetIds]]]

1 个答案:

答案 0 :(得分:0)

一种解决方案是将subnetId参数视为字符串,然后将其保留为空。 (但是,如果存在VPC,则用户必须手动输入子网ID列表)。

如果列表不为空(要使用现有的VPC),请使用Cloudformation custom resource lambda将字符串(用逗号分隔)转换为列表并返回cloudformation以用于资源创建。因此您的堆栈看起来就像

Parameters:
  VpcId:
    Type: String
    Description: Give the VPC id if you want to use an existing one. Leave empty for creating a new one.
  VpcPublicSubnetIds:
    Type: String
    Description: List of 3 public SubnetIds for the given VPC.
    Default: ''
  VpcPrivateSubnetIds:
    Type: String
    Description: List of 3 private SubnetIds for the given VPC.
    Default: ''
Conditions:
  CreateVPC: !Equals [ !Ref VpcId, ""]
  CreateList: !Not [!Equals [ !Ref VpcId, ""]]
Resources:
  CreateList:
    Type: AWS::CloudFormation::CustomResource
    Condition: CreateList
    Properties:
      ServiceToken:<some token>
      Public: !Ref VpcPublicSubnetIds
      Private: !Ref VpcPrivateSubnetIds
  SomeResource:
    Properties:
      PrivateSubnetIds: !If
        - CreateVPC
        - !GetAtt VPCStack.Outputs.PrivateSubnets
        - !GetAtt CreateList.PrivateSubnetIds
      PublicSubnetIds: !If
        - CreateVPC
        - !GetAtt VPCStack.Outputs.PublicSubnets
        - !GetAtt CreateList.PublicSubnetIds

请注意,我已经验证了此脚本,因此您可能需要进行一些更正。