Ansible dans l'ecosysteme DevOps 26 min de lecture

GitLab CI et HashiCorp Vault avec Ansible

GitLab CI avec Ansible

Integrer Ansible dans les pipelines GitLab CI pour automatiser les deploiements.

Pipeline GitLab CI complet

# .gitlab-ci.yml
stages:
  - validate
  - provision
  - configure
  - deploy
  - smoke_test

variables:
  ANSIBLE_FORCE_COLOR: "true"
  ANSIBLE_CONFIG: "./ansible.cfg"

validate_ansible:
  stage: validate
  image: python:3.11
  script:
    - pip install ansible ansible-lint yamllint
    - yamllint -c .yamllint .
    - ansible-lint
    - ansible-playbook --syntax-check site.yml

provision_infra:
  stage: provision
  image: hashicorp/terraform:1.6
  script:
    - cd terraform
    - terraform init
    - terraform plan -out=tfplan
    - terraform apply tfplan
    - terraform output -json > ../tf_output.json
  artifacts:
    paths:
      - tf_output.json
    expire_in: 1 hour

configure_servers:
  stage: configure
  image: python:3.11
  dependencies:
    - provision_infra
  before_script:
    - pip install ansible
    - ansible-galaxy install -r requirements.yml
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | ssh-add -
  script:
    - ansible-playbook -i inventory/dynamic.py configure.yml
  environment:
    name: staging

deploy_app:
  stage: deploy
  image: python:3.11
  dependencies:
    - configure_servers
  before_script:
    - pip install ansible
    - eval $(ssh-agent -s)
    - echo "$SSH_PRIVATE_KEY" | ssh-add -
  script:
    - ansible-playbook -i inventory/dynamic.py deploy.yml
      -e "app_version=$CI_COMMIT_TAG"
  environment:
    name: production
  rules:
    - if: $CI_COMMIT_TAG
  when: manual

smoke_test:
  stage: smoke_test
  image: python:3.11
  dependencies:
    - deploy_app
  script:
    - ansible-playbook -i inventory/dynamic.py smoke-tests.yml

HashiCorp Vault avec Ansible

HashiCorp Vault stocke les secrets de maniere securisee. Ansible peut les recuperer via le plugin hashi_vault.

# Installation
pip install hvac
ansible-galaxy collection install community.hashi_vault

Lookup plugin hashi_vault

- hosts: all
  vars:
    vault_addr: "https://vault.example.com:8200"
    vault_token: "{{ lookup('env', 'VAULT_TOKEN') }}"

  tasks:
    - name: Recuperer un secret depuis Vault
      ansible.builtin.set_fact:
        db_password: "{{ lookup('community.hashi_vault.hashi_vault',
          'secret/data/production/database',
          token=vault_token,
          url=vault_addr) | community.hashi_vault.vault_kv2_get('password') }}"

    - name: Recuperer plusieurs secrets
      ansible.builtin.set_fact:
        app_secrets: "{{ lookup('community.hashi_vault.hashi_vault',
          'secret/data/production/app',
          token=vault_token,
          url=vault_addr) }}"

    - name: Utiliser les secrets
      ansible.builtin.template:
        src: app-config.j2
        dest: /etc/mon-app/config.yml
        mode: "0600"
      vars:
        database_url: "postgresql://app:{{ db_password }}@db:5432/production"
        api_key: "{{ app_secrets.data.data.api_key }}"

Authentification Vault via AppRole

- hosts: all
  vars:
    vault_addr: "https://vault.example.com:8200"

  tasks:
    - name: S'authentifier via AppRole
      ansible.builtin.uri:
        url: "{{ vault_addr }}/v1/auth/approle/login"
        method: POST
        body_format: json
        body:
          role_id: "{{ lookup('env', 'VAULT_ROLE_ID') }}"
          secret_id: "{{ lookup('env', 'VAULT_SECRET_ID') }}"
      register: vault_auth

    - name: Recuperer les secrets avec le token AppRole
      ansible.builtin.set_fact:
        secrets: "{{ lookup('community.hashi_vault.hashi_vault',
          'secret/data/production/app',
          token=vault_auth.json.auth.client_token,
          url=vault_addr) }}"

Ansible Vault vs HashiCorp Vault

  • Ansible Vault : chiffrement de fichiers locaux, ideal pour les petits projets
  • HashiCorp Vault : gestion centralisee des secrets, rotation automatique, audit, ideal pour l'entreprise
Securite : Ne stockez jamais de secrets dans les variables ou les fichiers en clair. Utilisez HashiCorp Vault ou Ansible Vault selon la taille du projet.