AWS CloudFormation是一个AWS提供的,可以帮助我们快速创建云资源的工具。
创建AWS资源,可以使用CLI,API或者各种SDK直接创建资源,这些方式对于创建单类资源还好,如果要用来管理整个team或公司的资源就显得力不从心,而CloudFormation是专门用来管理AWS资源的IaC工具,可以清晰的描述和修改资源。
文章目录:
CloudFormation概念
如何使用CloudFormation
CloudFormation相关权限
使用CodePipeline部署CF
template:是一个json或yaml格式的文件,里面包含申请的资源
AWSTemplateFormatVersion: '2010-09-09'
Description: create ELB for query service
Parameters:
EnvName:
Type: String
Description: Name of current running environment
Conditions:
CreateResourceAllowed: !Equals [ !Ref 'AWS::Region', us-east-1 ]
Resources:
MyEC2Instance:
Type: AWS::EC2::Instance
Condition: CreateResourceAllowed
Properties:
ImageId: "ami-79fd7eee"
KeyName: "testkey"
BlockDeviceMappings:
- DeviceName: "/dev/sdm"
Ebs:
VolumeType: "io1"
Iops: "200"
DeleteOnTermination: "false"
VolumeSize: "20"
- DeviceName: "/dev/sdk"
NoDevice: {}
Outputs:
MyEC2InstanceInstanceID:
Value: !Ref 'MyEC2Instance'
Description: The ID of MyEC2Instance
Export:
Name: 'MyEC2Instance_ID'
template主要分为几部分,Parameters用来描述参数,Conditions用来描述创建资源的条件,Resources描述需要的资源,Outputs输入变量,可供其他stack使用。
template可以是本地文件,也可以是放在s3上的文件
stack: 管理资源的集合,一个template对应一个stack
changeset: 描述对一个stack的修改
准备好AWS环境和一个有CloudFormation权限的账户
准备aws template,描述要创建的ELB,如下
AWSTemplateFormatVersion: '2010-09-09'
Description: create ELB for query service
Parameters:
EnvName:
Type: String
Description: Name of current running environment
Resources:
AWSCFELB:
Type: AWS::ElasticLoadBalancing::LoadBalancer
Properties:
LoadBalancerName: !Join
- ''
- - aws-cf-lb-
- !Ref 'EnvName'
Subnets: 'xxxxx'
SecurityGroups: 'yyyyy'
CrossZone: true
Listeners:
- LoadBalancerPort: '2443'
InstancePort: '3443'
Protocol: TCP
InstanceProtocol: TCP
ConnectionSettings:
IdleTimeout: 300
3. 使用使用CLI,API,SDK或者AWS console创建stac
aws cloudformation create-stack \
--stack-name aws-cf-lb-stack \
--template-body file:///home/eason/aws-cf-lb.yaml \
--parameters ParameterKey=EnvName,ParameterValue=test
之后就可以在CloudFormation里面看到这个stack,也可以修改template,然后使用update-stack命令更新stack
CloudFormation process

对于要创建CF stack的user,需要CreateStack等权限才能创建CF stack,但是由于资源是由stack创建的,stack并没有创建资源的权限,所以需要给CF stack一个service role,让CF stack代表该role去创建资源。
比如stack的service role是cmsCfRole,cmsCfRole包含了创建sqs的权限,该stack才能创建sqs,否则会失败。

此时还要注意,user要有将CfRole传递给stack的权限—iam:PassRole。举例,user有ec2:CreateVpc和cloudformation:CreateStack的权限,表示该user可以创建VPC和CF stack,但是该user创建的stack却没有CreateVpc的权限,所以需要PassRole,因此user需要设置PassRole.
- PolicyName: CloudFormationIAMPRAccess
PolicyDocument:
Version: '2012-10-17'
Statement:
- Action:
- 'iam:PassRole'
Effect: Allow
Resource:
- 'arn:aws:iam::*:role/CfRole'
iam:PassRole可能会遇到多级传递的问题,比如user用CodePipeline去创建stack,stack创建的ec2:instance需要ec2Role,那么user需要有CodePipeline等资源的权限,和将CfRole传递下去的PassRole,此时CodePipeline创建的stack的role为CfRole,CfRole需要包含将ec2Role传递下去的PassRole,这样stack创建的ec2才能有ec2Role权限。
如果stack中包含IAM资源,需要执行capabilities, CAPABILITY_IAM or CAPABILITY_NAMED_IAM, 如果包含自定义IAM资源,则需指定为CAPABILITY_NAMED_IAM
使用CodePipeline可以更细致的部署CF,可以查看CF的changeset再决定是否部署,给运维人员更多的选择。
CodePipeline是一个continuous delivery service,pipeline由stage组成,stage包含action,action是一系列操作的集合。
run CF的pipeline一般由两个stage组成,第一个stage定义CF template位置,第二个stage包含三个action,CreateChangeSet,ApproveChangeSet 和ExecuteChangeSet action,其中create和execute changeSet action需指定有操作stack权限的role,因为这两步会创建或修改stack,如果stack创建的资源需要特定权限,则该role需要有PassRole权限。
因为stack可能会引用其他stack的output,所以stack的创建有顺序的要求,同理CodePipeline的执行也有顺序要求,以避免创建stack失败。

