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.