Jelajahi Sumber

add docker role

Blaine Story 3 tahun lalu
induk
melakukan
b5f6cf74a2

+ 29 - 0
roles/docker/.travis.yml

@@ -0,0 +1,29 @@
+---
+language: python
+python: "2.7"
+
+# Use the new container infrastructure
+sudo: false
+
+# Install ansible
+addons:
+  apt:
+    packages:
+    - python-pip
+
+install:
+  # Install ansible
+  - pip install ansible
+
+  # Check ansible version
+  - ansible --version
+
+  # Create ansible.cfg with correct roles_path
+  - printf '[defaults]\nroles_path=../' >ansible.cfg
+
+script:
+  # Basic role syntax check
+  - ansible-playbook tests/test.yml -i tests/inventory --syntax-check
+
+notifications:
+  webhooks: https://galaxy.ansible.com/api/v1/notifications/

+ 38 - 0
roles/docker/README.md

@@ -0,0 +1,38 @@
+Role Name
+=========
+
+A brief description of the role goes here.
+
+Requirements
+------------
+
+Any pre-requisites that may not be covered by Ansible itself or the role should be mentioned here. For instance, if the role uses the EC2 module, it may be a good idea to mention in this section that the boto package is required.
+
+Role Variables
+--------------
+
+A description of the settable variables for this role should go here, including any variables that are in defaults/main.yml, vars/main.yml, and any variables that can/should be set via parameters to the role. Any variables that are read from other roles and/or the global scope (ie. hostvars, group vars, etc.) should be mentioned here as well.
+
+Dependencies
+------------
+
+A list of other roles hosted on Galaxy should go here, plus any details in regards to parameters that may need to be set for other roles, or variables that are used from other roles.
+
+Example Playbook
+----------------
+
+Including an example of how to use your role (for instance, with variables passed in as parameters) is always nice for users too:
+
+    - hosts: servers
+      roles:
+         - { role: username.rolename, x: 42 }
+
+License
+-------
+
+BSD
+
+Author Information
+------------------
+
+An optional section for the role authors to include contact information, or a website (HTML is not allowed).

+ 8 - 0
roles/docker/defaults/main.yml

@@ -0,0 +1,8 @@
+---
+container_user: containers
+container_uid: 1001
+
+container_group: containers
+container_gid: 1001
+
+containers: []

+ 15 - 0
roles/docker/handlers/main.yml

@@ -0,0 +1,15 @@
+---
+- name: Apply SELinux contexts
+  shell:
+    cmd: restorecon -r "{{ item }}"
+  with_items:
+    - "{{ persistent_container_dirs }}"
+
+- name: Refresh systemd service files
+  systemd:
+    daemon_reload: yes 
+
+#- name: Restart fail2ban
+#  systemd:
+#    name: fail2ban
+#    state: restarted

+ 112 - 0
roles/docker/tasks/main.yml

@@ -0,0 +1,112 @@
+---
+- name: Install docker packages
+  dnf:
+    name:
+      - moby-engine
+      - docker-compose
+    state: present
+
+- name: Start/enable docker service
+  systemd:
+    name: docker
+    state: started
+    enabled: yes
+
+- name: Create docker service folders
+  file:
+    path: /root/docker/{{ item }}
+    state: directory
+    owner: root
+    group: root
+    mode: '0750'
+  with_items:
+    - "{{ containers | map(attribute='service_name') | flatten }}"
+
+- name: Create docker networks
+  docker_network:
+    name: "{{ item.name }}"
+    ipam_config:
+      - subnet: "{{ item.subnet }}"
+        gateway: "{{ item.gateway }}"
+        iprange: "{{ item.ip_range }}"
+    state: present
+  with_items:
+    - "{{ container_networks }}"
+  when:
+    - container_networks is defined
+  loop_control:
+    label: "{{ item.name }}"
+
+- name: Write docker compose file
+  template:
+    src: docker-compose.yml.j2
+    dest: /root/docker/{{ item }}/docker-compose.yml
+    owner: root
+    group: root
+    mode: '0640'
+  with_items:
+    - "{{ containers | map(attribute='service_name') | flatten }}"
+
+- name: Create container group
+  group:
+    name: "{{ container_group }}"
+    gid: "{{ container_gid }}"
+
+- name: Create container user
+  user:
+    name: "{{ container_user }}"
+    uid: "{{ container_uid }}"
+    group: "{{ container_group }}"
+
+- name: Generate list of persistent container directories
+  set_fact:
+    persistent_container_dirs: "{{ containers | map(attribute='volumes') | flatten | map('regex_replace', ':.*' ) | list }}"
+  changed_when: false
+
+- name: Create persistent container directories
+  file:
+    path: "{{ item }}"
+    state: directory
+    owner: "{{ container_user }}"
+    group: "{{ container_group }}"
+    mode: '0770'
+  with_items:
+    - "{{ persistent_container_dirs }}"
+
+- name: Modify SELinux contexts for container directories
+  sefcontext:
+    target: '{{ item }}(/.*)?'
+    setype: container_file_t
+    state: present
+  with_items:
+    - "{{ persistent_container_dirs }}"
+  notify: Apply SELinux contexts
+
+- name: Copy systemd service file
+  template:
+    src: service.j2
+    dest: /etc/systemd/system/{{ item }}.service
+    owner: root
+    group: root
+    mode: '0640'
+  notify: Refresh systemd service files
+  with_items:
+    - "{{ containers | map(attribute='service_name') | flatten }}"
+
+- meta: flush_handlers
+
+- name: Open up firewall ports
+  firewalld:
+    port: "{{ item }}"
+    permanent: yes
+    state: enabled
+  with_items:
+    - "{{ firewall_ports }}"
+
+- name: Start/enable services
+  systemd:
+    name: "{{ item }}"
+    enabled: yes
+    state: started
+  with_items:
+    - "{{ containers | map(attribute='service_name') | flatten }}"

+ 122 - 0
roles/docker/templates/docker-compose.yml.j2

@@ -0,0 +1,122 @@
+# {{ ansible_managed }}
+---
+version: "{{ compose_schema_version | default('3') }}"
+services:
+{% for container in containers %}
+{% if container.active and container.service_name == item %}
+  {{ container.service_name }}:
+    image: {{ container.image }}
+    container_name: {{ container.container_name | default(container.service_name) }}
+{% if container.extra_hosts is defined %}
+    extra_hosts:
+{% for host in container.extra_hosts %}
+      - {{ host }}
+{% endfor %}
+{% endif %}
+{% if container.network_mode is defined %}
+    network_mode: {{ container.network_mode }}
+{% endif %}
+{% if container.privileged is defined %}
+    privileged: {{ container.privileged }}
+{% endif %}
+{% if container.cap_add is defined %}
+    cap_add: 
+{% for cap in container.cap_add %}
+      - {{ cap }}
+{% endfor %}
+{% endif %}
+{% if container.devices is defined %}
+    devices:
+{% for device in container.devices %}
+      - {{ device }}
+{% endfor %}
+{% endif %}
+{% if container.volumes is defined %}
+    volumes:
+{% for volume in container.volumes %}
+      - {{ volume }}
+{% endfor %}
+{% endif %}
+{% if container.labels is defined %}
+    labels:
+{% for label in container.labels %}
+      - {{ label }}
+{% endfor %}
+{% endif %}
+{% if container.ports is defined %}
+    ports:
+{% for port in container.ports %}
+      - {{ port }}
+{% endfor %}
+{% endif %}
+{% if ( container.environment is defined ) or ( container.include_global_env_vars is defined and container.include_global_env_vars) %}
+    environment:
+{% if container.include_global_env_vars | default(false) %}
+{% for global_var in global_env_vars %}
+      - {{ global_var }}
+{% endfor %}
+{% endif %}
+{% if container.environment is defined %}
+{% for env_var in container.environment %}
+      - {{ env_var }}
+{% endfor %}
+{% endif %}
+{% endif %}
+{% if container.depends_on is defined %}
+    depends_on:
+{% for dependent in container.depends_on %}
+      - {{ dependent }}
+{% endfor %}
+{% endif %}
+{% if container.hostname is defined %}
+    hostname: {{ container.hostname }}
+{% endif %}
+{% if container.mem_limit is defined %}
+    mem_limit: {{ container.mem_limit }}
+{% endif %}
+{% if container.command is defined %}
+    command:
+{% for command in container.command %}
+      - {{ command }}
+{% endfor %}
+{% endif %}
+{% if container.security_opt is defined %}
+    security_opt:
+{% for sec_opt in container.security_opt %}
+      - {{ sec_opt }}
+{% endfor %}
+{% endif %}
+{% if container.sysctl is defined %}
+    sysctls:
+{% for param in container.sysctl %}
+      - {{ param }}
+{% endfor %}
+{% endif %}
+{% if container.shm_size is defined %}
+    shm_size: {{ container.shm_size }}
+{% endif %}
+{% if container.dns is defined %}
+    dns:
+{% for dns_entry in container.dns %}
+      - {{ dns_entry }}
+{% endfor %}
+{% endif %}
+{% if container.restart is defined %}
+    restart: {{ container.restart }}
+{% endif %}
+{% endif %}
+{% if container.networks is defined and container.service_name == item %}
+    networks:
+{% for network in container.networks %}
+      - {{ network }}
+{% endfor %}
+{% endif %}
+{% endfor %}
+
+{% if container_networks is defined %}
+networks:
+{% for network in container_networks %}
+  {{ network.name }}:
+    external: true
+{% endfor %}
+{% endif %}

+ 19 - 0
roles/docker/templates/service.j2

@@ -0,0 +1,19 @@
+# {{ ansible_managed }}
+[Unit]
+Description=systemd wrapper around docker {{ item }} service
+Requires=docker.service
+After=docker.service
+
+[Service]
+Restart=always
+User=root
+Group=docker
+
+ExecStartPre=/usr/bin/docker-compose -f /root/docker/{{ item }}/docker-compose.yml down -v
+ExecStartPre=/usr/bin/docker-compose -f /root/docker/{{ item }}/docker-compose.yml pull
+ExecStart=/usr/bin/docker-compose -f /root/docker/{{ item }}/docker-compose.yml up
+#ExecStartPost=/usr/bin/docker system prune -f # caused custom bridged network to be deleted before container got going
+ExecStop=/usr/bin/docker-compose -f /root/docker/{{ item }}/docker-compose.yml down -v
+
+[Install]
+WantedBy=multi-user.target