wal*_*ros 7 linux amazon-ec2 amazon-web-services aws-cloudformation
在Cloudformation中,我有两个堆栈(一个嵌套).
嵌套堆栈"ec2-setup":
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Parameters" : {
// (...) some parameters here
"userData" : {
"Description" : "user data to be passed to instance",
"Type" : "String",
"Default": ""
}
},
"Resources" : {
"EC2Instance" : {
"Type" : "AWS::EC2::Instance",
"Properties" : {
"UserData" : { "Ref" : "userData" },
// (...) some other properties here
}
}
},
// (...)
}
Run Code Online (Sandbox Code Playgroud)
现在在我的主模板中,我想引用上面给出的嵌套模板,并使用userData
参数传递一个bash脚本.另外,我不想内联用户数据脚本的内容,因为我想为少数ec2实例重用它(所以每次我在主模板中声明ec2实例时我都不想复制脚本).
我试图通过将脚本的内容设置为参数的默认值来实现此目的:
{
"AWSTemplateFormatVersion": "2010-09-09",
"Parameters" : {
"myUserData": {
"Type": "String",
"Default" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash \n",
"yum update -y \n",
"# Install the files and packages from the metadata\n",
"echo 'tralala' > /tmp/hahaha"
]]}}
}
},
(...)
"myEc2": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"TemplateURL": "s3://path/to/ec2-setup.json",
"TimeoutInMinutes": "10",
"Parameters": {
// (...)
"userData" : { "Ref" : "myUserData" }
}
Run Code Online (Sandbox Code Playgroud)
但是在尝试启动堆栈时出现以下错误:
"模板验证错误:模板格式错误:每个默认成员必须是一个字符串."
该错误似乎是由于声明{Fn :: Base64(...)}是一个对象 - 而不是一个字符串(尽管它导致返回base64编码的字符串).
一切正常,如果我在调用嵌套模板时将我的脚本直接粘贴到参数部分(作为内联脚本)(而不是将字符串设置为参数):
"myEc2": {
"Type": "AWS::CloudFormation::Stack",
"Properties": {
"TemplateURL": "s3://path/to/ec2-setup.json",
"TimeoutInMinutes": "10",
"Parameters": {
// (...)
"userData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash \n",
"yum update -y \n",
"# Install the files and packages from the metadata\n",
"echo 'tralala' > /tmp/hahaha"
]]}}
}
Run Code Online (Sandbox Code Playgroud)
但是我希望将userData
脚本的内容保存在参数/变量中以便能够重用它.
有没有机会重复使用这样的bash脚本而不需要每次都复制/粘贴它?
wjo*_*dan 11
以下是有关如何在用户数据中为通过CloudFormation定义的多个EC2实例重用bash脚本的一些选项:
您的原始尝试解决方案应该有效,只需稍作调整:您必须将默认参数声明为字符串,如下所示(使用YAML而不是JSON可以更容易/更容易地声明多行字符串内联):
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
myUserData:
Type: String
Default: |
#!/bin/bash
yum update -y
# Install the files and packages from the metadata
echo 'tralala' > /tmp/hahaha
(...)
Resources:
myEc2:
Type: AWS::CloudFormation::Stack
Properties
TemplateURL: "s3://path/to/ec2-setup.yml"
TimeoutInMinutes: 10
Parameters:
# (...)
userData: !Ref myUserData
Run Code Online (Sandbox Code Playgroud)
然后,在您的嵌套堆栈中,在EC2实例的资源属性中应用任何必需的内部函数(Fn::Base64
以及Fn::Sub
在您需要在用户数据脚本中应用任何函数Ref
或Fn::GetAtt
函数时非常有用):
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
# (...) some parameters here
userData:
Description: user data to be passed to instance
Type: String
Default: ""
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
UserData:
"Fn::Base64":
"Fn::Sub": !Ref userData
# (...) some other properties here
# (...)
Run Code Online (Sandbox Code Playgroud)
您可以将单个Bash脚本上载到S3存储桶,然后通过在模板中的每个EC2实例中添加最小用户数据脚本来调用脚本:
AWSTemplateFormatVersion: "2010-09-09"
Parameters:
# (...) some parameters here
ScriptBucket:
Description: S3 bucket containing user-data script
Type: String
ScriptKey:
Description: S3 object key containing user-data script
Type: String
Resources:
EC2Instance:
Type: AWS::EC2::Instance
Properties:
UserData:
"Fn::Base64":
"Fn::Sub": |
#!/bin/bash
aws s3 cp s3://${ScriptBucket}/${ScriptKey} - | bash -s
# (...) some other properties here
# (...)
Run Code Online (Sandbox Code Playgroud)
最后,您可以使用troposphere或您自己的模板预处理器工具从更紧凑/富有表现力的源文件中"生成"详细的CloudFormation可执行模板.这种方法将允许您消除源文件中的重复 - 尽管模板将包含"重复的"用户数据脚本,这只会出现在生成的模板中,因此不应该造成问题.
归档时间: |
|
查看次数: |
8527 次 |
最近记录: |