如何在CloudFormation脚本中获取当前日期?

chr*_*ris 10 amazon-web-services aws-cloudformation

我正在使用我的cfn脚本中的标签标记我的资源:

"Tags" : [ { "Key" : "Owner",       "Value" : "my name" },
           { "Key" : "Name",        "Value" : "instance name" } 
           { "Key" : "DateCreated", "Value" : <something goes here> } 
         ],
Run Code Online (Sandbox Code Playgroud)

我想根据上面的例子创建一个带有当前日期的标签.可能吗?

Gus*_*uss 8

您可以使用"自定义资源"生成时间戳(或任何其他值).

自定义资源是CloudFormation中的一项新功能(于2014年左右推出),允许您基本上调用lambda函数来"创建","更新"或"删除"CloudFormation不提供语言支持的资源(甚至可以是外部资源) AWS).

我经常使用自定义资源来计算一些值,以便在堆栈的其他部分使用,例如创建保存计算值的"变量"(例如使用!Join和类似的函数),我需要经常使用并且想要计算一次.

您可以轻松使用自定义资源来生成时间戳.下面是一些示例代码,它与我在生产中实际使用的代码非常接近:

创建"资源"实现

Resources:
  ValueFunc:
    Type: AWS::Lambda::Function
    Properties:
      Code:
        ZipFile: >
          var r = require('cfn-response');
          exports.handler = function(ev, ctx) {
            ev.ResourceProperties.Time = new Date().toISOString();
            r.send(ev, ctx, r.SUCCESS, ev.ResourceProperties);
          }; 
      Handler: index.handler
      Runtime: nodejs6.10
      Timeout: 30
      Role: !GetAtt ValueFunctionExecutionRole.Arn

  ValueFunctionExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal: { Service: [ lambda.amazonaws.com ] }
            Action: sts:AssumeRole
      Policies:
        - PolicyName: 
            Fn::Sub: "value-custom-res-${AWS::StackName}-${AWS::Region}"
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Effect: Allow
                Action:
                  - logs:CreateLogGroup
                  - logs:CreateLogStream
                  - logs:PutLogEvents
                Resource: "arn:aws:logs:*:*:*"
              - Effect: Allow
                Action: cloudformation:DescribeStacks
                Resource: "arn:aws:cloudformation:*:*:*"
Run Code Online (Sandbox Code Playgroud)

然后,无论您想在哪里生成时间戳,都可以执行以下操作(从此处获取计划操作示例):

创建计算其创建时间的自定义资源

GetTimeThisTime:
  Type: Custom::Value
  Properties:
    ServiceToken: !GetAtt ValueFunc.Arn
Run Code Online (Sandbox Code Playgroud)

使用该Time属性读取创建的时间戳

ScheduledActionUp: 
  Type: AWS::AutoScaling::ScheduledAction
  Properties:
    AutoScalingGroupName: !Ref WebServerGroup
    DesiredCapacity: 2
    StartTime: !GetAtt GetTimeThisTime.Time
    Recurrence: "0 7 * * *"
Run Code Online (Sandbox Code Playgroud)

您可以在创建堆栈的不同时间生成多个时间戳,只需创建一个新的"自定义值",该值取决于您想要创建其时间的逻辑实体.

  • 似乎这仅适用于初始堆栈创建,但不适用于后续堆栈更新 (3认同)

zor*_*lem 7

@Guy的建议是正确的,您可以从堆栈属性访问堆栈的创建时间戳.

如果您仍需要将标记指定为参数,则可以通过以下方式执行此操作.目前,JSON语法支持极其有限的一组函数.因此,动态修改模板的可能性非常小.我看到引入这个标签的唯一方法是向模板本身添加另一个参数.根据初始化堆栈的方式,您可以编写动态指定的参数脚本或在Web控制台中提供该参数.

例如,如果您在模板中有此内容:

  "Parameters" : {
    "CreationDate" : {
      "Description" : "Date",
      "Type" : "String",
      "Default" : "2013-03-20 21:15:00",
      "AllowedPattern" : "^\\d{4}(-\\d{2}){2} (\\d{2}:){2}\\d{2}$",
      "ConstraintDescription" : "Date and time of creation"
    }
  },
Run Code Online (Sandbox Code Playgroud)

您可以稍后使用标签中的Ref关键字引用它,如下所示:

 "Tags" : [ { "Key" : "Owner",       "Value" : "my name" },
            { "Key" : "Name",        "Value" : "instance name" },
            { "Key" : "DateCreated", "Value" : { "Ref" : "CreationDate" } } 
          ],
Run Code Online (Sandbox Code Playgroud)

如果从AWS控制台创建堆栈,则自动分配当前时间并非易事,但如果使用CLI工具,则可以像下面这样调用cfn-create-stack:

  cfn-create-stack MyStack --template-file My.template --parameters "CreationDate=$(date +'%F %T')"
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助!

  • 这不仅仅是实例 - 这种方法也适用于卷、AMI 以及您可以标记的任何其他内容 - 谢谢。 (2认同)