如何在 CloudFormation 模板中创建一些随机或唯一值?

lex*_*ore 7 aws-cloudformation

有没有办法在 CloudFormation 模板中创建某种随机或唯一值?

为什么我需要这个。在我们的模板中,我们有许多自定义命名的资源,例如AWS::AutoScaling::LaunchConfigurationwith specifiedLaunchConfigurationName或AWS::AutoScaling::AutoScalingGroupwith specified AutoScalingGroupName。
在更新堆栈时,我们经常会收到以下错误:

当自定义命名的资源需要替换时,CloudFormation 无法更新堆栈。重命名 some-stack-launch-configuration 并再次更新堆栈。

我们不想仅仅因为需要更新资源而重命名资源。
我们也不希望在我们的资源中删除自定义名称。然而,我们不介意在我们的自定义名称中有一些随机后缀。

使用“随机生成器”,解决方案可能类似于:

  MyAutoScalingGroup:
    Type: 'AWS::AutoScaling::AutoScalingGroup'
    Properties:
      AutoScalingGroupName: !Sub 'my-auto-scaling-group-${AWS::Random}'
Run Code Online (Sandbox Code Playgroud)

owl*_*lks 11

这类似于/sf/answers/4701343741/但更短:

Value: !Select [2, !Split ['/', !Ref AWS::StackId]]
Run Code Online (Sandbox Code Playgroud)


Ale*_*nko 6

在我看来,实现此类逻辑的最优雅的方法(如果您不想重命名资源)是使用 Cloudformation Macros。它们就像自定义资源,但您可以在模板转换期间隐式调用它们。因此,我将尝试提供一些示例,但您可以在AWS 文档中进行更多研究。

首先,您创建将发挥神奇作用的函数(具有所有必需的权限等)(如LiuChang提到的那样)。

然后,您应该从此函数创建一个宏:

Resources:
    Macro:
      Type: AWS::CloudFormation::Macro
      Properties:
        Name: <MacroName>
        Description: <Your description>
        FunctionName: <Function ARN>
Run Code Online (Sandbox Code Playgroud)

然后在资源定义中使用此宏:

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>
Run Code Online (Sandbox Code Playgroud)

此外,要使用宏,您应该在堆栈创建/更新期间指定CAPABILITY_AUTO_EXPAND功能。

就是这样。它应该可以工作,但当然这种方法的缺点之一 - 您应该维护额外的 lambda 函数。


Tul*_*nde 5

如果您只需要一个随机 ID(没有密码,没有特殊要求),我推荐的方法是使用AWS::StackId的一部分,格式如下:

arn:aws:cloudformation:us-west-2:123456789012:stack/teststack/51af3dc0-da77-11e4-872e-1234567db123
Run Code Online (Sandbox Code Playgroud)

因此,为了获得最后一部分,您需要进行两次拆分,例如:

      AutoScalingGroupName:
        Fn::Join:
          - '-'
          - - my-auto-scaling-group
            - Fn::Select:
                - 4
                - Fn::Split:
                    - '-'
                    - Fn::Select:
                        - 2
                        - Fn::Split:
                            - /
                            - Ref: AWS::StackId
Run Code Online (Sandbox Code Playgroud)

等效的较短语法:

AutoScalingGroupName: !Join ['-', ['my-auto-scaling-group', !Select [4, !Split ['-', !Select [2, !Split ['/', !Ref AWS::StackId]]]]]]
Run Code Online (Sandbox Code Playgroud)

意义:

  1. 开始AWS::StackId,例如:arn:aws:cloudformation:us-west-2:123456789012:stack/teststack/51af3dc0-da77-11e4-872e-1234567db123
  2. 拆分/并选择第二部分(0 索引):51af3dc0-da77-11e4-872e-1234567db123
  3. 拆分-并选择第 4 部分(0 索引):1234567db123
  4. 加入您的固定部分名称:my-auto-scaling-group-1234567db123。

优点:与创建 CustomResource 相比,我更喜欢这种方式,因为对于大型 AWS 环境和许多堆栈,您最终可能会使用多个 lambda,从而使治理变得更加困难。

缺点:它更冗长(Fn::Join、Fn::Select、 和Fn::Split)。

  • 这也是一个不错的选择,@Nipazz!请记住,仅按“/”进行拆分可能会打破某些 AWS 资源的名称长度限制。 (2认同)

小智 4

我认为您需要创建一个Lambda函数来执行此操作。

这是一个 GitHub 项目cloudformation-random-string,它有一个 Lambda 函数和一个简单的教程。

这是另一个教程在 AWS CloudFormation 模板中生成密码。

您可以参考上面的 Lambda 函数并让它为您工作。