使用Cloud Formation在AWS EC2实例中创建文件的最佳实践

3

有很多选项可以做到这一点,我不知道哪个是最好的。一开始我尝试按照以下方式操作:

ServiceInstance:
Type: "AWS::EC2::Instance"
Properties:
  ImageId: !Ref AmiId, !Ref LatestOnescoutAmi ]
  InstanceType: !Ref InstanceType
  SubnetId: !ImportValue vpc-stack-PublicASubnet
  SecurityGroupIds:
    - !Ref ServiceSecurityGroup
  KeyName: !Ref KeyName
  UserData:
    'Fn::Base64': !Sub |
      #cloud-config
      write_files:
        - path: /etc/sysconfig/cloudformation
          permissions: 0644
          owner: root
          content: |
            STACK_NAME=${AWS::StackName}
            AWS_REGION=${AWS::Region}
        - path: /etc/datadog-agent/conf.d/mysql.d/conf.yaml
          permissions: 0644
          owner: dd-agent
          content: |
            init_config:
            instances:
            - server: some-db-host
              user: some-admin
              pass: some-password
              port: 3306
              tags:
              - dbinstanceidentifier:someide

      runcmd:
        ## enable datadog agent
        - systemctl start datadog-agent
        - systemctl start application.service

但是我的 /etc/datadog-agent/conf.d/mysql.d/conf.yaml 文件变得越来越大,现在大约有13个块,把它们硬编码到模板中不好。最好保持模板的通用性,并将配置文件作为参数传递。 但是根据这个 答案, 不可能将文件或文件内容传递给CloudFormation。
上述方法是我能想到的三种选项中最简单的一种。
  1. Store the config in SSM and then get it back at the ec2 start.

  2. Create an Autoscaling and launch group which accepts the file path but it's more complex than I need:

    LaunchConfig:
        Type: AWS::AutoScaling::LaunchConfiguration
        Metadata:
          AWS::CloudFormation::Init:
            configSets:
              service_configuration:
              - datadog_setup
            datadog_setup:
              files:
                /etc/datadog-agent/conf.d/mysql.d/conf.yaml:
                  content: "@file://./config/conf-${Env}.yaml"
                  mode: "000644"
                  owner: "root"
                  group: "root"
              commands:
                start_datadog:
                  command: service datadog-agent start
    

有没有简单、通用且安全的方法来实现这个?如果能给出一个示例就更好了。提前感谢。

2个回答

1
我是如何用另一种方式完成这个任务的,我创建了一个S3存储桶,然后创建了一个角色给我的EC2实例,使其可以访问这个S3存储桶并下载文件,在我的runcmd部分,我下载了这个文件。
  ServiceInstance:
    Type: "AWS::EC2::Instance"
    Properties:
      InstanceType: !Ref InstanceType
      IamInstanceProfile: !Ref InstanceProfile
      UserData:
        'Fn::Base64': !Sub |
          #cloud-config
          write_files:
          - path: /etc/sysconfig/cloudformation
            permissions: 0644
            owner: root
            content: |
              STACK_NAME=${AWS::StackName}
              AWS_REGION=${AWS::Region}
          runcmd:
          - aws s3 cp s3://${ArtifactsBucketName}/dd-get-secrets.py /home/ec2-user/dd-get-secrets.py

  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: /
      Roles: [!Ref IAMRole]

  IAMRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
        - Effect: Allow
          Principal:
            Service: [ec2.amazonaws.com]
          Action: ['sts:AssumeRole']
      Path: /
      Policies:

      - PolicyName: allow-downloading-dd-templates
        PolicyDocument:
          Statement:
          - Effect: Allow
            Action:
            - s3:GetObject
            - s3:ListBucket
            Resource: !Sub "arn:aws:s3:::${ArtifactsBucketName}/*"

0

如何传递参数以创建JSON文件

  DNACInstance:
    Type: "AWS::EC2::Instance"
    Properties:
      ImageId: !FindInMap [RegionMap, !Ref "AWS::Region", Production]
      InstanceType: t2.medium
      SecurityGroupIds: 
        - !Ref SecurityGroupID
      KeyName: !Ref Keypair 
      SubnetId: !Ref PrivateSubnet1ID
      PrivateIpAddress: !Ref PrimaryIP
      Tags:
        - Key: Name
          Value: !Sub '${EnvironmentName}_Production_Instance'
      UserData:
        'Fn::Base64': !Sub |
           #cloud-config
           write_files:
            - content: |
                {
                  "IPaddress": "${PrimaryIP}",
                  "SecondaryIPaddress": "${SecondaryIP}",
                  "netmask": "${Netmask}",
                  "gateway": "${Gateway}",
                  "dns_servers": "${Server}",
                  "https_proxy" : "${HttpProxy}",
                  "FQDN": "${FQDN}",
                  "ntp": ["169.254.169.123"]
                }
              path: /etc/instance.json```

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接