重构云形成模板中的重复参数吗?

时间:2019-01-20 00:00:57

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

我正在寻找一种方法来重构我的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数量?

2 个答案:

答案 0 :(得分:0)

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

要研究的另一种选择是cfndsl,这是一种特定于域的语言,它使诸如参数和模板之类的某些事情变得容易一些。

答案 1 :(得分:0)

您可以使用参数:

示例:

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

有关更多信息,请访问: