17

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

"Tags" : [ { "Key" : "Owner",       "Value" : "my name" },
           { "Key" : "Name",        "Value" : "instance name" } 
           { "Key" : "DateCreated", "Value" : <something goes here> } 
         ],

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

4

2 回答 2

14

您可以使用“自定义资源”来生成时间戳(或任何其他值)。

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

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

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

创建“资源”实现

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:*:*:*"

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

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

GetTimeThisTime:
  Type: Custom::Value
  Properties:
    ServiceToken: !GetAtt ValueFunc.Arn

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

ScheduledActionUp: 
  Type: AWS::AutoScaling::ScheduledAction
  Properties:
    AutoScalingGroupName: !Ref WebServerGroup
    DesiredCapacity: 2
    StartTime: !GetAtt GetTimeThisTime.Time
    Recurrence: "0 7 * * *"

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

于 2018-03-28T14:37:46.620 回答
12

@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"
    }
  },

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

 "Tags" : [ { "Key" : "Owner",       "Value" : "my name" },
            { "Key" : "Name",        "Value" : "instance name" },
            { "Key" : "DateCreated", "Value" : { "Ref" : "CreationDate" } } 
          ],

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

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

希望这可以帮助!

于 2013-03-26T23:57:30.217 回答