如何使用 CloudFormation 脚本从外部文件(例如从 S3 存储桶)更新 EC2 实例中的文件 application.properties?
How to update a file application.properties in EC2 instance from an external file (e.g from S3 bucket) using CloudFormation script?
我可以更新 application.properties 并使用以下 CloudFormation 模板重新启动服务。但我想从外部文件(例如: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 或特定 bucket/object 的读取权限的 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'
我可以更新 application.properties 并使用以下 CloudFormation 模板重新启动服务。但我想从外部文件(例如: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 或特定 bucket/object 的读取权限的 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'