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:
| Variable | Description | Default | Required |
|---|---|---|---|
ANSIBLE_MODULE_VERSION | Version/tag of the Ansible module to use | v0.0.118 | No |
ANSIBLE_MODULE_PATH | GitLab path to the Ansible module repository | welance/platform/infrastructure/modules/ansible.git | No |
ANSIBLE_DIR | Directory where Ansible code will be placed | infrastructure_code/configuration_management/ | No |
DATABASE | Database type to configure | '' | No |
APP_ENVIRONMENT | Target environment | '' | Yes |
ACCESS_TOKEN | GitLab OAuth token for cloning repositories | - | Yes |
SSH_PRIVATE_KEY | SSH private key for server access | - | Yes |
SSH_PUBLIC_KEY | SSH 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 totcp://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 repositorySSH_PRIVATE_KEY: SSH private key for authenticating to target serversSSH_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:
-
Install SSH client (if not available):
which ssh-agent || ( apt-get update -qy && apt-get install openssh-client -qqy ) -
Start SSH agent:
eval `ssh-agent -s` -
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
-
Configure SSH directory:
mkdir -p ~/.ssh
chmod 700 ~/.ssh
echo "$SSH_PUBLIC_KEY" >> ~/.ssh/id_rsa.pub -
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:
-
Replace environment variable in playbook:
sed -i "s/\$ENVIRONMENT/${APP_ENVIRONMENT}/g" playbook-config.yml- Replaces
$ENVIRONMENTplaceholder with the actual environment value
- Replaces
-
Display playbook (for debugging):
cat playbook-config.yml -
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.ymlfile - Ansible hosts file: An
hostsinventory 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.04includes Ansible 2.16.4 - Docker TLS is configured for Docker-in-Docker scenarios if needed
- The job supports conditional database configuration based on the
DATABASEvariable