2

I am writing an Ansible playbook to deploy services to a clustered environment. There are 3 types of hosts (Application, Load balancer, database). Services are deployed via docker-compose on each host separately.

Example of playbook to deploy to a database host.

- name:           Deploy database node.
  hosts:          databases
  become:         yes
  become_method:  sudo

  roles:
  - common
  - zabbix-agent
  - database
  - backup

The Ansible play needs to dynamically generate a docker-compose file based on which roles have been invoked on that host. So this example would need to generate a docker-compose which lists these roles.

How do i programmatically generate a docker-compose.yml file, based on which roles have been invoked?

I have considered:

  • Ansible facts
  • Tags
  • global boolean variables [yuck] but none of these seems like the right way to me.

If there is a better approach to achieving my objective I'm open to any other suggestions too.

Edit:

Can you explain what is in the container here?

'common' role currently installs Docker and docker-compose onto the target host. 'database' starts a mariadb container. 'zabbix-agent' installs..well, zabbix agent on the host. 'backup' copies some shell scripts over.

Is the database in the container, or is the container running next to the database?

the database is a mariadb Docker container. So my compose file will need to include a 'mariadb' section.

What would a good docker-compose.yml look like for you?

Good question. Something like this:

version:                            '2.2'
services:

  terracotta:
    image:                          terracotta/terracotta-server-oss:5.5.1
    container_name:                 terracotta
    restart:                        always
    networks:
      - skyNet
    logging:
      driver:                       "json-file"
      options:
        max-size:                   "10m"
        max-file:                   "5"

  mariadb:
    image:                          mariadb/server:{{docker_mariadb_version}}
    container_name:                 mariadb
    restart:                        always        
    logging:
      driver:                       "json-file"
      options:
        max-size:                   "10m"
        max-file:                   "5"
    networks:
      - skyNet
    ports:
    - 127.0.0.1:3306:3306/tcp
    volumes:
      - /opt/mariadb/data:/var/lib/mysql
    environment:
      MARIADB_ROOT_PASSWORD:        "{{database_root_password}}"


# Network
networks:
  skyNet:
    driver:                         bridge

I need to be able to need to be able to toggle which services are added to the compose file via Tags or something. Maybe I should change the phrasing of my question?

1
  • 4
    Can you explain what is in the container here? Is the database in the container, or is the container running next to the database? What would a good docker-compose.yml look like for you? Oct 31, 2019 at 13:08

1 Answer 1

0

How do i programmatically generate a docker-compose.yml file, based on which roles have been invoked?

Reading your question, I don't think you need to do that. You're already deploying things on an explicit network; just make this external to the individual compose files. That is, perform the equivalent of:

docker network create skyNet

And then modify your compose configuration to reference that as an external network:

services:

  mariadb:
    image:                          mariadb/server:{{docker_mariadb_version}}
    container_name:                 mariadb
    restart:                        always        
    logging:
      driver:                       "json-file"
      options:
        max-size:                   "10m"
        max-file:                   "5"
    networks:
      - skyNet
    ports:
    - 127.0.0.1:3306:3306/tcp
    volumes:
      - /opt/mariadb/data:/var/lib/mysql
    environment:
      MARIADB_ROOT_PASSWORD:        "{{database_root_password}}"

networks:
  skyNet:
    external: true

You can have each role manage it's own docker-compose.yaml file (and be responsible for bring up the stack). Because you're sharing a network between them, name lookups will work as expected between services, even though they're defined in different files.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.