【问题标题】:Refactor repeated parameters in cloud formation template?重构云形成模板中的重复参数?
【发布时间】:2019-06-13 19:22:55
【问题描述】:

我正在寻找一种方法来重构我的 Cloud Formation 模板中的重复值导入。

我有以下配置一个简单应用程序的模板:

Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access into the server
    Type: AWS::EC2::KeyPair::KeyName
  S3StackName:
    Description: Name of S3 Stack
    Type: String

Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Metadata:
      AWS::CloudFormation::Init:
        config:
          packages:
            yum:
              httpd: []
              php: []
          files:
            /var/www/html/index.html:
              source:
                Fn::Sub:
                  - https://s3.amazonaws.com/${bucketName}/index.html
                  - bucketName:
                      Fn::ImportValue:
                        !Sub "${S3StackName}-s3Bucket"
            /var/www/html/styles.css:
              source:
                Fn::Sub:
                  - https://s3.amazonaws.com/${bucketName}/styles.css
                  - bucketName:
                      Fn::ImportValue:
                        !Sub "${S3StackName}-s3Bucket"
            /var/www/html/script.js:
              source:
                Fn::Sub:
                  - https://s3.amazonaws.com/${bucketName}/script.js
                  - bucketName:
                      Fn::ImportValue:
                        !Sub "${S3StackName}-s3Bucket"
          services:
            sysvinit:
              httpd:
                enabled: true
                ensureRunning: true
      AWS::CloudFormation::Authentication:
        S3AccessCreds:
          type: S3
          roleName: !Ref EC2InstanceRole
          buckets:
            -
              Fn::ImportValue:
                  !Sub "${S3StackName}-s3Bucket"
    Properties:
      IamInstanceProfile: !Ref EC2InstanceProfile
      InstanceType: t2.micro
      ImageId: ami-1853ac65
      SecurityGroupIds:
        - !Ref MySecurityGroup
      KeyName: !Ref KeyName
      UserData:
        'Fn::Base64':
          !Sub |
            #!/bin/bash -xe
            # Ensure AWS CFN Bootstrap is the latest
            yum install -y aws-cfn-bootstrap
            # Install the files and packages from the metadata
            /opt/aws/bin/cfn-init -v --stack ${AWS::StackName} --resource EC2Instance  --region ${AWS::Region}

  MySecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Open Ports 22 and 80
      SecurityGroupIngress:
      - IpProtocol: tcp
        FromPort: '22'
        ToPort: '22'
        CidrIp: 0.0.0.0/0
      - IpProtocol: tcp
        FromPort: '80'
        ToPort: '80'
        CidrIp: 0.0.0.0/0

Outputs:
  Website:
    Description: The Public DNS for the EC2 Instance
    Value: !Sub 'http://${EC2Instance.PublicDnsName}'

你会注意到有很多重复,特别是导入一个已经从现有堆栈中导出的值,例如:

Fn::Sub:
  - https://s3.amazonaws.com/${bucketName}/index.html
  - bucketName:
      Fn::ImportValue:
        !Sub "${S3StackName}-s3Bucket"

这个模式在我上面发布的模板中总共使用了 4 次。我想简化这一点,我不会一遍又一遍地重复相同的 YAML 块。

我的第一个想法是向模板的元数据部分添加一个值,但这不起作用,因为资源部分不能从元数据部分!Ref

如何减少此模板中重复 YAML 的数量?

【问题讨论】:

    标签: amazon-web-services yaml amazon-cloudformation


    【解决方案1】:

    您应该能够使用 CloudFormation 宏来实现这一点。 This blog post 很好地概述了宏。你可以定义一个宏来调用一个简单的 lambda 函数并转换模板,这样你就可以用宏做很多有趣的事情。这里有一些examples on GitHub

    另一个需要调查的选项是cfndsl,这是一种特定领域的语言,它使参数和模板等一些事情变得更容易一些。

    【讨论】:

      【解决方案2】:

      你可以使用参数:

      例子:

      Parameters:
        FunctionRepeat:
          Fn::Sub:
            - https://s3.amazonaws.com/${bucketName}/index.html
            - bucketName:
                Fn::ImportValue:
                  !Sub "${S3StackName}-s3Bucket"
      

      然后你可以在任何你喜欢的地方重复使用这个块。

      例子:

      files:
        /var/www/html/index.html:
          source:
            Ref: FunctionRepeat
        /var/www/html/styles.css:
          source:
            Ref: FunctionRepeat
        /var/www/html/script.js:
          source:
            Ref: FunctionRepeat
      

      欲了解更多信息,您可以访问:

      【讨论】:

      • 不使用参数意味着用户在运行堆栈时可以覆盖该值吗?我认为参数将用于输入变量。
      • 必须在运行时为每个参数分配一个值,AWS CloudFormation 才能成功预置堆栈。您可以选择指定要使用的 AWS CloudFormation 的默认值,除非提供了其他值。我建议你通过这个:docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/…
      • 当我尝试这个时,我收到以下错误:调用 ValidateTemplate 操作时发生错误 (ValidationError):无效的模板参数属性 'Fn::Sub'
      • 这是参数部分的无效语法,另外根据文档,您不能在参数部分中使用内部函数。
      猜你喜欢
      • 2019-11-13
      • 1970-01-01
      • 2011-10-21
      • 2012-11-06
      • 2014-05-27
      • 1970-01-01
      • 2014-09-15
      • 2020-04-14
      • 2019-08-01
      相关资源
      最近更新 更多