cytopia.cloudformation

Rola Ansible: Tworzenie stosów CloudFormation

Motywacja | Instalacja | Funkcje | Zmienne | Użycie | Szablony | Różnice | Zależności | Wymagania | Licencja

Status budowy Ansible Galaxy Wydanie

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.

  1. 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.
  2. 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.
  3. 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

Licencja MIT

Copyright (c) 2017 cytopia

O projekcie

Ansible role to render an arbitrary number of Jinja2 templates into cloudformation files and create any number of stacks.

Zainstaluj
ansible-galaxy install cytopia.cloudformation
Licencja
mit
Pobrania
5.2k
Właściciel
DevOps Engineer