Skip to main content

Deploy Config

The deploy-config job is used to deploy infrastructure configuration using Ansible. It runs Ansible playbooks to configure servers and infrastructure components.

Overview

This job:

  • Uses Ansible to manage infrastructure configuration
  • Clones a specific version of the Ansible module from GitLab
  • Configures SSH access for remote server management
  • Runs Ansible playbooks to apply configuration
  • Supports database-specific configuration (MySQL or PostgreSQL)
  • Supports environment-specific configuration (develop, staging, production)

Variables

The following variables can be configured:

VariableDescriptionDefaultRequired
ANSIBLE_MODULE_VERSIONVersion/tag of the Ansible module to usev0.0.118No
ANSIBLE_MODULE_PATHGitLab path to the Ansible module repositorywelance/platform/infrastructure/modules/ansible.gitNo
ANSIBLE_DIRDirectory where Ansible code will be placedinfrastructure_code/configuration_management/No
DATABASEDatabase type to configure''No
APP_ENVIRONMENTTarget environment''Yes
ACCESS_TOKENGitLab OAuth token for cloning repositories-Yes
SSH_PRIVATE_KEYSSH private key for server access-Yes
SSH_PUBLIC_KEYSSH public key for server access-Yes

Variable Details

  • ANSIBLE_MODULE_VERSION: The Git tag or branch of the Ansible module repository to use (e.g., v0.0.118)
  • ANSIBLE_MODULE_PATH: The GitLab project path to the Ansible module repository (e.g., welance/platform/infrastructure/modules/ansible.git)
  • ANSIBLE_DIR: Local directory where the Ansible module will be cloned and executed from
  • DATABASE: Database type to configure. Options:
    • 'mysql' - Configure MySQL database
    • 'postgres' - Configure PostgreSQL database
    • '' (empty) - Skip database configuration
  • APP_ENVIRONMENT: Target environment for configuration. Options:
    • 'develop' - Development environment
    • 'staging' - Staging environment
    • 'production' - Production environment

GitLab CI/CD Variables

The job uses the following built-in GitLab CI/CD variables:

  • DOCKER_HOST: Docker daemon connection (set to tcp://docker:2376)
  • DOCKER_TLS_CERTDIR: Docker TLS certificate directory (set to "/certs")

Required Secrets

The following secrets must be configured in GitLab CI/CD variables:

  • ACCESS_TOKEN: GitLab OAuth token with access to clone the Ansible module repository
  • SSH_PRIVATE_KEY: SSH private key for authenticating to target servers
  • SSH_PUBLIC_KEY: SSH public key corresponding to the private key

Usage

Basic Usage

variables:
ANSIBLE_MODULE_VERSION: v0.0.118
ANSIBLE_MODULE_PATH: welance/platform/infrastructure/modules/ansible.git
APP_ENVIRONMENT: 'develop'
DATABASE: ''

.deploy-config:
image: willhallonline/ansible:2.16.4-ubuntu-22.04
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
ANSIBLE_DIR: infrastructure_code/configuration_management/
DATABASE: ''
APP_ENVIRONMENT: ''
before_script:
- 'which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy )'
- eval `ssh-agent -s`
- echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$SSH_PUBLIC_KEY" >> ~/.ssh/id_rsa.pub
- echo "clone ansible module version "
- git clone --depth 1 --branch $ANSIBLE_MODULE_VERSION https://oauth2:[email protected]/$ANSIBLE_MODULE_PATH
- mv ansible/* $ANSIBLE_DIR
- cd $ANSIBLE_DIR
script:
- sed -i "s/\$ENVIRONMENT/${APP_ENVIRONMENT}/g" playbook-config.yml
- cat playbook-config.yml
- if [ -n "$DATABASE" ]; then ansible-playbook playbook-config.yml -i hosts --tags $DATABASE --extra-vars "ansible_ssh_extra_args='-o StrictHostKeyChecking=no'" --private-key="~/.ssh/id_rsa" --extra-vars "ENVIRONMENT=$APP_ENVIRONMENT"; else ansible-playbook playbook-config.yml -i hosts --skip-tags "mysql" --skip-tags "postgres" --extra-vars "ansible_ssh_extra_args='-o StrictHostKeyChecking=no'" --private-key="~/.ssh/id_rsa" --extra-vars "ENVIRONMENT=$APP_ENVIRONMENT"; fi

Job Details

Before Script

The before_script section performs the following setup:

  1. Install SSH client (if not available):

    which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy )
  2. Start SSH agent:

    eval `ssh-agent -s`
  3. Add SSH private key:

    echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add - > /dev/null
    • Removes carriage returns from the key
    • Adds the key to the SSH agent
  4. Configure SSH directory:

    mkdir -p ~/.ssh
    chmod 700 ~/.ssh
    echo "$SSH_PUBLIC_KEY" >> ~/.ssh/id_rsa.pub
  5. Clone Ansible module:

    git clone --depth 1 --branch $ANSIBLE_MODULE_VERSION https://oauth2:[email protected]/$ANSIBLE_MODULE_PATH
    mv ansible/* $ANSIBLE_DIR
    cd $ANSIBLE_DIR
    • Clones only the specified version (shallow clone)
    • Moves Ansible files to the configured directory
    • Changes to the Ansible directory

Script

The main script performs the following:

  1. Replace environment variable in playbook:

    sed -i "s/\$ENVIRONMENT/${APP_ENVIRONMENT}/g" playbook-config.yml
    • Replaces $ENVIRONMENT placeholder with the actual environment value
  2. Display playbook (for debugging):

    cat playbook-config.yml
  3. Run Ansible playbook:

    • If DATABASE is set: Runs playbook with database-specific tags
    • If DATABASE is empty: Runs playbook skipping database tags

With Database Configuration

ansible-playbook playbook-config.yml \
-i hosts \
--tags $DATABASE \
--extra-vars "ansible_ssh_extra_args='-o StrictHostKeyChecking=no'" \
--private-key="~/.ssh/id_rsa" \
--extra-vars "ENVIRONMENT=$APP_ENVIRONMENT"

Without Database Configuration

ansible-playbook playbook-config.yml \
-i hosts \
--skip-tags "mysql" \
--skip-tags "postgres" \
--extra-vars "ansible_ssh_extra_args='-o StrictHostKeyChecking=no'" \
--private-key="~/.ssh/id_rsa" \
--extra-vars "ENVIRONMENT=$APP_ENVIRONMENT"

Configuration Examples

Development Environment with MySQL

variables:
ANSIBLE_MODULE_VERSION: v0.0.118
ANSIBLE_MODULE_PATH: welance/platform/infrastructure/modules/ansible.git
APP_ENVIRONMENT: 'develop'
DATABASE: 'mysql'

deploy-config-dev:
extends: .deploy-config
stage: deploy
only:
- develop

Staging Environment with PostgreSQL

variables:
ANSIBLE_MODULE_VERSION: v0.0.118
ANSIBLE_MODULE_PATH: welance/platform/infrastructure/modules/ansible.git
APP_ENVIRONMENT: 'staging'
DATABASE: 'postgres'

deploy-config-staging:
extends: .deploy-config
stage: deploy
only:
- staging

Production Environment without Database

variables:
ANSIBLE_MODULE_VERSION: v0.0.118
ANSIBLE_MODULE_PATH: welance/platform/infrastructure/modules/ansible.git
APP_ENVIRONMENT: 'production'
DATABASE: ''

deploy-config-prod:
extends: .deploy-config
stage: deploy
only:
- main
- tags

Complete Pipeline Example

variables:
ANSIBLE_MODULE_VERSION: v0.0.118
ANSIBLE_MODULE_PATH: welance/platform/infrastructure/modules/ansible.git

stages:
- build
- deploy

.deploy-config:
image: willhallonline/ansible:2.16.4-ubuntu-22.04
variables:
DOCKER_HOST: tcp://docker:2376
DOCKER_TLS_CERTDIR: "/certs"
ANSIBLE_DIR: infrastructure_code/configuration_management/
DATABASE: ''
APP_ENVIRONMENT: ''
before_script:
- 'which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy )'
- eval `ssh-agent -s`
- echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- echo "$SSH_PUBLIC_KEY" >> ~/.ssh/id_rsa.pub
- echo "clone ansible module version "
- git clone --depth 1 --branch $ANSIBLE_MODULE_VERSION https://oauth2:[email protected]/$ANSIBLE_MODULE_PATH
- mv ansible/* $ANSIBLE_DIR
- cd $ANSIBLE_DIR
script:
- sed -i "s/\$ENVIRONMENT/${APP_ENVIRONMENT}/g" playbook-config.yml
- cat playbook-config.yml
- if [ -n "$DATABASE" ]; then ansible-playbook playbook-config.yml -i hosts --tags $DATABASE --extra-vars "ansible_ssh_extra_args='-o StrictHostKeyChecking=no'" --private-key="~/.ssh/id_rsa" --extra-vars "ENVIRONMENT=$APP_ENVIRONMENT"; else ansible-playbook playbook-config.yml -i hosts --skip-tags "mysql" --skip-tags "postgres" --extra-vars "ansible_ssh_extra_args='-o StrictHostKeyChecking=no'" --private-key="~/.ssh/id_rsa" --extra-vars "ENVIRONMENT=$APP_ENVIRONMENT"; fi

deploy-config-develop:
extends: .deploy-config
variables:
APP_ENVIRONMENT: 'develop'
DATABASE: 'mysql'
stage: deploy
only:
- develop

deploy-config-production:
extends: .deploy-config
variables:
APP_ENVIRONMENT: 'production'
DATABASE: ''
stage: deploy
only:
- main

Prerequisites

  • Ansible module repository: The Ansible module must exist at the specified GitLab path
  • SSH access: SSH keys must be configured and have access to target servers
  • GitLab access token: OAuth token with permissions to clone the Ansible module repository
  • Ansible playbook: The repository must contain a playbook-config.yml file
  • Ansible hosts file: An hosts inventory file must exist in the Ansible directory
  • Target servers: Servers must be accessible via SSH and configured in the Ansible inventory

Security Considerations

  • SSH Keys: Store SSH private and public keys as GitLab CI/CD masked variables
  • Access Token: Store the GitLab access token as a masked and protected variable
  • Key Permissions: SSH keys should have minimal required permissions
  • StrictHostKeyChecking: The job disables strict host key checking for convenience, but this should be reviewed for production use

Notes

  • The job uses a shallow clone (--depth 1) to reduce clone time
  • SSH agent is used to manage the SSH key during the job execution
  • The playbook file is modified in-place to replace environment placeholders
  • Database configuration is optional - the job can run without database tags
  • The Ansible image willhallonline/ansible:2.16.4-ubuntu-22.04 includes Ansible 2.16.4
  • Docker TLS is configured for Docker-in-Docker scenarios if needed
  • The job supports conditional database configuration based on the DATABASE variable