是否可以在CloudFormation模板中创建某种随机或唯一值?
为什么我需要这个。在我们的模板中,我们有许多自定义名称的资源,例如具有指定AWS::AutoScaling::LaunchConfiguration
的{{1}}或具有指定LaunchConfigurationName
的{{1}}。
更新堆栈时,我们经常会遇到以下错误:
当需要替换自定义名称的资源时,CloudFormation无法更新堆栈。重命名some-stack-launch-configuration并再次更新堆栈。
我们不想因为需要更新资源而重命名资源。
我们也不想在资源中删除自定义名称。但是,我们不介意在自定义名称中添加一些随机后缀。
使用“随机数生成器”,解决方案可能类似于:
AWS::AutoScaling::AutoScalingGroup
答案 0 :(得分:3)
如果您只需要一个随机 ID(没有密码,没有特殊要求),我推荐的方法是使用 AWS::StackId 的一部分,格式如下:
arn:aws:cloudformation:us-west-2:123456789012:stack/teststack/51af3dc0-da77-11e4-872e-1234567db123
因此,为了获得最后一部分,您需要进行两次拆分,例如:
AutoScalingGroupName:
Fn::Join:
- '-'
- - my-auto-scaling-group
- Fn::Select:
- 4
- Fn::Split:
- '-'
- Fn::Select:
- 2
- Fn::Split:
- /
- Ref: AWS::StackId
含义:
AWS::StackId
开头,例如:arn:aws:cloudformation:us-west-2:123456789012:stack/teststack/51af3dc0-da77-11e4-872e-1234567db123
/
上拆分并选择第二部分(0 索引):51af3dc0-da77-11e4-872e-1234567db123
-
上拆分并选择第 4 部分(0 索引):1234567db123
my-auto-scaling-group-1234567db123
。优点:与创建 CustomResource 相比,我更喜欢这种方式,因为对于大型 AWS 环境和许多堆栈,您最终可能会使用多个 lambda,从而使治理变得更加困难。
缺点:比较冗长(Fn::Join
、Fn::Select
和 Fn::Split
)。
答案 1 :(得分:1)
我认为您需要创建一个Lambda
函数才能做到这一点。
这是一个GitHub项目cloudformation-random-string,具有Lambda函数和一个简单的教程。
这是另一个教程Generate Passwords in AWS CloudFormation Template。
您可以参考上面的Lambda函数,使其适合您。
答案 2 :(得分:0)
我正在使用AWS Java SDK运行一些堆栈更新命令。
我使用Java生成随机值,然后将其作为参数传递。
答案 3 :(得分:0)
我认为,实现这种逻辑的最优雅的方法(如果您不想重命名资源)是使用Cloudformation Macros。它们就像一个自定义资源,但是您可以在模板转换期间隐式调用它们。 因此,我将尝试提供一些示例,但是您可以在AWS Documentation中进行更多研究。
首先,您将创建具有魔术作用的函数(具有所有必需的权限等)(例如提到的 LiuChang 之类的东西)。
然后,您应该从此函数创建一个宏:
Resources:
Macro:
Type: AWS::CloudFormation::Macro
Properties:
Name: <MacroName>
Description: <Your description>
FunctionName: <Function ARN>
然后在您的资源定义中使用此宏:
MyAutoScalingGroup:
Type: 'AWS::AutoScaling::AutoScalingGroup'
Properties:
AutoScalingGroupName:
'Fn::Transform':
- Name: <MacroName>
Parameters:
InputString: <Input String>
...<Some other parameters like operation type or you can skip this>
此外,要使用宏,您应该在堆栈创建/更新期间指定 CAPABILITY_AUTO_EXPAND 功能。
就是这样。它应该可以工作,但是这种方法的缺点之一是-您应该维护附加的lambda函数。
答案 4 :(得分:0)
这类似于 https://stackoverflow.com/a/67162053/2660313 但更短:
Value: !Select [2, !Split ['/', !Ref AWS::StackId]]