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

时间:2019-08-26 15:15:13

标签: amazon-cloudformation

是否可以在CloudFormation模板中创建某种随机或唯一值?

为什么我需要这个。在我们的模板中,我们有许多自定义名称的资源,例如具有指定AWS::AutoScaling::LaunchConfiguration的{​​{1}}或具有指定LaunchConfigurationName的{​​{1}}。
更新堆栈时,我们经常会遇到以下错误:

  

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

我们不想因为需要更新资源而重命名资源。
我们也不想在资源中删除自定义名称。但是,我们不介意在自定义名称中添加一些随机后缀。

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

AWS::AutoScaling::AutoScalingGroup

5 个答案:

答案 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

含义:

  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::JoinFn::SelectFn::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]]