首页 > 解决方案 > 如何使用 CloudFormation 脚本更新 EC2 实例中的文件 application.properties?

问题描述

我创建了 AMI 以使用云形成模板启动实例。我创建了一个 centos 实例并在其上配置了我的应用程序并从该实例创建了 AMI。

现在我想创建一个 CF 模板,该模板将创建一个存储桶并在启动实例时使用创建的存储桶信息更新文件 (application.properties)。

我怎样才能做到这一点?

我的示例 CF 模板,它没有更新我的 application.properties

AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation Template with EC2InstanceWithSecurityGroup
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  InstanceType:
    Description: EC2 instance type
    Type: String
    Default: t2.medium
    AllowedValues:
      - t2.medium
      - t2.large
    ConstraintDescription: must be a valid EC2 instance type.
  RemoteAccessLocation:
    Description: The IP address range that can be used to access to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Metadata: 
      AWS::CloudFormation::Init:
        config:
          files: 
            /usr/local//application.properties:
              content:
                Fn::Join:
                  - 'SSSSSSSSSSSSSSSSSSSSSSSSSSSS'
                  - - 'YYYYYYYYYYYYYYYYYYYYYYYYYYYY'
    Properties:
      InstanceType: !Ref 'InstanceType'
      SecurityGroups:
        - !Ref 'InstanceSecurityGroup'
      KeyName: !Ref 'KeyName'
      ImageId: ami-xxxxxxxxxxxxxxx 
  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH (22), HTTP (8080)
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: !Ref 'RemoteAccessLocation'
        - CidrIp: 0.0.0.0/0
          FromPort: '8080'
          IpProtocol: tcp
          ToPort: '8080'
  S3Bucket:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Retain
    Properties:
      BucketName: sample-bucket
      AccessControl: Private 
Outputs:
  InstanceId:
    Description: InstanceId of the newly created EC2 instance
    Value: !Ref 'EC2Instance'
  AZ:
    Description: Availability Zone of the newly created EC2 instance
    Value: !GetAtt 'EC2Instance.AvailabilityZone'
  PublicDNS:
    Description: Public DNSName of the newly created EC2 instance
    Value: !GetAtt 'EC2Instance.PublicDnsName'
  PublicIP:
    Description: Public IP address of the newly created EC2 instance
    Value: !GetAtt 'EC2Instance.PublicIp'

这里的任何输入都非常感谢。

标签: yamlamazon-cloudformationaws-cloudformation-custom-resource

解决方案


AWS::CloudFormation::Init不会自行执行。您必须在UserData中使用cfn-init显式调用它。

因此,如果您必须创建UserData,直接在其中创建文件可能更容易。例如:

AWSTemplateFormatVersion: '2010-09-09'
Description: AWS CloudFormation Template with EC2InstanceWithSecurityGroup
Parameters:
  KeyName:
    Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
    Type: AWS::EC2::KeyPair::KeyName
    ConstraintDescription: must be the name of an existing EC2 KeyPair.
  InstanceType:
    Description: EC2 instance type
    Type: String
    Default: t2.medium
    AllowedValues:
      - t2.medium
      - t2.large
    ConstraintDescription: must be a valid EC2 instance type.
  RemoteAccessLocation:
    Description: The IP address range that can be used to access to the EC2 instances
    Type: String
    MinLength: '9'
    MaxLength: '18'
    Default: 0.0.0.0/0
    AllowedPattern: (\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/(\d{1,2})
    ConstraintDescription: must be a valid IP CIDR range of the form x.x.x.x/x.
Resources:
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref 'InstanceType'
      SecurityGroups:
        - !Ref 'InstanceSecurityGroup'
      KeyName: !Ref 'KeyName'
      ImageId: ami-xxxxxxxxxxxxxxx
      UserData:
        Fn::Base64: !Sub |
              #!/bin/bash -ex

              cat >/usr/local//application.properties <<EOL
              BucketName: ${S3Bucket}
              BucketArn: ${S3Bucket.Arn}
              # some other info from S3Bucket 
              EOL

  InstanceSecurityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties:
      GroupDescription: Enable SSH (22), HTTP (8080)
      SecurityGroupIngress:
        - IpProtocol: tcp
          FromPort: '22'
          ToPort: '22'
          CidrIp: !Ref 'RemoteAccessLocation'
        - CidrIp: 0.0.0.0/0
          FromPort: '8080'
          IpProtocol: tcp
          ToPort: '8080'
  S3Bucket:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Retain
    Properties:
      BucketName: sample-bucket
      AccessControl: Private 
Outputs:
  InstanceId:
    Description: InstanceId of the newly created EC2 instance
    Value: !Ref 'EC2Instance'
  AZ:
    Description: Availability Zone of the newly created EC2 instance
    Value: !GetAtt 'EC2Instance.AvailabilityZone'
  PublicDNS:
    Description: Public DNSName of the newly created EC2 instance
    Value: !GetAtt 'EC2Instance.PublicDnsName'
  PublicIP:
    Description: Public IP address of the newly created EC2 instance
    Value: !GetAtt 'EC2Instance.PublicIp'


推荐阅读