AWS CloudFormation: 如何从VPC获取子网列表?

9

在CloudFormation中,我正在创建一个VPC、两个EC2实例和一个Elasticache。在模板中,我试图将Elasticache添加到VPC中。问题出现在创建AWS::Elasticache::SubnetGroup时。

    "CacheSubnetGroup" : {
      "Type" : "AWS::ElastiCache::SubnetGroup",
      "Properties" : {
        "Description" : "Subnets available for the ElastiCache Cluster",
        "SubnetIds" : [ ... ]
      }
    },

我不想像这里建议的那样要求用户输入子网列表,因为我假设用户不知道什么是子网。是否有类似于{ "Fn::GetAtt" : ["myVpc", "SubnetList"] }的函数?

编辑 在jarmod的回复后,我正在创建子网、VPC和其他所有内容。但还存在一个问题。我可以在创建的VPC中启动EC2实例,但实例在初始化过程中停止运行并重新生成新实例。这个循环会一直持续,直到我删除cf堆栈。以下是我认为问题产生的部分:

"WebServerGroup" : {
  "Type" : "AWS::AutoScaling::AutoScalingGroup",
  "Properties" : {
    "VPCZoneIdentifier" : [{ "Ref" : "InstanceSubnet1" }, { "Ref" : "InstanceSubnet2" }, { "Ref" : "InstanceSubnet3" }, { "Ref" : "InstanceSubnet4" }],
    "LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
    "MinSize" : "1",
    "MaxSize" : "4",
    ...
  }
}

如果您检查堆栈事件,实例创建会打印出什么错误? - Efren
2个回答

11

处理这种情况有三种典型方式(按我偏好的顺序):

  1. 如果子网仅由此堆栈使用,请将其作为堆栈的一部分创建并使用ref。

  2. 如果子网将被多个堆栈使用,请在单独的堆栈中创建它们,将它们定义为输出,对定义堆栈执行describe-stack以获取值,然后将它们作为参数传递给此堆栈。

  3. 如果子网是在CloudFormation之外创建的,则只需将其作为参数传递。

如果您真的想使用VPC中的所有子网,虽然我不建议这样做,以防将来为其他目的创建新的子网,则始终可以执行describe-subnets并在VpcId上进行过滤以获取列表。


谢谢回复。是的,这是新手错误,我以为在创建VPC时会创建默认子网,但事实并非如此。但是出现了一个新问题,我已经更新了我的帖子来解释它。 - James Robert Albert
@bsvingen 在CloudFormation参数部分如何描述子网并过滤VpcId? - Rupesh Patil

2
如果您的模板创建了VPC,则可能也为该VPC创建了子网。您不能只是从您创建的每个子网的单独子网ID中填充SubnetIds吗?
类似这样:
"SubnetIds" : [ {"Ref":"mysubnet1"}, {"Ref":"mysubnet2"} ]

好的,这很有道理。我仍然是个新手,以为在创建VPC时会默认创建子网。所以我已经创建了我的子网,除了我的AutoScalingGroup之外,一切都正常工作。我的EC2在VPC中被创建,但它们启动并在初始化过程中停止,所有新的EC2实例都会被创建。这种情况会持续下去,直到我删除CF堆栈。我不确定为什么会发生这种情况,任何帮助都将不胜感激。我更新了帖子,其中包含我认为问题起源的部分。 - James Robert Albert
自动扩展组旨在用新的、健康的实例替换不健康的实例。我会认为您的实例看起来不健康,无论它们是否真的不健康,因此它们未能通过健康检查并被自动扩展组终止和替换。您需要了解实例状态检查是否失败,或者是 ELB 健康检查失败(假设您使用 ELB)。更多信息请参见 http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/as-maintain-instance-levels.html。 - jarmod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接