CloudFormation
提供了几个Python脚本来帮助用户处理EC2资源,包括cfn-init, cfn-signal, cfn-hup
等
CloudFormation helper script
已经安装在Amazon Linux AMI上,路径在opt/aws/bin
;如果想更新到最新版本,可以在userdata中执行yum update -y aws-cfn-bootstrap
aws-cfn-bootstrap
包来安装cfn-init helper script
会从 AWS::CloudFormation::Init
里读取metadata,然后执行相应的命令。然后CloudFormation
执行UserData
时,会从stack
中取出相应cfn-init
命令并执行。例如:
---
Parameters:
SSHKey:
Type: AWS::EC2::KeyPair::KeyName
Description: Name of an existing EC2 KeyPair to enable SSH access to the instance
Resources:
MyInstance:
Type: AWS::EC2::Instance
Properties:
AvailabilityZone: us-east-1a
ImageId: ami-009d6802948d06e52
InstanceType: t2.micro
KeyName: !Ref SSHKey
SecurityGroups:
- !Ref SSHSecurityGroup
# we install our web server with user data
UserData:
Fn::Base64:
!Sub |
#!/bin/bash -xe
# 获取最新版本的helper script
yum update -y aws-cfn-bootstrap
# Start cfn-init
/opt/aws/bin/cfn-init -s ${AWS::StackId} -r MyInstance --region ${AWS::Region} || error_exit 'Failed to run cfn-init'
Metadata:
Comment: Install a simple Apache HTTP page
AWS::CloudFormation::Init: # AWS::CloudFormation::Init必须放到资源的Metadata下。
config:
packages:
yum:
httpd: []
files:
"/var/www/html/index.html":
content: |
<h1>Hello World from EC2 instance!</h1>
<p>This was created using cfn-init</p>
mode: '000644'
commands:
hello:
command: "echo 'hello world'"
services:
sysvinit:
httpd:
enabled: 'true'
ensureRunning: 'true'
# our EC2 security group
SSHSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: SSH and HTTP
SecurityGroupIngress:
- CidrIp: 0.0.0.0/0
FromPort: 22
IpProtocol: tcp
ToPort: 22
- CidrIp: 0.0.0.0/0
FromPort: 80
IpProtocol: tcp
ToPort: 80
上面的CloudFormation会创建一台EC2并启动http服务, 创建完成后,登录到ec2上,index.html
已被写到里面:
cfn-init
和userdata
是如此的相像,它们都用于在创建EC2时执行自定义脚本。
但它们也有不同点:userdata
是纯的bash脚本;而cfn-init
是bash脚本层面上做抽象,将它转换为yaml格式