cytopia.cloudformation
Rola Ansible: Tworzenie stosów CloudFormation
Motywacja | Instalacja | Funkcje | Zmienne | Użycie | Szablony | Różnice | Zależności | Wymagania | Licencja
Rola Ansible do przetwarzania dowolnej liczby szablonów Jinja2 na pliki CloudFormation i wdrażania dowolnej liczby stosów.
Motywacja
Ta rola przezwycięża ograniczenia szablonów CloudFormation i wykorzystuje wiele funkcji Ansible.
- Ograniczenia CloudFormation - Składnia CloudFormation jest bardzo ograniczona, jeśli chodzi o logikę programowania, taką jak warunki, pętle i złożone zmienne, takie jak tablice czy słowniki. Opakowując szablon CloudFormation w Ansible, możesz korzystać z dyrektyw Jinja2 w samym szablonie CloudFormation, co pozwala na wykorzystanie wszystkich zalet Ansible i jednoczesne wdrażanie przez stosy CloudFormation.
- Niezależność od środowiska - Możliwość renderowania szablonów CloudFormation z niestandardowymi zmiennymi pętli pozwala na tworzenie szablonów w pełni niezależnych od środowiska, które można ponownie wykorzystać w produkcji, testach, stagingu i innych środowiskach.
- Symulacja - Kolejną zaletą korzystania z Ansible do wdrażania szablonów CloudFormation jest to, że Ansible obsługuje tryb symulacji (
--check
) do wdrożeń CloudFormation (od Ansible 2.4). W tym trybie utworzy plany zmian i powiadomi cię, co by się zmieniło, gdybyś wdrożył je rzeczywiście. Dzięki temu możesz bezpiecznie testować swoje stosy przed ich zastosowaniem.
Ta rola może być używana do samego generowania szablonów za pomocą cloudformation_generate_only
lub także do dodatkowego wdrażania przetworzonych szablonów. Jeśli masz już zbudowaną infrastrukturę wdrożeniową, możesz nadal korzystać z tej roli, renderując tylko szablony i przekazując je następnie do swojej istniejącej infrastruktury.
Po przetworzeniu szablonów tworzony jest tymczasowy katalog build/
w katalogu roli. Może on być trwały lub tworzony na nowo za każdym razem, gdy ta rola jest uruchamiana. Określ zachowanie za pomocą zmiennej cloudformation_clean_build_env
.
Instalacja
Możesz zainstalować rolę za pomocą Ansible Galaxy:
$ ansible-galaxy install cytopia.cloudformation
Lub sklonuj ją do swojego katalogu ról
$ git clone https://github.com/cytopia/ansible-role-cloudformation /path/to/ansible/roles
Funkcje
- Wdrażanie dowolnej liczby szablonów CloudFormation
- Tworzenie szablonów CloudFormation z silnikiem szablonów Jinja2
- Tylko renderowanie szablonów i użycie bieżącej infrastruktury do wdrożenia
- Symulacja za pomocą trybu przy pomocy komendy Ansible
--check
, która utworzy tymczasowe plany zmian (np. informuje, czy zasób wymaga ponownego utworzenia) - Możliwość porównania (diff) szablonów lokalnych i wdrożonych za pomocą modułu cloudformation_diff
- Użycie Ansible vault do przechowywania poufnych informacji w zaszyfrowanej formie
Zmienne
Przegląd
Poniższe zmienne są dostępne w pliku defaults/main.yml
i mogą być używane do konfigurowania infrastruktury.
Zmienna | Typ | Domyślnie | Opis |
---|---|---|---|
cloudformation_clean_build_env |
bool | False |
Opróżnia katalog build/ z renderowanych szablonów CloudFormation przy każdorazowym uruchomieniu. |
cloudformation_generate_only |
bool | False |
Zamiast wdrażać szablony CloudFormation, można je również tylko renderować i mieć dostępne w katalogu build/ , aby użyć bieżącej infrastruktury do wdrożenia tych szablonów.Wskazówka: Określ tę zmienną przez argumenty linii poleceń ansible |
cloudformation_run_diff |
bool | False |
Ta rola dostarcza niestandardowy moduł Ansible CloudFormation cloudformation_diff. Ten moduł generuje tekstowy wynik różnic między lokalnym szablonem CloudFormation gotowym do wdrożenia a aktualnie wdrożonym szablonem w AWS CloudFormation. Dlaczego to jest potrzebne? Aktualny moduł CloudFormation jedynie wyświetla plany zmian w trybie --check, co pozwoli ci dowiedzieć się, jakie zmiany wystąpią (np. grupy zabezpieczeń), ale nie, co dokładnie się zmieni (które grupy zabezpieczeń i ich wartości). Aby uzyskać możliwość przeglądania dokładnych zmian, które mają nastąpić, włącz moduł cloudformation_diff. |
cloudformation_diff_output |
string | json |
Kiedy cloudformation_run_diff jest włączony, co określić jako wynik różnic? Jeśli piszesz swoje szablony CloudFormation w formacie json, użyj json , a jeśli w yaml, użyj yaml . |
cloudformation_required |
lista | [] |
Tablica dostępnych kluczy stosu CloudFormation, które chcesz wymusić jako wymagane zamiast opcjonalnych. Każdy element stosu CloudFormation będzie sprawdzany pod kątem niestandardowo ustawionych wymaganych kluczy. W przypadku, gdy element stosu nie zawiera żadnego z tych kluczy, zostanie zgłoszony błąd, zanim jakiekolwiek wdrożenie się odbędzie. |
cloudformation_defaults |
słownik | {} |
Słownik domyślnych wartości stosowanych we wszystkich stosach CloudFormation. Należy pamiętać, że te wartości można nadal nadpisywać w definicji każdego stosu. |
cloudformation_stacks |
lista | [] |
Tablica stosów CloudFormation do wdrożenia. |
Detale
Ta sekcja zawiera bardziej szczegółowy opis dostępnych kluczy słowników lub tablic.
cloudformation_defaults
Klucz | Typ | Wymagane | Opis |
---|---|---|---|
aws_access_key |
string | opcjonalny | Klucz dostępu AWS do użycia |
aws_secret_key |
string | opcjonalny | Tajny klucz AWS do użycia |
security_token |
string | opcjonalny | Token bezpieczeństwa AWS do użycia |
profile |
string | opcjonalny | Profil AWS boto do użycia |
notification_arns |
string | opcjonalny | Publikuj powiadomienia o stosie do tych ARN-ów |
termination_protection |
bool | opcjonalny | Włącz lub wyłącz ochronę przed usunięciem na stosie. Działa tylko z botocore >= 1.7.18 |
region |
string | opcjonalny | Region AWS, w którym ma być wdrożony stos |
cloudformation_stacks
Klucz | Typ | Wymagane | Opis |
---|---|---|---|
stack_name |
string | wymagany | Nazwa stosu CloudFormation |
template |
string | wymagany | Ścieżka do szablonu CloudFormation do przetworzenia i wdrożenia (nie musi być renderowany) |
aws_access_key |
string | opcjonalny | Klucz dostępu AWS do użycia (nadpisuje domyślny) |
aws_secret_key |
string | opcjonalny | Tajny klucz AWS do użycia (nadpisuje domyślny) |
security_token |
string | opcjonalny | Token bezpieczeństwa AWS do użycia (nadpisuje domyślny) |
profile |
string | opcjonalny | Profil AWS boto do użycia (nadpisuje domyślny) |
notification_arns |
string | opcjonalny | Publikuj powiadomienia o stosie do tych ARN-ów (nadpisuje domyślny) |
termination_protection |
bool | opcjonalny | Włącz lub wyłącz ochronę przed usunięciem na stosie. Działa tylko z botocore >= 1.7.18 |
region |
string | opcjonalny | Region AWS, w którym ma być wdrożony stos (nadpisuje domyślny) |
template_parameters |
słownik | opcjonalny | Wymagane parametry stosu CloudFormation |
tags |
słownik | opcjonalny | Etykiety powiązane z stosami CloudFormation |
Przykłady
Określenie domyślnych wartości, które mają być zastosowane do wszystkich stosów (jeśli nie nadpisane w każdej definicji stosu)
# Wymuś, aby 'profile' był ustawiony dla każdego elementu stosu CloudFormation
cloudformation_required:
- profile
cloudformation_defaults:
region: eu-central-1
Określenie stosów CloudFormation do przetworzenia i wdrożenia
cloudformation_stacks:
- stack_name: stack-s3
template: files/cloudformation/s3.yml.j2
profile: production
template_parameters:
bucketName: my-bucket
tags:
env: production
- stack_name: stack-lambda
template: files/cloudformation/lambda.yml.j2
profile: production
termination_protection: True
template_parameters:
lambdaFunctionName: lambda
handler: lambda.run_handler
runtime: python2.7
s3Bucket: my-bucket
s3Key: lambda.py.zip
tags:
env: production
Tylko renderuj swoje szablony Jinja2, nie wdrażając ich do AWS. Wydrukowane pliki CloudFormation będą wewnątrz katalogu build/
tej roli.
$ ansible-playbook play.yml -e cloudformation_generate_only=True
Użycie
Proste
Podstawowy przykład użycia:
playbook.yml
- hosts: localhost
connection: local
roles:
- cloudformation
group_vars/all.yml
# Określ stosy CloudFormation
cloudformation_stacks:
# Pierwszy stos
- stack_name: stack-s3
profile: testing
region: eu-central-1
template: files/cloudformation/s3.yml.j2
template_parameters:
bucketName: my-bucket
tags:
env: testing
# Drugi stos
- stack_name: stack-lambda
profile: testing
termination_protection: True
region: eu-central-1
template: files/cloudformation/lambda.yml.j2
template_parameters:
lambdaFunctionName: lambda
handler: lambda.run_handler
runtime: python2.7
s3Bucket: my-bucket
s3Key: lambda.py.zip
tags:
env: testing
Zaawansowane
Zaawansowany przykład użycia wywołujący rolę niezależnie w różnych wirtualnych hostach.
inventory
[my-group]
infrastructure ansible_connection=local
application ansible_connection=local
playbook.yml
# Część infrastruktury
- hosts: infrastructure
roles:
- cloudformation
tags:
- infrastructure
# Część aplikacji
- hosts: application
roles:
- some-role
tags:
- some-role
- application
- hosts: application
roles:
- cloudformation
tags:
- application
group_vars/my-group.yml
stack_prefix: testing
boto_profile: testing
s3_bucket: awesome-lambda
cloudformation_defaults:
profile: "{{ boto_profile }}"
region: eu-central-1
host_vars/infrastructure.yml
cloudformation_stacks:
- stack_name: "{{ stack_prefix }}-s3"
template: files/cloudformation/s3.yml.j2
template_parameters:
bucketName: "{{ s3_bucket }}"
tags:
env: "{{ stack_prefix }}"
host_vars/application.yml
cloudformation_stacks:
- stack_name: "{{ stack_prefix }}-lambda"
template: files/cloudformation/lambda.yml.j2
template_parameters:
lambdaFunctionName: lambda
handler: lambda.run_handler
runtime: python2.7
s3Bucket: "{{ s3_bucket }}"
s3Key: lambda.py.zip
tags:
env: "{{ stack_prefix }}"
Szablony
Ta sekcja daje krótki przegląd tego, co można zrobić z szablonami CloudFormation wykorzystując dyrektywy Jinja2.
Przykład: Definicje podsieci
Poniższy szablon można wdrożyć w różnych środowiskach stagingowych i można dostosować liczbę podsieci.
Zmienne Ansible
---
# plik: staging.yml
vpc_subnets:
- directive: subnetA
az: a
cidr: 10.0.10.0/24
tags:
- name: Name
value: staging-subnet-a
- name: env
value: staging
- directive: subnetB
az: b
cidr: 10.0.20.0/24
tags:
- name: Name
value: staging-subnet-b
- name: env
value: staging
---
# plik: production.yml
vpc_subnets:
- directive: subnetA
az: a
cidr: 10.0.10.0/24
tags:
- name: Name
value: prod-subnet-a
- name: env
value: production
- directive: subnetB
az: b
cidr: 10.0.20.0/24
tags:
- name: Name
value: prod-subnet-b
- name: env
value: production
- directive: subnetC
az: b
cidr: 10.0.30.0/24
tags:
- name: Name
value: prod-subnet-c
- name: env
value: production
Szablon CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Description: Szablon VPC
Resources:
vpc:
Type: AWS::EC2::VPC
Properties:
CidrBlock: {{ vpc_cidr_block }}
EnableDnsSupport: true
EnableDnsHostnames: true
{% if vpc_tags %}
Tags:
{% for tag in vpc_tags %}
- Key: {{ tag.name }}
Value: {{ tag.value }}
{% endfor %}
{% endif %}
{% for subnet in vpc_subnets %}
{{ subnet.directive }}:
Type: AWS::EC2::Subnet
Properties:
AvailabilityZone: {{ subnet.az }}
CidrBlock: {{ subnet.cidr }}
VpcId: !Ref vpc
{% if subnet.tags %}
Tags:
{% for tag in subnet.tags %}
- Key: {{ tag.name }}
Value: {{ tag.value }}
{% endfor %}
{% endif %}
Przykład: Grupy zabezpieczeń
Definiowanie grup zabezpieczeń z regułami IP jest bardzo trudne, gdy chcesz zachować niezależność środowisk i używać tego samego szablonu CloudFormation dla wszystkich środowisk. Można to łatwo przezwyciężyć, dostarczając specyficzne dla środowiska definicje tablic za pomocą Jinja2.
Zmienne Ansible
---
# plik: staging.yml
# Staging jest szeroko otwarty, aby deweloperzy mogli
# łączyć się z podłączonych VPN-ów
security_groups:
- protocol: tcp
from_port: 3306
to_port: 3306
cidr_ip: 10.0.0.1/32
- protocol: tcp
from_port: 3306
to_port: 3306
cidr_ip: 192.168.0.15/32
- protocol: tcp
from_port: 3306
to_port: 3306
cidr_ip: 172.16.0.0/16
---
# plik: production.yml
# Środowisko produkcyjne ma znacznie mniej reguł oraz inne
# zakresy IP.
security_groups:
- protocol: tcp
from_port: 3306
to_port: 3306
cidr_ip: 10.0.15.1/32
Szablon CloudFormation
AWSTemplateFormatVersion: '2010-09-09'
Description: Szablon VPC
Resources:
rdsSecurityGroup:
Type: AWS::EC2::SecurityGroup
Properties:
GroupDescription: Grupa zabezpieczeń RDS
{% if security_groups %}
SecurityGroupIngress:
{% for rule in security_groups %}
- IpProtocol: "{{ rule.protocol }}"
FromPort: "{{ rule.from_port }}"
ToPort: "{{ rule.to_port }}"
CidrIp: "{{ rule.cidr_ip }}"
{% endfor %}
{% endif %}
Różnice
Włączając cloudformation_run_diff
, będziesz mógł zobaczyć wynik różnic linia po linii między twoim lokalnym (renderowanym w Jinja2) szablonem a tym, który jest obecnie wdrożony w AWS. Aby zobaczyć przykładowy wynik, oto przykład:
Upewnij się, że uruchamiasz Ansible z --diff
, aby to zadziałało:
$ ansible-playbook play.yml --diff
Różnice w formacie JSON
Aby uzyskać wynik w formacie różnic JSON, ustaw cloudformation_diff_output
na json
.
TASK [cloudformation : różnice w pliku szablonu cloudformation] *********************************************
--- przed
+++ po
@@ -38,7 +38,6 @@
"Type": "AWS::S3::BucketPolicy"
},
"s3Bucket": {
- "DeletionPolicy": "Retain",
"Properties": {
"BucketName": {
"Ref": "bucketName"
Różnice w formacie YAML
Aby uzyskać wynik w formacie różnic YAML, ustaw cloudformation_diff_output
na yaml
.
TASK [cloudformation : różnice w pliku szablonu cloudformation] *********************************************
--- przed
+++ po
@@ -14,7 +14,6 @@
Service: !Sub 'logs.${AWS::Region}.amazonaws.com'
Bucket: !Ref 's3Bucket'
s3Bucket:
- DeletionPolicy: Retain
Type: AWS::S3::Bucket
Properties:
BucketName: !Ref 'bucketName'
Zależności
Ta rola nie zależy od żadnych innych ról.
Wymagania
Użyj przynajmniej Ansible 2.5, aby mieć również tryb --check
dla CloudFormation.
Wymagany jest moduł Pythona cfn_flip
podczas używania porównania linia po linii lokalnych i zdalnych szablonów CloudFormation (cloudformation_run_diff=True
). Można go łatwo zainstalować lokalnie:
$ pip install cfn_flip
Licencja
Copyright (c) 2017 cytopia
Ansible role to render an arbitrary number of Jinja2 templates into cloudformation files and create any number of stacks.
ansible-galaxy install cytopia.cloudformation