用Ansible创建和删除CloudFormation的堆栈
这是关于如何使用Ansible来创建和删除AWS CloudFormation堆栈的备忘录。简单的堆栈管理可以通过使用aws命令在shell脚本中封装来实现,但为了增强对模板输入参数和输出内容的重用性,我们使用Ansible来实现。
这里是 Ansible 的 cloudformation 模块的文档。
- cloudformation – Create or delete an AWS CloudFormation stack — Ansible Documentation
此处使用 AWS 的 Quick Start 中提供的 VPC 和 Bastion 生成堆栈。
-
- VPC Architecture – AWS Quick Start
- Linux bastion hosts on AWS – Quick Start
除了使用DependsOn来构建新的VPC堆栈的主模板之外,Bastion Stack还有一个选项是通过调用单独的模板来传递堆栈输出作为Ansible变量。
准备
首先安装Ansible,并添加Boto以便调用AWS的API。
安装 Ansible 在 Ubuntu 上需要进行以下步骤,但在其他发行版和 macOS 上大致相同。请根据使用环境进行调整。
$ sudo apt-get install -y python-pip
$ sudo pip install -U pip
$ sudo pip install ansible==2.4.0
接下来,安装Boto并将访问密钥的信息写入配置文件(〜/.boto)。
$ sudo pip install boto3
请根据使用的帐户来配置访问密钥的信息。除了具备创建和删除 CloudFormation 的权限之外,还需要具备管理堆栈中资源的权限。在堡垒机堆栈中,需要有 IAM 角色相关的权限。
[Credentials]
aws_access_key_id = xxxxxxxxxxxxxxx
aws_secret_access_key = xxxxxxxxxxxxxxx
将Ansible的变量文件准备为group_vars/all.yml。在其中定义了允许访问跳板主机(bastion)的IP地址为remote_global_ip_addr,但请根据执行环境的网络进行必要的更改。此外,请根据需要调整区域、可用区、密钥对和堆栈名称等相关参数。
---
remote_global_ip_addr: "aaa.bbb.ccc.ddd/32"
aws_region: ap-northeast-1
aws_ec2_keypair_bastion:
name: bastion
private_key_file: ~/.ssh/keys/aws_bastion.pem
aws_cfn_stack_name: "Example"
aws_cfn_vpc_stack_name: "{{ aws_cfn_stack_name }}VPC"
aws_cfn_vpc_availability_zones: "ap-northeast-1b,ap-northeast-1c"
aws_cfn_vpc_qs_template_url: "https://s3.amazonaws.com/quickstart-reference/aws/vpc/latest/templates/aws-vpc.template"
aws_cfn_vpc_qs_keypair: "{{ aws_ec2_keypair_bastion.name }}"
aws_cfn_bastion_stack_name: "{{ aws_cfn_stack_name }}Bastion"
aws_cfn_bastion_qs_template_url: "https://s3.amazonaws.com/quickstart-reference/linux/bastion/latest/templates/linux-bastion.template"
为了举例,这里将其命名为 all.yml,但如果想要根据不同的清单文件进行加载,您需要适当调整文件配置和Playbook。有关清单文件配置的详细信息,请参阅 Ansible 的文档。
- Best Practices — Ansible Documentation
创建堆栈
准备一个名为 site.yml 的 Playbook。
---
- name: Create VPC and Bastion stack
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Launch VPC network with NAT gateway
cloudformation:
region: "{{ aws_region }}"
stack_name: "{{ aws_cfn_vpc_stack_name }}"
state: "present"
template_url: "{{ aws_cfn_vpc_qs_template_url }}"
template_parameters:
AvailabilityZones: "{{ aws_cfn_vpc_availability_zones }}"
KeyPairName: "{{ aws_cfn_vpc_qs_keypair }}"
register: _vpc
- name: Launch bastion stack
cloudformation:
region: "{{ aws_region }}"
stack_name: "{{ aws_cfn_bastion_stack_name }}"
state: "present"
template_url: "{{ aws_cfn_bastion_qs_template_url }}"
template_parameters:
VPCID: "{{ _vpc.stack_outputs.VPCID }}"
PublicSubnet1ID: "{{ _vpc.stack_outputs.PublicSubnet1ID }}"
PublicSubnet2ID: "{{ _vpc.stack_outputs.PublicSubnet2ID }}"
RemoteAccessCIDR: "{{ remote_global_ip_addr }}"
EnableTCPForwarding: "true"
KeyPairName: "{{ aws_ec2_keypair_bastion.name }}"
register: _bastion
- name: Show bastion EIP
local_action: shell echo {{ _bastion.stack_outputs.EIP1 }} > bastion
执行Playbook。如果处理成功完成,将在bastion文件中输出跳板主机的IP地址。
$ ansible-playbook site.yml
删除堆栈
准备一个名为 halt.yml 的剧本。
---
- name: Delete all stacks
hosts: localhost
connection: local
gather_facts: no
tasks:
- name: Delete bastion stack
cloudformation:
region: "{{ aws_region }}"
stack_name: "{{ aws_cfn_bastion_stack_name }}"
state: "absent"
- name: Delete VPC stack
cloudformation:
region: "{{ aws_region }}"
stack_name: "{{ aws_cfn_vpc_stack_name }}"
state: "absent"
执行Playbook。
$ ansible-playbook halt.yml
总结
使用Ansible创建和删除了AWS的CloudFormation堆栈。可以根据Ansible清单管理输入参数,并将堆栈的输出结果作为变量在playbook中使用,因此在需要进行其他处理时非常方便。例如,可以考虑将跳板主机的EIP追加到~/.ssh/config中。
因为Shell脚本的写法因人而异,条件下对变量的使用也比较困难,所以将其整合到诸如Ansible等配置管理工具中会很方便。
提供环境支持
如果您要使用Vagrant来安装Ansible和Boto,请按照以下步骤进行。
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "bento/ubuntu-16.04"
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y python-pip
pip install -U pip
pip install ansible==2.4.0
pip install boto3
SHELL
end
可以使用 Ansible Local 来执行 Playbook。
- Ansible Local – Provisioning – Vagrant by HashiCorp