Container Configuration¶
Learn how to customize container deployments for different testing scenarios.
Configuration Methods¶
There are multiple ways to configure containers:
- Inventory variables (recommended for permanent settings)
- Extra variables (good for ad-hoc changes)
- Environment variables (for secrets)
- Role defaults (fallback values)
Inventory Configuration¶
Group Variables¶
Define settings for all containers:
# inventory.yml or group_vars/all.yml
---
all:
vars:
# Common settings
domain: example.org
ansible_user: youruser
# Network settings
service_network: "ct-net"
service_dns_servers:
- "1.1.1.1"
- "8.8.8.8"
Host Variables¶
Configure specific services per host:
# host_vars/testhost.yml
---
# Redis configuration
redis_state: present
redis_port: 6379
redis_password: "test_password_123"
redis_maxmemory: "512mb"
# Mattermost configuration
mattermost_state: present
mattermost_port: 8065
mattermost_postgres_password: "mm_test_pass"
Service Groups¶
Group hosts by service:
# inventory.yml
all:
children:
redis_hosts:
hosts:
testhost1:
testhost2:
vars:
redis_port: 6379
redis_password: "shared_password"
mattermost_hosts:
hosts:
testhost3:
vars:
mattermost_port: 8065
Extra Variables¶
Override settings on the command line:
# Change port
./manage-svc.sh redis deploy -e redis_port=6380
# Enable TLS
./manage-svc.sh elasticsearch deploy \
-e elasticsearch_enable_tls=true \
-e elasticsearch_tls_cert_file=/path/to/cert.pem
# Multiple overrides
./manage-svc.sh mattermost deploy \
-e mattermost_port=8066 \
-e mattermost_site_name="Test Instance"
Environment Variables¶
For sensitive data, use environment variables:
# Export before running
export REDIS_PASSWORD="secure_password"
export ELASTIC_PASSWORD="another_secure_password"
./manage-svc.sh redis deploy
./manage-svc.sh elasticsearch deploy
In your role defaults:
# roles/redis/defaults/main.yml
redis_password: "{{ lookup('env', 'REDIS_PASSWORD') | default('changeme') }}"
Common Configuration Patterns¶
Pattern 1: Testing with Minimal Resources¶
For fast, lightweight testing:
Pattern 2: Production-like Configuration¶
For realistic integration testing:
# production-like.yml
elasticsearch_memory: "2g"
elasticsearch_enable_tls: true
redis_maxmemory: "1g"
vault_enable_audit: true
mattermost_enable_tls: true
Pattern 3: Multi-Instance Testing¶
Run multiple instances on different ports:
# instance1.yml
redis_port: 6379
redis_data_dir: "~/redis-instance1-data"
# instance2.yml
redis_port: 6380
redis_data_dir: "~/redis-instance2-data"
Pattern 4: Service Mesh Testing¶
Configure multiple services to work together:
# service-mesh.yml
---
# Traefik as reverse proxy
traefik_state: present
traefik_http_port: 8080
# Backend services
mattermost_state: present
mattermost_port: 8065
elasticsearch_state: present
elasticsearch_port: 9200
# Configure Traefik to route to services
traefik_services:
- name: mattermost
port: 8065
host: "chat.test.local"
- name: elasticsearch
port: 9200
host: "search.test.local"
Service-Specific Configuration¶
Redis¶
# Cache server
redis_maxmemory: "256mb"
redis_maxmemory_policy: "allkeys-lru"
redis_save: "" # Disable persistence
# Persistent queue
redis_maxmemory: "1g"
redis_maxmemory_policy: "noeviction"
redis_save: "900 1 300 10 60 10000" # RDB snapshots
redis_appendonly: true # Enable AOF
Elasticsearch¶
# Development
elasticsearch_memory: "512m"
elasticsearch_enable_security: false
# Testing
elasticsearch_memory: "1g"
elasticsearch_enable_security: true
elasticsearch_password: "test_password"
# Performance testing
elasticsearch_memory: "4g"
elasticsearch_enable_tls: true
Mattermost¶
# Minimal
mattermost_port: 8065
mattermost_enable_email: false
# Full-featured
mattermost_port: 8065
mattermost_enable_email: true
mattermost_enable_tls: true
mattermost_smtp_server: "localhost:25"
HashiVault¶
# File storage (simplest)
vault_storage_type: "file"
# Raft storage (HA testing)
vault_storage_type: "raft"
vault_cluster_addr: "http://127.0.0.1:8201"
Dynamic Configuration¶
Using Ansible Facts¶
# Use host memory for automatic sizing
elasticsearch_memory: "{{ (ansible_memtotal_mb * 0.5) | int }}m"
# Use hostname in configuration
mattermost_site_name: "Mattermost - {{ ansible_hostname }}"
Conditional Configuration¶
# Enable features based on environment
redis_enable_persistence: "{{ 'production' in group_names }}"
vault_enable_audit: "{{ 'production' in group_names }}"
Templates with Variables¶
# Use Jinja2 in values
mattermost_site_url: "https://{{ ansible_fqdn }}:{{ mattermost_port }}"
elasticsearch_cluster_name: "{{ ansible_hostname }}-cluster"
Configuration Validation¶
Pre-deployment Checks¶
# tasks/validate.yml
- name: Validate required variables
assert:
that:
- redis_password is defined
- redis_password != "changeme"
- redis_port >= 1024
- redis_port <= 65535
fail_msg: "Invalid Redis configuration"
Post-deployment Verification¶
# Verify configuration applied correctly
./svc-exec.sh redis verify
./svc-exec.sh elasticsearch verify
Configuration File Management¶
Backup Configurations¶
# Save current configuration
podman exec redis-svc redis-cli CONFIG GET '*' > redis-config-backup.txt
# Export Elasticsearch settings
curl -X GET "localhost:9200/_cluster/settings?pretty" > es-config-backup.json
Version Control¶
Keep test configurations in version control:
configs/
├── test/
│ ├── minimal.yml
│ ├── full-stack.yml
│ └── performance.yml
├── ci/
│ ├── github-actions.yml
│ └── gitlab-ci.yml
└── local/
└── dev.yml
Troubleshooting Configuration Issues¶
Check Applied Configuration¶
# Redis
podman exec redis-svc redis-cli CONFIG GET maxmemory
# Elasticsearch
curl localhost:9200/_cluster/settings?include_defaults=true
# Vault
podman exec vault-svc vault status
View Role Variables¶
# Show all variables for a role
ansible-playbook deploy-redis.yml --list-tags
ansible localhost -m debug -a "var=hostvars[inventory_hostname]" | grep redis
Configuration Precedence¶
Understanding precedence (lowest to highest):
- Role defaults (
roles/*/defaults/main.yml) - Inventory group_vars (
group_vars/all.yml) - Inventory host_vars (
host_vars/hostname.yml) - Extra variables (
-eflag) - Task-level variables
Best Practices¶
- Use Inventory for Persistent Settings
- Store long-term configuration in inventory files
-
Keep in version control
-
Use Extra Variables for Overrides
- Use
-efor one-time changes -
Good for testing different configurations
-
Use Environment Variables for Secrets
- Never commit passwords to version control
-
Use
lookup('env', 'VAR_NAME') -
Document Configuration
- Add comments explaining why settings were chosen
-
Document dependencies between services
-
Validate Configuration
- Add assertion tasks for critical settings
-
Fail fast on invalid configuration
-
Test Configuration Changes
- Deploy to test environment first
- Verify services work as expected
Example: Complete Test Environment¶
# test-environment.yml
---
# Common settings
all:
vars:
ansible_user: testuser
ansible_connection: local
ansible_host: localhost
# Services
redis_state: present
redis_port: 6379
redis_password: "{{ lookup('env', 'REDIS_PASSWORD') }}"
redis_maxmemory: "256mb"
elasticsearch_state: present
elasticsearch_port: 9200
elasticsearch_password: "{{ lookup('env', 'ES_PASSWORD') }}"
elasticsearch_memory: "1g"
mattermost_state: present
mattermost_port: 8065
mattermost_postgres_password: "{{ lookup('env', 'MM_DB_PASSWORD') }}"
vault_state: present
vault_api_port: 8200
vault_enable_ui: true
Deploy: