有没有办法为从 CloudFormation 模板参数派生的常用值定义快捷方式?
例如 - 我有一个脚本,它创建一个多可用区项目堆栈,其中 ELB 名称project
和 ELB 后面的两个实例称为project-1
and project-2
。我只将ELBHostName
参数传递给模板,然后用它来构造:
"Fn::Join": [
".", [
{ "Fn::Join": [ "", [ { "Ref": "ELBHostName" }, "-1" ] ] },
{ "Ref": "EnvironmentVersioned" },
{ "Ref": "HostedZone" }
]
]
这种构造或非常相似的构造在整个模板中重复多次 - 以创建 EC2 主机名、Route53 记录等。
我不想一遍又一遍地重复,我想将它的输出分配Fn::Join
给某种变量,并且只引用它,就像我可以使用"Ref":
语句一样。
理想情况下是这样的:
Var::HostNameFull = "Fn::Join": [ ... ]
...
{ "Name": { "Ref": "Var::HostNameFull" } }
或类似简单的东西。
Amazon CloudFormation 可以做到吗?
我没有答案,但确实想指出,您可以通过使用
Fn::Sub
代替Fn::Join
替换
不,我试过了,但结果是空的。对我来说有意义的方法是创建一个名为“CustomVariables”的映射条目,并让该条目容纳我的所有变量。它适用于简单的字符串,但不能在 Mappings 中使用 Intrinsics(Refs、Fn::Joins 等)。
作品:
不会工作:
这只是一个例子。您不会将独立的 Ref 放入变量中。
我正在寻找相同的功能。想到使用 SpoonMeiser 建议的嵌套堆栈,但后来我意识到我真正需要的是自定义函数。幸运的是,CloudFormation 允许使用AWS::CloudFormation::CustomResource,只需做一些工作,就可以做到这一点。对于变量来说,这感觉有点矫枉过正(我认为一开始就应该在 CloudFormation 中),但它完成了工作,此外,还允许所有的灵活性(选择 python/node /java)。应该注意的是,lambda 函数需要花钱,但我们在这里谈论的是便士,除非您每小时创建/删除多次堆栈。
第一步是在这个页面上创建一个 lambda 函数,它除了获取输入值并将其复制到输出之外什么都不做。我们可以让 lambda 函数做各种疯狂的事情,但是一旦我们有了恒等函数,其他任何事情都变得容易了。或者,我们可以在堆栈本身中创建 lambda 函数。由于我在 1 个帐户中使用了许多堆栈,因此我将拥有一大堆剩余的 lambda 函数和角色(并且所有堆栈都需要使用 创建
--capabilities=CAPABILITY_IAM
,因为它也需要一个角色。创建 lambda 函数
index.handler
然后将下面的代码复制粘贴到代码字段中。函数的顶部是来自cfn-response python 模块的代码,它只有在通过 CloudFormation 创建 lambda 函数时才会自动安装,原因很奇怪。该
handler
功能非常不言自明。您现在可以通过选择“测试”按钮来测试 lambda 函数,并选择“CloudFormation 创建请求”作为示例模板。您应该在日志中看到返回给它的变量。
在 CloudFormation 模板中使用变量
现在我们有了这个 lambda 函数,我们可以在 CloudFormation 模板中使用它。首先记下 lambda 函数 Arn(进入lambda 主页,点击刚刚创建的函数,Arn 应该在右上角,类似于
arn:aws:lambda:region:12345:function:CloudFormationIdentity
)。现在在您的模板中,在资源部分中,指定您的变量,例如:
首先,我指定一个
Identity
包含 lambda 函数的 Arn 的变量。把它放在一个变量中,意味着我只需要指定一次。我将所有变量都设为 typeCustom::Variable
。Custom::
CloudFormation 允许您使用以自定义资源开头的任何类型名称。请注意,该
Identity
变量包含两次 lambda 函数的 Arn。一次指定要使用的 lambda 函数。第二次作为变量的值。现在我有了
Identity
变量,我可以使用定义新变量ServiceToken: !GetAtt [Identity, Arn]
(我认为 JSON 代码应该类似于"ServiceToken": {"Fn::GetAtt": ["Identity", "Arn"]}
)。我创建了 2 个新变量,每个变量都有 2 个字段:名称和 Arn。在模板的其余部分中,我可以使用!GetAtt [ClientBucketVar, Name]
或!GetAtt [ClientBucketVar, Arn]
在需要时使用。警告
使用自定义资源时,如果 lambda 函数崩溃,您会被卡住 1 到 2 小时,因为 CloudFormation 在放弃之前会等待(崩溃)函数的回复一个小时。因此,在开发 lambda 函数时为堆栈指定一个较短的超时时间可能会很好。
您可以使用嵌套堆栈来解析其输出中的所有变量,然后用于
Fn::GetAtt
从该堆栈读取输出使用另一个堆栈作为嵌套堆栈并传入计算的参数示例:
您可以使用嵌套模板,在其中“解析”外部模板中的所有变量并将它们传递给另一个模板。