【问题标题】:Reusing AWS::CloudFormation::Init (and userdata?) for multiple instances为多个实例重用 AWS::CloudFormation::Init(和 userdata?)
【发布时间】:2015-02-14 11:05:04
【问题描述】:

是否可以为模板中的多个EC2::Instances 重用来自AWS::CloudFormation::Init(和/或userdata)的相同引导配置?

我需要设置 3 个文件的内容,然后运行 ​​3 个命令来引导所有服务器,但 Metadata 块大约有 30 行长(并且可能会增长)。 每个服务器实例都有一组不同的标签,有些标签比其他的多。

理想情况下,我认为您应该能够将AWS::CloudFormation::Init 声明为资源,并从多个EC2::Instances 中引用它,但我认为这是不可能的。

我最初(作为新手)认为AWS::CloudFormation::CustomResource 可能是合适的,但我不认为它是合适的。

我目前正在考虑使用AWS::CloudFormation::Stack 导入共享实例模板,但我需要以某种方式将堆栈模板中每个资源的Tags 参数传递到实例模板中。问题是 - 如果这是最好的方法,我应该在当前有 ???? 的 3 个位置输入什么?

(奖励积分 - userdata 和这个 init 块有什么区别?)

stack.template

...
"Resources" : {
  "Server1" : {
    "Type": "AWS::CloudFormation::Stack",
    "Properties": {
      "Parameters": {
        "InstanceType": "m1.medium",
        ...
        "Tags": { ???? }
      },
      "TemplateURL": "https://s3.amazonaws.com/mybucket/instance.template"
    }

instance.template

...
"Parameters" : {
   "InstanceType" : {...}
   "KeyName": {...}
   ...
   "Tags": {
       ????
   }
},

"Resources" : {
    "Instance" : {
      "Type" : "AWS::EC2::Instance",
      "Metadata" : {
        "AWS::CloudFormation::Init" : {
          "config" : {
            "files" : {
              "/etc/apt/apt.conf.d/99auth" : {
                "content" : "APT::Get::AllowUnauthenticated yes;"
              },
              "/etc/apt/sources.list.d/my-repo.list" : {
                "content" : "deb  http://my-repo/repo apt/"
              },
          },
            "commands" : {
              "01-apt-get update" : {
                "command" : "apt-get update"
              },
              "02-apt-get install puppet" : {
                "command" : "apt-get install puppet my-puppet-config"
              },
              "03-puppet apply" : {
                "command" : "puppet apply"
              }
            }
          }
        }
      },
      "Properties" : {
        "InstanceType" : {"Ref" : "InstanceType"},
        "ImageId" : "ami-84a333be",
        "KeyName" : {"Ref" : "KeyName"},
        "SubnetId" : {"Ref" : "SubnetId"},
        "SecurityGroupIds" : [ { "Ref" : "SecurityGroupId"] } ],
        "Tags" : [
          ????
        ]
      }
    }
}

【问题讨论】:

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


    【解决方案1】:

    是否可以重用相同的引导配置 AWS::CloudFormation::Init(和/或用户数据)用于多个 模板中的 EC2::Instances?

    不,这对于单个模板中的 AWS::EC2::Instance 资源是不可能的。但是,有一种资源类型AWS::AutoScaling::LaunchConfiguration,但今天此资源仅适用于 Auto Scaling 组。理想情况下,AWS 将提供可应用于多个 AWS::EC2::Instance 资源的类似资源类型。话虽这么说,有很多value in using Auto Scaling groups

    这是一个简单的示例,可让您在单个模板中使用单个启动配置和多个 Auto Scaling 组资源来执行此操作。 Auto Scaling 通常配置有多个实例,但我使用 1 的 MinSize 和 MaxSize 来反映您使用 AWS::EC2::Instance 资源类型进行的配置。即使我们使用带有 Auto Scaling 组的单个实例,我们仍然可以从具有单实例弹性的 Auto Scaling 中获益。如果实例变得不健康,Auto Scaling 将自动替换该实例。

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Resources" : {
        "LaunchConfig" : {
          "Type" : "AWS::AutoScaling::LaunchConfiguration",
          "Properties" : {
            "InstanceType" : { "Ref" : "InstanceType" },
            "ImageId" : "ami-84a333be",
            "KeyName" : { "Ref" : "KeyName" },
            "SecurityGroupIds" : [{"Ref" : "SecurityGroupId"}],
            "UserData" : { "Fn::Base64" : { "Fn::Join" : [ "", [
              "#!/bin/bash -v\n",
    
              "# Run cfn-init\n",
              "/opt/aws/bin/cfn-init -v ",
              "    -stack ", { "Ref": "AWS::StackName" },
              "    -resource LaunchConfig ",
              "    --region ", { "Ref" : "AWS::Region" }, "\n",
    
              "# Signal success\n",
              "/opt/aws/bin/cfn-signal -e $? '", { "Ref" : "WaitConditionHandle" }, "'\n"
            ]]}}
          },
          "Metadata" : {
            "AWS::CloudFormation::Init" : {
              "config" : {
                "files" : {
                  "/etc/apt/apt.conf.d/99auth" : {
                    "content" : "APT::Get::AllowUnauthenticated yes;"
                  },
                  "/etc/apt/sources.list.d/my-repo.list" : {
                    "content" : "deb  http://my-repo/repo apt/"
                  }
                },
                "commands" : {
                  "01-apt-get update" : {
                    "command" : "apt-get update"
                  },
                  "02-apt-get install puppet" : {
                    "command" : "apt-get install puppet my-puppet-config"
                  },
                  "03-puppet apply" : {
                    "command" : "puppet apply"
                  }
                }
              }
            }
          }
        },   
        "ASG1" : {
          "Type" : "AWS::AutoScaling::AutoScalingGroup",
          "Properties" : {
            "AvailabilityZones" : [ { "Ref" : "AZ" } ],
            "VPCZoneIdentifier" : [ { "Ref" : "SubnetId" } ],
            "LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
            "MaxSize" : "1",
            "MinSize" : "1",
            "Tags" : [
              { "Key" : "Name", "Value": "Server1", "PropagateAtLaunch" : "true" },
              { "Key" : "Version", "Value": "1.0", "PropagateAtLaunch" : "true" }
            ]
          }
        },
        "ASG2" : {
          "Type" : "AWS::AutoScaling::AutoScalingGroup",
          "Properties" : {
            "AvailabilityZones" : [ { "Ref" : "AZ" } ],
            "VPCZoneIdentifier" : [ { "Ref" : "SubnetId" } ],
            "LaunchConfigurationName" : { "Ref" : "LaunchConfig" },
            "MaxSize" : "1",
            "MinSize" : "1",
            "Tags" : [
              { "Key" : "Name", "Value": "Server2", "PropagateAtLaunch" : "true" },
              { "Key" : "Version", "Value": "1.0", "PropagateAtLaunch" : "true" }
            ]
          }
        },
        "WaitConditionHandle" : {
          "Type" : "AWS::CloudFormation::WaitConditionHandle"
        },
        "WaitCondition" : {
          "Type" : "AWS::CloudFormation::WaitCondition",
          "Properties" : {
            "Handle" : { "Ref" : "WaitConditionHandle" },
            "Timeout" : "300"
          }
        }
      }
    }
    

    这是一个不完整的示例,您可以使用 Auto Scaling 做更多事情,但我只是想为您提供一个与多个实例共享启动配置的简单示例。每个 Auto Scaling 组都定义了自己的一组标签。


    我目前正在考虑使用 AWS::CloudFormation::Stack 来导入 共享实例模板,但我需要以某种方式传递标签 堆栈模板中的每个资源的参数到实例中 模板。问题是 - 如果这是最好的方法,我该怎么做 输入当前有 ?????的 3 个位置

    我会推荐我上面描述的解决方案,但我也想回答您关于如何将标签与嵌套堆栈方法一起使用的问题。

    stack.template

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Resources" : {
        "Server1" : {
          "Type": "AWS::CloudFormation::Stack",
          "Properties": {
            "TemplateURL": "https://s3.amazonaws.com/mybucket/instance.template",
            "Parameters": {
              "InstanceType": "m1.medium",
              "TagName": "Server1"
              "TagVersion": "1.0"
            }
          }
        },
        "Server2" : {
          "Type": "AWS::CloudFormation::Stack",
          "Properties": {
            "TemplateURL": "https://s3.amazonaws.com/mybucket/instance.template",
            "Parameters": {
              "InstanceType": "m1.medium",
              "TagName": "Server2"
              "TagVersion": "1.0"
            }
          }
        }
      }
    }
    

    instance.template

    {
      "AWSTemplateFormatVersion": "2010-09-09",
      "Parameters" : {
         "InstanceType" : {...},
         "KeyName": {...}
         "TagName": {
           "Description" : "The name tag to be applied to each instance",
           "Type" : "String"
         },
         "TagVersion": {
           "Description" : "The version tag to be applied to each instance",
           "Type" : "String"
         }
      },
    
      "Resources" : {
        "Instance" : {
          "Type" : "AWS::EC2::Instance",
          "Metadata" : {
            "AWS::CloudFormation::Init" : {
              ...
            }
          },
          "Properties" : {
            "InstanceType" : { "Ref" : "InstanceType" },
            "ImageId" : "ami-84a333be",
            "KeyName" : { "Ref" : "KeyName" },
            "SubnetId" : { "Ref" : "SubnetId" },
            "SecurityGroupIds" : [ { "Ref" : "SecurityGroupId"] } ],
            "Tags" : [
              { "Key" : "Name", "Value": { "Ref" : "TagName" } },
              { "Key" : "Version", "Value": { "Ref" : "TagVersion" } },
            ]
          }
        }
      }
    }
    

    没有将整个标签数组作为参数传递的标准,因此您可以看到我只是将每个标签分解为自己的参数并将它们传递到嵌套堆栈。


    (奖励积分 - userdata 和这个 init 有什么区别 阻止?)

    UserData 允许您在第一次启动时将任意数据传递给实例。通常这是一个 shell 脚本,可以在实例启动时自动执行任务。例如,您可以简单地运行 yum update。

    "UserData" : { "Fn::Base64" : { "Fn::Join" : [ "", [
      "#!/bin/bash\n"
      "yum update -y", "\n"
    ]]}}
    

    当与允许您构建引导配置的AWS::CloudFormation::Init 元数据结合使用时,UserData 变得更加有用。在这种情况下,UserData 仅用于调用执行 AWS::CloudFormation::Init 元数据的 cfn-init 脚本。我在上面的第一个示例中使用了启动配置包含了这种模式。需要注意的是,UserData 部分仅在实例的第一次引导期间执行一次。在考虑如何处理实例更新时,请牢记这一点。

    【讨论】:

    • 回答这个问题时“AWS::Include”不存在吗?因为它似乎至少可以解决其中的一些问题。
    猜你喜欢
    • 2021-12-26
    • 2019-06-27
    • 1970-01-01
    • 2017-07-27
    • 2012-01-14
    • 2017-07-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多