将AZ映射到选定的子网,将子网映射到选定的VPC

时间:2017-02-15 13:26:31

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

我正在创建一个创建一些资源(如EC2实例)的云形态模板。此模板将用于不同的AWS账户。 我们有3个帐户,一个用于测试环境,一个用于开发环境,一个用于生产。在每个帐户中有2个VPC(所有帐户中的区域相同)。

我的问题是,为了正确构建资源,在创建EC2时,我们需要选择VPC,同一VPC内的子网和同一子网的可用区。我需要可用区,因为我将EFS安装在实例的userData中,以便实例可以连接到安装目标。

众所周知,每个子网中都有一个目标数量,而dns会根据AZ进行更改。以下是我在userData中放置目标的内容:

echo "availability-zone.file-system-id.efs.aws-region.amazonaws.com:/ /efs-mount-point nfs4 nfsvers=4.1 0 0" >> /etc/fstab

我不是直接创建实例,而是通过创建启动配置和自动缩放组来实现。

"Launchconfig":{
        "Type":"AWS::AutoScaling::LaunchConfiguration",
        "Properties":{
          "ImageId":{ "Fn::FindInMap":[ "AWSRegionToAMI", { "Ref":"AWS::Region" }, "AMIID" ] },
          "SecurityGroups":[ { "Ref":"EcsSecurityGroup" } ],
          "InstanceType": {"Ref":"InstanceType" },
          "IamInstanceProfile":{ "Ref":"EC2InstanceProfile" },
          "KeyName":{ "Fn::FindInMap" : [ "KeyPairMapping", {"Ref" : "EnvParam"}, "Key"] },
          "UserData":{  "Fn::Base64" : {
            "Fn::Join" : ["", [
              "#!/bin/bash -xe\n",
              "echo eu-west-1c.",{ "Fn::FindInMap" : [ "FileSystemMap", {"Ref" : "EnvParam"}, "FileSystemID"] },
              ".efs.",{ "Ref" : "AWS::Region" },".amazonaws.com:/ /efs-mount-target nfs defaults,vers=4.1 0 0",
              " >> /etc/fstab\n"
              ]]}
          }
        }
      },

      "AutoScalingGroup":{
        "Type":"AWS::AutoScaling::AutoScalingGroup",
        "Properties":{
          "VPCZoneIdentifier":{ "Ref":"SubnetID" },
          "LaunchConfigurationName":{ "Ref":"Launchconfig" },
          "MinSize":"1",
          "MaxSize":{ "Ref":"MaxSize" },
          "DesiredCapacity":{ "Ref":"DesiredCapacity" }
        }
      },

我的问题:通过使用映射,如何根据所选子网获取userdata中可用区的值?

2 个答案:

答案 0 :(得分:1)

这可以通过两种方式完成,具体取决于您的使用案例:

  1. VPCZoneIdentifier资源的AutoScalingGroup属性接受子网标识符字符串列表。或者,AvailabilityZones属性接受可用区域字符串列表。如果您只为Auto Scaling组指定单个可用区/子网,则可以确保该实例将在指定的可用区内启动。

  2. 如果您的Auto Scaling组可以在多个可用区中启动实例,您可以Retrieve Instance Metadata确定实例的当前可用区,例如,通过在用户数据中运行以下命令实例上的脚本:

    AZ=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone)
    echo "$AZ.${FileSystemId}.efs.${AWS::Region}.amazonaws.com:/ /efs-mount-point nfs4 nfsvers=4.1 0 0" >> /etc/fstab
    

答案 1 :(得分:0)

我不认为您可以在创建堆栈期间直接访问用户数据。但是你可以参数化这个值并在你需要的两个地方引用参数吗?