Ansible: configuration and deploy
(Section: Technology and Infrastructure)
Brief Summary
Ansible is a declarative configuration and orchestration tool ideal for repeated configuration of VMs/hosts, services and applications when the infrastructure has already been created (Terraform/IaC) and you need to "revive" the environment: install packages, roll out the release, roll out templates, restart services without downtime, apply security policies. Key to success: modular structure (roles/collections), strict idempotence, neat work with secrets (Vault), dynamic inventory, testing and GitOps discipline.
When is Ansible appropriate (and how does it fit with Terraform)
Terraform - creates resources (VPC, clusters, databases).
Ansible - configures the OS/software, rolls out versions, drives migrations, edits files and services.
Link: Terraform outputs' inventory '/IP/secrets to artifacts, Ansible reads them in a CD step.
Repository structure (recommended template)
ansible/
inventories/
prod/
inventory. ini # or inventory. yaml group_vars/
all. yml web. yml db. yml host_vars/
web-01. yml stage/
...
roles/
webapp/
defaults/main. yml vars/main. yml tasks/main. yml handlers/main. yml templates/.j2 files/
meta/main. yml hardening/
...
playbooks/
site. yml deploy_webapp. yml hardening. yml collections/requirements. yml ansible. cfg
ansible. cfg (minimum):
ini
[defaults]
inventory = inventories/stage/inventory. ini stdout_callback = yaml callbacks_enabled = timer, profile_tasks interpreter_python = auto retry_files_enabled = False forks = 25 host_key_checking = True
Inventories: static and dynamic
Static (ini):ini
[web]
web-01 ansible_host=10. 0. 1. 10 web-02 ansible_host=10. 0. 1. 11
[db]
db-01 ansible_host=10. 0. 2. 10
[all:vars]
ansible_user=ansible ansible_ssh_common_args='-o ProxyJump=bastion@1. 2. 3. 4'
Dynamic
Use cloud plugins (or your own script) to tag hosts. Environment/tag variables → 'group _ vars'.
Roles and Collections
Role = independent reuse module (tasks, files, templates, handlers).
Collections - a set of roles/plugins/modules. Fix version pins in 'collections/requirements. yml`.
yaml collections/requirements. yml collections:
- name: community. general version: ">=8. 0. 0,<9. 0. 0"
- name: ansible. posix
Playbooks: Idempotent scripts
Example of a general playbook:yaml playbooks/site. yml
- hosts: all gather_facts: true become: true roles:
- hardening
- hosts: web become: true roles:
- webapp
'Webapp'role (fragments):
yaml roles/webapp/tasks/main. yml
- name: Install packages:
name: ["nginx", "python3-venv"]
state: present
- name: Template configuration template:
src: nginx. conf. j2 dest: /etc/nginx/nginx. conf mode: "0644"
notify: Restart nginx
- name: unarchive artifact deploy:
src: "{{ webapp_package_url }}" # артефакт из CI dest: /opt/webapp remote_src: true creates: /opt/webapp/current
- name: Link to the current version of file:
src: "/opt/webapp/releases/{{ release_id }}"
dest: /opt/webapp/current state: link notify: Reload webapp
Handlers:
yaml roles/webapp/handlers/main. yml
- name: Restart nginx service: { name: nginx, state: restarted }
- name: Reload webapp systemd: { name: webapp, state: reloaded, daemon_reload: true }
Jinja2 Templates and Variables
Store default variables in 'defaults/main. yml ', sensitive - in Vault.
Use filters ('| to_nice_yaml',' | b64encode ',' | default ') and' when 'conditions.
jinja2 worker_processes auto;
http {
server {
listen 80;
server_name {{ inventory_hostname }};
location / {
proxy_pass http://127. 0. 0. 1:{{ webapp_port }};
}
}
}
Secrets: Ansible Vault and Secret Managers
Vault to encrypt variable files ('group _ vars/all. vault. yml`).
It is better to read secrets from external managers (KMS/Secrets Manager/SSM) through the corresponding modules and store only links/ARN in Vault.
yaml group_vars/all. vault. yml (ansible-vault encrypted)
webapp_db_password: "..."
jwt_signing_key: "..."
Recommendations:
- Share access: developers see dev/stage, prod - only CI.
- Enable secret rotation and access auditing.
Idempotency and correct changes
Use modules ('package', 'user', 'lineinfile', 'template', 'systemd') instead of 'shell/command'.
Mark "noisy" tasks' changed _ when: false'if they do not change anything.
Support check mode ('--check') and diff for roles.
For unstable tasks: 'retries', 'delay', 'until'.
yaml
- name: Wait for HTTP uri availability:
url: "http://localhost/health"
status_code: 200 register: health retries: 10 delay: 5 until: health. status == 200
Performance: Large farms and peaks
forks: raise concurrency (caution: do not overload target).
strategy = free-Execute tasks without waiting for neighbors.
pipelining = True в `ansible. cfg 'reduces RTT.
gather_facts: false where facts are unnecessary.
async/poll for long-term operations; throttle/serial for deploy waves.
delegate_to and run_once for single actions (for example, database migration).
Zero downtime patterns
Rolling Deploy (20% each)
yaml
- hosts: web serial: "20%"
max_fail_percentage: 10 roles: [webapp]
Canary
Run the playbook with '--limit web-canary' (a subset of the group), check the metrics, then roll out to the entire group.
Blue-Green
Two host groups' web _ blue'and' web _ green '; prepare a new wave with a playbook, then switch traffic (DNS/LB) with the 'community task. general. affiliate_lb'/API your balancer.
Security and hardening
Hardening role: SSH policies, banners, 'sudo' without NOPASSWD, firewall, auditd/rsyslog, time-NTP, 'fail2ban'.
Enable SELinux/AppArmor, manage policies through modules.
Bastion: Restrict SSH to targets via jump-host only (see 'ProxyJump').
Minimize 'become: true'; draw up RBAC at the inventory level (who can run which playbooks).
Windows and network hardware
Windows: modules' win _ ', WinRM connection, PowerShell scripts - as the last argument.
Network: 'network _ cli '/' httpapi', modules for Cisco/Juniper/F5; atomicity via 'save _ when: changed'.
Testing and quality
ansible-lint + yamllint в CI.
Molecule: local/container role tests, idempotency check (double run unchanged).
Sandbox: individual VM temporary inventory/images.
yaml provisioner:
name: ansible verifier:
name: ansible scenario:
name: default
Integration with CI/CD and GitOps
Typical pipeline:1. Lint → Syntax check → Molecule.
2. Building application artifacts.
3. Deploy: `ansible-playbook -i inventories/prod site. yml --limit web --tags deploy`.
4. Report on changed hosts, artifact of logs.
Example step (concept):bash ansible-galaxy collection install -r collections/requirements. yml ansible-lint ansible-playbook playbooks/deploy_webapp. yml \
-i inventories/prod/inventory. ini \
-e release_id=${GIT_SHA} --diff
Observability and audit
Connect callback plugins (json/yaml/timer/profile_tasks) - reports on time and changes.
Save playbook logs to centralized storage.
Label 'tags:' tasks for selective runs and expedite investigations.
Frequent recipes for iGaming
Web/API node: Nginx + systemd-unit, health-checks, secrets from the manager, roll-restart.
Game services: config templates by region/tenants via 'group _ vars'.
Payment connectors: strict ones for keys, restart by notify, post-check of endpoints.
ETL jobs: deploying CronJob scripts with'cron 'module, idempotent lock file.
Monitoring: installation of agents (node_exporter/otelcol), auto-registration in monitoring.
Antipatterns
Using 'shell/command' where there is a module.
Playbooks without 'handlers' → unnecessary restarts and service jitter.
Storing secrets in public 'group _ vars'.
Absence of'serial '/' max _ fail _ percentage'during production wave depletion.
Global 'gather _ facts: true' and 'become: true' unnecessarily.
Roles without Molecule tests and without '--check' support.
Long commands without 'async/poll' blocking the entire wave.
Implementation checklist
1. Agree on the repository framework and naming conventions.
2. Configure dynamic inventory and bastion.
3. Create roles (webapp/hardening/monitoring) and pin versions of collections.
4. Enable Vault and/or integration with the Secret Manager.
5. Ensure idempotency, '--check/--diff', handlers and tags.
6. Connect ansible-lint, yamllint, Molecule to CI.
7. Describe the deploy pattern (rolling/canary/blue-green) and the'serial' limits.
8. Add callback plugins, log collection, change report.
9. Document rollback runbooks and incident actions.
10. Regularly hold game-day: SSH break, node drop, version rollback.
Results
Ansible closes the "last mile" between the infrastructure created and the sales that work: quick, secure and predictable changes to configurations and releases. With a role as a minimal reuse unit, dynamic inventory, correct secret handling, and verified zero-downtime patterns, Ansible helps iGaming teams reduce Time-to-Deploy, reduce nighttime incidents, and keep p99 at SLO level.