yaml - 如何使用 CloudFormation 脚本从外部文件(例如来自 S3 存储桶)更新 EC2 实例中的文件 application.properties?

标签 yaml aws-cloudformation aws-cloudformation-custom-resource

我可以使用以下 CloudFormation 模板更新 application.properties 并重新启动服务。但我想从外部文件(例如:S3 或 git)而不是脚本更新 application.properties 文件。

我怎样才能实现这个目标?

我的 CF 模板,

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:
  S3Bucket:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Retain
    Properties:
      BucketName: my-test-bucket
      AccessControl: Private 
  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref 'InstanceType'
      SecurityGroups:
        - !Ref 'InstanceSecurityGroup'
      KeyName: !Ref 'KeyName'
      ImageId: ami-xxxxxxxxxxxxxxxx
      UserData:
        Fn::Base64: !Sub |
              #!/bin/bash -ex

              cat >/usr/local/application.properties <<EOL
              amazon.s3.bucket-name=${S3Bucket}
              amazon.s3.region=ap-south-1
              amazon.s3.access-key=xxxxxxxxxxxxxxxxxxx
              amazon.s3.secret-key=yyyyyyyyyyyyyyyyxxxxxxxxx

              ## H2 Config
              spring.datasource.url=jdbc:h2:mem:testdb
              spring.datasource.driverClassName=org.h2.Driver
              spring.datasource.username=username
              spring.datasource.password=password
              spring.jpa.show-sql=true
              spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.H2Dialect
              spring.jpa.hibernate.ddl-auto=update
              EOL

              ## Restart our service
              sudo systemctl restart myapplication.service

  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'
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'

这里的任何意见都非常感谢。

最佳答案

您必须使用具有 S3 或特定存储桶/对象的读取权限的 AWS::IAM::Role 创建 AWS::IAM::InstanceProfile。然后,您在用户数据中使用 aws CLI 将文件从 s3 获取到您的实例中。我不知道您的 AMI 是什么,但如果是标准 Amazon Linux 2 或 Ubuntu,则它已经安装了 AWS CLI。

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:

  S3Bucket:
    Type: 'AWS::S3::Bucket'
    DeletionPolicy: Retain
    Properties:
      BucketName: my-test-bucket
      AccessControl: Private 

  MyInstanceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: '2012-10-17'               
        Statement:
          - Effect: Allow
            Principal: {'Service': ['ec2.amazonaws.com']}
            Action: ['sts:AssumeRole']
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess   
      Path: '/'  

  MyInstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties: 
      Roles: 
        - !Ref MyInstanceRole

  EC2Instance:
    Type: AWS::EC2::Instance
    Properties:
      InstanceType: !Ref 'InstanceType'
      SecurityGroups:
        - !Ref 'InstanceSecurityGroup'
      KeyName: !Ref 'KeyName'
      ImageId: ami-xxxxxxxxxxxxxxxx
      IamInstanceProfile: !Ref MyInstanceProfile
      UserData:
        Fn::Base64: !Sub |
              #!/bin/bash -ex

              aws s3 cp s3://<your-bucket-with-settings>/application.properties /usr/local/application.properties

              ## Restart our service
              sudo systemctl restart myapplication.service

  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'

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'

关于yaml - 如何使用 CloudFormation 脚本从外部文件(例如来自 S3 存储桶)更新 EC2 实例中的文件 application.properties?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66488012/

相关文章:

amazon-web-services - 云信息 : Import existing resource

json - 我可以在 AWS Cloudformation json 模板的 "Fn::Join"中使用 "Parameters"吗

postgresql - 如何将CloudFormation中RDS实例的PostgreSQL日志导出到CloudWatch?

amazon-web-services - AWS 云信息 : How to use username as a tag

perl - 为什么我必须加载 Perl 类才能使用我从 YAML 反序列化的对象?

amazon-web-services - "start a build under these conditions"的 AWS CodeBuild CloudFormation YAML Webhook 事件

amazon-web-services - AWS CDK : Adding new stack not working (not showing up)

bash - Gitlab CI 配置对条件语句无效

python - 安西 bool 。覆盖单个字典键

powershell - 在 PowerShell 中使用 YQ 时出现引用问题