来自自定义资源的云形成功能

时间:2018-07-03 06:57:13

标签: amazon-web-services amazon-cloudformation

我有一个CF模板,其中提供了一个参数,并进行条件检查以确定如何构造存储桶名称。如果是prod,则应为“名称”。如果不是prod,则应为“ name_environment”,如下所示:

# # # # # # # # # # # # # # # #
#                             #
#  Input Parameters           #
#  Prefix: t3st-acc0un7-123   #
#   Stage: dev                #
#                             #
#  Expected S3 Name Output    #
#  t3st-acc0un7-123-dev       #
#  t3st-acc0un7-123-dev-2     #
#                             #
# # # # # # # # # # # # # # # #
#                             #
#  Input Parameters           #
#  Prefix: t3st-acc0un7-123   #
#   Stage: prod               #
#                             #
#  Expected S3 Name Output    #
#  t3st-acc0un7-123           #
#  t3st-acc0un7-123-2         #
#                             #
# # # # # # # # # # # # # # # #

这是我的模板,用于执行此操作:

Parameters:
  Prefix:
    Type: String
    Default: t3st-acc0un7-123
  Stage:
    Type: String
    AllowedPattern: "([a-z]|[0-9])+"

Conditions:
  IsProdStage:
    Fn::Equals:
    - !Ref Stage
    - prod

Resources:
  TestBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: 
          Fn::If:
          - IsProdStage
          - !Ref Prefix
          - !Join
            - '-'
            - 
              - !Ref Prefix
              - !Ref Stage

  TestBucket2:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: 
        Fn::If:
        - IsProdStage
        - !Join
          - '-'
          -
            - !Ref Prefix
            - '2'
        - !Join
          - '-'
          - 
            - !Ref Prefix
            - !Ref Stage
            - '2'

在第一个示例模板中,条件和联接逻辑被复制。我基本上想将条件的值存储在某个位置,以从每个后续函数中调用,而不是复制逻辑。

在下一个示例中,我尝试使用自定义资源来调用虚拟lambda(因为需要 ServiceToken ),所以我可以在上设置 Value 属性> TestCustomResource 基于条件和输入的自定义资源,并从我创建的其他资源中读取。

Parameters:
  Prefix:
    Type: String
    Default: t3st-acc0un7-123
  Stage:
    Type: String
    AllowedPattern: "([a-z]|[0-9])+"

Conditions:
  IsProdStage:
    Fn::Equals:
    - !Ref Stage
    - prod

Resources:
  TestBucket:
      Type: AWS::S3::Bucket
      Properties:
        BucketName: !GetAtt TestCustomResource.Value

  TestBucket2:
    Type: AWS::S3::Bucket
    Properties:
      BucketName: !Join
        - '-'
        -
          - !GetAtt TestCustomResource.Value
          - 2

  TestCustomResource:
    Type: Custom::Codswallop
    Properties:
      ServiceToken: !GetAtt DummyLambda.Arn
      Value:
        Fn::If:
        - IsProdStage
        - !Ref Prefix
        - !Join
          - '-'
          - 
            - !Ref Prefix
            - !Ref Stage

  DummyLambda:
    Type: "AWS::Lambda::Function"
    Properties:
      Code: 
        ZipFile: >
          print("")
      Handler: lambda_function.lambda_handler
      Role: !GetAtt DummyRole.Arn
      Runtime: python3.6

  DummyRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
            - Effect: Allow
              Principal:
                Service:
                  - lambda.amazonaws.com
              Action:
                - sts:AssumeRole
      RoleName: DummyRole

我知道虚拟lambda有点小巧,但这似乎是非常有用的功能,能够存储在模板周围使用的计算值。第二个示例给出了这样的错误:TestCustomResource-自定义资源未能在预期的时间内稳定下来。

(答案可能是使用多个模板,这些模板取决于以前的CF输出值或嵌套模板。)

1 个答案:

答案 0 :(得分:1)

请勿将自定义资源用于伪造目的。

该操作完成后,该函数需要“回调”到CloudFormation。您的自定义资源没有代码,因此它将永远不会回调,因此您的模板将永远不会完成。

如果您的第一个示例可行,请坚持下去。您的第二种选择(除了不工作之外)对于将来的IT人员来说很难理解和维护。

始终可以通过优雅的技巧轻松地进行将来的维护。 (由不得不维护他人优雅技巧的人说出来。)