Для Ansible существует интересный модуль
cloudformation
, который позволяет создавать и удалять AWS CloudFormation стеки.
Его может быть полезно использовать, что бы удобно передавать различные параметрыдля стеков, например Dev и Production, через переменные самого Ansible.
Для примера возьмём шаблон ec2_simple_stack.json.
Содержание
Подготовка проекта
Создадим новые проект:
[simterm]
$ mkdir ansible_cf_example
[/simterm]
Создаём плейбук, всего одна роль — cloudformation
:
- hosts: - all become: true gather_facts: false roles: - role: cloudformation
Добавляем инвентори файл — hosts.ini
, домены тут сейчас не играют роли, но в реальном проекте через него будем передавать параметры для создаваемых стеков Dev и Production окружений:
[all:vars] ansible_connection: local [dev-cf-example] dev-cf-example.com [dev-cf-example:vars] [production-cf-example] production-cf-example.com [production-cf-example:vars]
В переменных для Dev и Production пока пусто, добавим их по ходу создания роли cloudformation
.
Роль cloudformation
Приступаем к созданию роли.
Добавляем каталоги:
[simterm]
$ mkdir -p roles/cloudformation/{tasks,files}
[/simterm]
Переменные для окружений
Есть несколько вариантов того, как можно определять параметры для Dev и Production стеков, например:
- передавать через
vars
вhosts.ini
- передавать через отдельные файлы переменных, которые будут подгружаться через
tasks
ролиcloudformation
(см. пример тут>>>)
Тут для простоты параметры будем переопределять через hosts.ini
, а потом использовать --limit
для ansible-playbook
, что бы указать на окружение, которое будем создавать.
Шаблон CloudFormation
В каталоге files
создаём шаблон из файла ec2_simple_stack.json:
[simterm]
$ cp ~/Work/RTFM/Github/setevoy-aws-templates/ec2_simple_stack.json roles/cloudformation/files/
[/simterm]
В нём имеется несколько параметров:
InstanceType
: тип инстанса в стекеAMIID
: AMI для EC2KeyName
: EC2 Key Pair для доступа в системуAllowLocation
: IP, которому будет разрешён SSHEC2AvailabilityZone
: в какой Availability зоне создавать инстанс
Вот их мы и будем переопределять для Dev и Production. Имеет смысл для Dev создавать инстанс поменьше, например t2.nano, а для Prod — t2.small, и использовать различные ключи, для Dev пусть будет setevoy-testing-dev, для прода — setevoy-testing-prod.
Остальные параметры будут общие, их задачим в [all:vars]
.
Кроме того — для Dev и Prod добавим переменную env
.
Возвращаемся к hosts.ini
, добавляем переменные:
[all:vars] aws_access_key="AKI***AYQ" aws_secret_key="q0I***jvj" region="eu-west-1" ansible_connection=local ami_id="ami-8a745cf3" allow_location="0.0.0.0/0" ec2_availability_zone="eu-west-1a" [dev-cf-example] dev-cf-example.com [dev-cf-example:vars] instance_type="t2.nano" key_name="setevoy-testing-dev" env="Dev" [production-cf-example] production-cf-example.com [production-cf-example:vars] instance_type="t2.small" key_name="setevoy-testing-prod" env="Production"
Задача создания стека
Теперь можно добавить задачу для создания стека.
Описываем её в файле roles/cloudformation/tasks/main.yml
:
- name: "Create a {{ env }} Cloudformation stack" cloudformation: aws_access_key: "{{ aws_access_key }}" aws_secret_key: "{{ aws_secret_key }}" region: "{{ region }}" stack_name: "ansible-{{ env }}-cf-example" state: "present" disable_rollback: true template: "roles/cloudformation/files/ec2_simple_stack.json" template_parameters: KeyName: "{{ key_name }}" InstanceType: "{{ instance_type }}" AllowLocation: "{{ allow_location }}" tags: Stack: "ansible-cloudformation"
Создание стека
Далее можно создавать стек.
Проверяем плейбук:
[simterm]
$ ansible-playbook -i hosts.ini --limit=dev-cf-example ansible_cf_example.yml --check PLAY [all] **** TASK [cloudformation : Create a Dev Cloudformation stack] **** changed: [dev-cf-example.com] PLAY RECAP **** dev-cf-example.com : ok=1 changed=1 unreachable=0 failed=0
[/simterm]
Создаём Dev:
[simterm]
$ ansible-playbook -i hosts.ini --limit=dev-cf-example ansible_cf_example.yml PLAY [all] **** TASK [cloudformation : Create a Dev Cloudformation stack] **** changed: [dev-cf-example.com] PLAY RECAP **** dev-cf-example.com : ok=1 changed=1 unreachable=0 failed=0
[/simterm]
Проверяем значения, которые мы передавали:
[simterm]
$ aws ec2 describe-instances --instance-ids i-027dbe988498ce5d6 --query '[Reservations[*].Instances[*].InstanceType]' --output text t2.nano
[/simterm]
ОК, создаём Production:
[simterm]
$ ansible-playbook -i hosts.ini --limit=production-cf-example ansible_cf_example.yml PLAY [all] **** TASK [cloudformation : Create a Production Cloudformation stack] **** changed: [production-cf-example.com] PLAY RECAP **** production-cf-example.com : ok=1 changed=1 unreachable=0 failed=0
[/simterm]
Проверяем:
[simterm]
$ aws ec2 describe-instances --instance-ids i-012c67879aaf0001b --query '[Reservations[*].Instances[*].InstanceType]' --output text t2.small
[/simterm]
Всё работает, как ожидалось.
Готово.