Terraform deploy on hetzner cloud

This commit is contained in:
norimicry 2019-04-13 02:06:51 +02:00
parent 979d0ed0ee
commit 1b943fbf3e
24 changed files with 1189 additions and 2 deletions

View File

@ -1,10 +1,44 @@
---
- name: Example
- name: Stardew
hosts: "all"
become: true
roles:
- role: "nickjj.docker"
tags: ["docker"]
- role "stardew"
tasks:
- name: Creates directory
file:
path: /var/docker/stardew
state: directory
- name: "Copy Shit over"
copy:
src: ./docker-compose.yml
dest: /var/docker/stardew/docker-compose.yml
- name: "Copy Shit over"
copy:
src: ./asound.conf
dest: /var/docker/stardew/asound.conf
- name: "Copy Shit over"
copy:
src: ./init.sh
dest: /var/docker/stardew/init.sh
- name: "Copy Shit over"
copy:
src: ./Dockerfile
dest: /var/docker/stardew/Dockerfile
- name: "Copy Shit over"
copy:
src: ./config
dest: /var/docker/stardew/config
- name: Pip install docker for Ansible's docker_login and docker_service modules
pip:
name: ["docker", "docker-compose"]
- name: "Start docker-compose"
docker_service:
project_src: "/var/docker/stardew"
pull: yes

23
roles/nickjj.docker/.gitignore vendored Executable file
View File

@ -0,0 +1,23 @@
.DS_Store
*/**.DS_Store
._*
.*.sw*
*~
.idea/
.vscode/
*.retry
__pycache__/
*.py[cod]
*$py.class
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/

16
roles/nickjj.docker/.travis.yml Executable file
View File

@ -0,0 +1,16 @@
---
services: "docker"
env:
- distro: "ubuntu1604"
- distro: "ubuntu1804"
- distro: "debian9"
script:
# Download test shim.
- wget -O ${PWD}/tests/test.sh https://gist.githubusercontent.com/nickjj/d12353b5b601e33cd62fda111359957a/raw
- chmod +x ${PWD}/tests/test.sh
# Run tests.
- ${PWD}/tests/test.sh

190
roles/nickjj.docker/CHANGELOG.md Executable file
View File

@ -0,0 +1,190 @@
# Changelog
## v1.8.0
*Released: December 19th 2018*
- Change `docker__apt_key_server` to `docker__apt_key_url`
- `docker__version` and `docker__compose_version` are back to being empty strings by default
## v1.7.0
*Released: December 18th 2018*
- `docker__version` and `docker__compose_version` are now both undefined by default
- Change `docker__users` to default to `docker__users: ["{{ ansible_env.SUDO_USER | d('root') }}"]`
- Check for an existing Docker Compose file before trying to symlink it
## v1.6.0
*Released: December 15th 2018*
### Features
- Docker and Docker Compose can now be installed to their latest versions by default
- A Virtualenv will be created for any PIP packages that get installed
- The `docker-compose` package is installed through PIP (complete with latest / version pinning)
- The `docker` package is installed through PIP (all of Ansible's `docker_*` modules now work)
- Symlinks are created to put `docker-compose` and `python-docker` on the system's path
- Better documentation to demonstrate how to downgrade / upgrade Docker versions
- Docker login's config path can now be configured
- Overall improved documentation and tests
### Variables
- Remove `python-pip` from `docker__package_dependencies`
- Remove `docker__install_docker_compose`
- Remove `docker__compose_download_url`
- Remove `docker__default_daemon_json_log_max_size`
- Remove `docker__default_daemon_json_log_max_file`
- Add `docker__state` to control the Docker APT package's state
- Add `docker__pip_dependencies` to install various APT dependencies to run PIP
- Add `docker__pip_virtualenv` to create a Virtualenv for PIP
- Add `docker__default_pip_packages` to install default PIP packages
- Add `docker__pip_packages` to install additional PIP packages
- Add `docker__pip_docker_compose_state` to control the Docker Compose PIP package's state
- Add `docker__pip_docker_state` to control the Docker PIP package's state
- Add `config_path` property to the `docker__registries` list
- Add `docker__cron_jobs_prune_flags` to configure which prune flags get set
- Change `docker__default_daemon_json` to log to journald by default
- Change `docker__channel` from being a string to a list
## v1.5.0
*Released: November 11th 2018*
- Rename `docker__install_docker__compose` to `docker__install_docker_compose`
- Bump Docker Compose version to 1.23
- Change systemd options to use `-H unix://` to be compatible with 18.09 by default
- Install `python-pip` apt package as a dependency for pip installing `docker`
- Pip install `docker` so Ansible's `docker_login` and `docker_service` modules work
- Remove unnecessary "Remove Upstart config file" task
- Remove unnecessary "Install Python for managing Docker login credentials" task
- Remove unnecessary `enabled: true` in the systemd restart handler (it starts on boot by default)
## v1.4.0
*Released: October 31st 2018*
- Rename `docker__daemon_options` to `docker__daemon_json`
- Rename `docker__daemon_options_log_max_size` to `docker__default_daemon_json_log_max_size`
- Rename `docker__daemon_options_log_max_file` to `docker__default_daemon_json_log_max_file`
- Add `docker__daemon_flags` for setting systemd unit file Docker daemon options
- Add `docker__systemd_override` for setting custom systemd directives for the Docker service
- Rename `docker__cron_tasks` to `docker__cron_jobs`
- `cron_file` can now be configured with cron jobs to write out cron jobs in `/etc/cron.d`
- Add `user` to cron jobs since we're now using `cron_file`
- Drastically improve documentation
## v1.3.0
*Released: October 21st 2018*
- Variables are now using the `docker__*` style instead of `docker_*`
- Add configuration value for Docker Compose download URL
- Make style changes based on yamllint and ansible-lint
## v1.2.0
*Released: October 11th 2018*
- Remove ability to remove the `docker-*` package
- Add documentation on how to remove Docker if you need to downgrade versions
- Let Docker manage its own systemd unit file
- Allow environment configuration using the systemd `docker.service.d/*` pattern
## v1.1.0
*Released: October 9th 2018*
- Add `-H fd://` to the daemon options at the systemd unit file level
- Update systemd unit file as per Docker's latest settings
- Convert to using `/etc/docker/daemon.json` for setting daemon options
- Add variables to configure log size and max number of files
- Default to rotating logs after 10 gigs of space is used (was previously unlimited)
- System prune cron job now sets the `-a` flag to remove unused images
## v1.0.0
*Released: September 19th 2018*
- Update role to be compliant and depend on Ansible 2.5+
- Add official support for Ubuntu 16.04 / 18.04 and Debian Jessie / Stretch
- Default to Docker v18.06
- Default to Docker Compose v1.22
- Default to the stable channel instead of edge
- Add support for configuring 1 or more registries (thanks to @Mykhailo Chalyi for starting this)
- Add ability to remove Docker by setting `docker__remove_package: True`
- Fix APT GPG key issues (thanks to @bidossessi for starting this)
- Add proper version pinning support
- Remove `docker__apt_package_name` because the package name has been simplified thanks to pinning
- Redirect system prune's cron output to `/dev/null`
- Extract Docker's package dependencies into `docker__package_dependencies`
- Add more tests
## v0.2.3
*Released: April 13th 2018*
- Default to Docker v18.04
- Default to Docker Compose v1.21
- Expose `docker__apt_package_name` to customize the APT package name
## v0.2.2
*Released: March 28th 2018*
- Default to Docker v18.03
- Default to Docker Compose v1.20
## v0.2.1
*Released: February 14th 2018*
- Default to Docker v18.02
- Default to Docker Compose v1.19
## v0.2.0
*Released: January 25th 2018*
- Change version strategy to be separate from Docker releases (it was a bad idea!)
- Change `docker__options` to `docker__daemon_options`
- Default to Docker v18.01 on the CE edge channel
- Fix systemd service so Docker loads after `network-online.target` instead of `network.target`
- Add cron job to clean up after Docker
- Add proper tests and support for Ubuntu 16, Debian Stretch and Debian Jessie
- Update format and style consistencies
## v17.12
*Released: January 11th 2018*
- Default to Docker v17.12 on the CE edge channel
- Default to Docker Compose v1.18
## v17.06
*Released: June 28th 2017*
- Default to Docker v17.06 on the CE edge channel
- Default to Docker Compose v1.14
- Update code base to support Docker's new version format
## v0.1.2
*Released: October 9th 2016*
- Fix apt.cache https could not be found error
## v0.1.1
*Released: October 9th 2016*
- Fix issue where `docker-engine` package was not found
## v0.1.0
*Released: October 8th 2016*
- Initial release

22
roles/nickjj.docker/LICENSE Executable file
View File

@ -0,0 +1,22 @@
The MIT License (MIT)
Copyright (c) 2016 Nick Janetakis nick.janetakis@gmail.com
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

397
roles/nickjj.docker/README.md Executable file
View File

@ -0,0 +1,397 @@
## What is ansible-docker? [![Build Status](https://secure.travis-ci.org/nickjj/ansible-docker.png)](http://travis-ci.org/nickjj/ansible-docker)
It is an [Ansible](http://www.ansible.com/home) role to:
- Install Docker (editions, channels and version pinning are all supported)
- Install Docker Compose using PIP (version pinning is supported)
- Install the `docker` PIP package so Ansible's `docker_*` modules work
- Manage Docker registry login credentials
- Configure 1 or more users to run Docker without needing root access
- Configure the Docker daemon's options and environment variables
- Configure a cron job to run Docker clean up commands
## Why would you want to use this role?
If you're like me, you probably love Docker. This role provides everything you
need to get going with a production ready Docker host.
By the way, if you don't know what Docker is, or are looking to become an expert
with it then check out
[Dive into Docker: The Complete Docker Course for Developers](https://diveintodocker.com/?utm_source=ansibledocker&utm_medium=github&utm_campaign=readmetop).
## Supported platforms
- Ubuntu 16.04 LTS (Xenial)
- Ubuntu 18.04 LTS (Bionic)
- Debian 9 (Stretch)
---
*You are viewing the master branch's documentation which might be ahead of the
latest release. [Switch to the latest release](https://github.com/nickjj/ansible-docker/tree/v1.8.0).*
---
## Quick start
The philosophy for all of my roles is to make it easy to get going, but provide
a way to customize nearly everything.
### What's configured by default?
The latest Docker CE and Docker Compose will be installed, Docker disk clean up
will happen once a week and Docker container logs will be sent to `journald`.
### Example playbook
```yml
---
# site.yml
- name: Example
hosts: "all"
become: true
roles:
- role: "nickjj.docker"
tags: ["docker"]
```
Usage: `ansible-playbook site.yml -t docker`
### Installation
`$ ansible-galaxy install nickjj.docker`
## Default role variables
### Installing Docker
#### Edition
Do you want to use "ce" (community edition) or "ee" (enterprise edition)?
```yml
docker__edition: "ce"
```
#### Channel
Do you want to use the "stable", "edge", "testing" or "nightly" channels? You
can add more than one (order matters).
```yml
docker__channel: ["stable"]
```
#### Version
- When set to "", the current latest version of Docker will be installed
- When set to a specific version, that version of Docker will be installed and pinned
```yml
docker__version: ""
# For example, pin it to 18.06.
docker__version: "18.06"
# For example, pin it to a more precise version of 18.06.
docker__version: "18.06.1"
```
*Pins are set with `*` at the end of the package version so you will end up
getting minor and security patches unless you pin an exact version.*
##### Upgrade strategy
- When set to `"present"`, running this role in the future won't install newer
versions (if available)
- When set to `"latest"`, running this role in the future will install newer
versions (if available)
```yml
docker__state: "present"
```
##### Downgrade strategy
The easiest way to downgrade would be to uninstall the Docker package manually
and then run this role afterwards while pinning whatever specific Docker version
you want.
```sh
# An ad-hoc Ansible command to stop and remove the Docker CE package on all hosts.
ansible all -m systemd -a "name=docker-ce state=stopped" \
-m apt -a "name=docker-ce autoremove=true purge=true state=absent" -b
```
### Installing Docker Compose
Docker Compose will get PIP installed inside of a Virtualenv. This is covered
in detail in another section of this README file.
#### Version
- When set to "", the current latest version of Docker Compose will be installed
- When set to a specific version, that version of Docker Compose will be installed
and pinned
```yml
docker__compose_version: ""
# For example, pin it to 1.23.
docker__compose_version: "1.23"
# For example, pin it to a more precise version of 1.23.
docker__compose_version: "1.23.2"
```
*Upgrade and downgrade strategies will be explained in the other section of this
README.*
### Configuring users to run Docker without root
A list of users to be added to the `docker` group.
Keep in mind this user needs to already exist, this role will not create it. If
you want to create users, check out my
[user role](https://github.com/nickjj/ansible-user).
This role does not configure User Namespaces or any other security features
by default. If the user you add here has SSH access to your server then you're
effectively giving them root access to the server since they can run Docker
without `sudo` and volume mount in any path on your file system.
In a controlled environment this is safe, but like anything security related
it's worth knowing this up front. You can enable User Namespaces and any
other options with the `docker__daemon_json` variable which is explained later.
```yml
# Try to use the sudo user by default, but fall back to root.
docker__users: ["{{ ansible_env.SUDO_USER | d('root') }}"]
# For example, if the user you want to set is different than the sudo user.
docker__users: ["admin"]
```
### Configuring Docker registry logins
Login to 1 or more Docker registries (such as the
[Docker Hub](https://hub.docker.com/)).
```yml
docker__registries:
- #registry_url: "https://index.docker.io/v1/"
username: "your_docker_hub_username"
password: "your_docker_hub_password"
#email: "your_docker_hub@emailaddress.com"
#reauthorize: false
#config_path: "$HOME/.docker/config.json"
#state: "present"
docker__registries: []
```
*Properties prefixed with \* are required.*
- `registry_url` defaults to `https://index.docker.io/v1/`
- *`username` is your Docker registry username
- *`password` is your Docker registry password
- `email` defaults to not being used (not all registries use it)
- `reauthorize` defaults to `false`, when `true` it updates your credentials
- `config_path` defaults to `(ansible_env.PWD | d('/root')) + '/.docker/config.json'`
- `state` defaults to "present", when "absent" the login will be removed
### Configuring the Docker daemon options (json)
Default Docker daemon options as they would appear in `/etc/docker/daemon.json`.
```yml
docker__default_daemon_json: |
"log-driver": "journald"
# Add your own additional daemon options without overriding the default options.
# It follows the same format as the default options, and don't worry about
# starting it off with a comma. The template will add the comma if needed.
docker__daemon_json: ""
```
### Configure the Docker daemon options (flags)
Flags that are set when starting the Docker daemon cannot be changed in the
`daemon.json` file. By default Docker sets `-H unix://` which means that option
cannot be changed with the json options.
Add or change the starting Docker daemon flags by supplying them exactly how
they would appear on the command line.
```yml
# Each command line flag should be its own item in the list.
#
# Using a Docker version prior to 18.09?
# You must set `-H fd://` instead of `-H unix://`.
docker__daemon_flags:
- "-H unix://"
```
*If you don't supply some type of `-H` flag here, Docker will fail to start.*
### Configuring the Docker daemon environment variables
```yml
docker__daemon_environment: []
# For example, here's how to set a couple of proxy environment variables.
docker__daemon_environment:
- "HTTP_PROXY=http://proxy.example.com:80"
- "HTTPS_PROXY=https://proxy.example.com:443"
```
### Configuring advanced systemd directives
This role lets the Docker package manage its own systemd unit file and adjusts
things like the Docker daemon flags and environment variables by using
the systemd override pattern.
If you know what you're doing, you can override or add to any of Docker's systemd
directives by setting this variable. Anything you place in this string will be
written to `/etc/systemd/system/docker.service.d/custom.conf` as is.
```yml
docker__systemd_override: ""
```
### Configuring Docker related cron jobs
By default this will safely clean up disk space used by Docker every Sunday at
midnight.
```yml
# `a` removes unused images (useful in production).
# `f` forces it to happen without prompting you to agree.
docker__cron_jobs_prune_flags: "af"
docker__cron_jobs:
- name: "Docker disk clean up"
job: "docker system prune -{{ docker__cron_jobs_prune_flags }} > /dev/null 2>&1"
schedule: ["0", "0", "*", "*", "0"]
cron_file: "docker-disk-clean-up"
#user: "{{ (docker__users | first) | d('root') }}"
#state: "present"
```
*Properties prefixed with \* are required.*
- *`name` is the cron job's description
- *`job` is the command to run in the cron job
- *`schedule` is the [standard cron job](https://en.wikipedia.org/wiki/Cron#Overview)
format for every Sunday at midnight
- *`cron_file` writes a cron file to `/etc/cron.d` instead of a user's individual crontab
- `user` defaults to the first `docker__users` user or root if that's not available
- `state` defaults to "present", when "absent" the cron file will be removed
### Configuring the APT package manager
Docker requires a few dependencies to be installed for it to work. You shouldn't
have to edit any of these variables.
```yml
# List of packages to be installed.
docker__package_dependencies:
- "apt-transport-https"
- "ca-certificates"
- "cron"
- "gnupg2"
- "software-properties-common"
# The Docker PGP key id used to sign the Docker package.
docker__apt_key_id: "9DC858229FC7DD38854AE2D88D81803C0EBFCD88"
# The Docker PGP key server address.
docker__apt_key_url: "https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg"
# The Docker upstream APT repository.
docker__apt_repository: >
deb [arch=amd64]
https://download.docker.com/linux/{{ ansible_distribution | lower }}
{{ ansible_distribution_release }} {{ docker__channel | join (' ') }}
```
### Installing Python packages with Virtualenv and PIP
#### Configuring Virtualenv
Rather than pollute your server's version of Python, all PIP packages are
installed into a Virtualenv of your choosing.
```yml
docker__pip_virtualenv: "/usr/local/lib/docker/virtualenv"
```
#### Installing PIP and its dependencies
This role installs PIP because Docker Compose is installed with the
`docker-compose` PIP package and Ansible's `docker_*` modules use the `docker`
PIP package.
```yml
# This will attempt to install the correct version of PIP based on what your
# configured Ansible Python interpreter is set to (ie. Python 2 or 3).
docker__pip_dependencies:
- "python-setuptools"
- "python{{ '3' if ansible_python.version.major == 3 else '' }}-pip"
```
#### Installing PIP packages
```yml
docker__default_pip_packages:
- name: "docker"
state: "{{ docker__pip_docker_state }}"
- name: "docker-compose"
version: "{{ docker__compose_version }}"
path: "/usr/local/bin/docker-compose"
src: "{{ docker__pip_virtualenv + '/bin/docker-compose' }}"
state: "{{ docker__pip_docker_compose_state }}"
# Add your own PIP packages with the same properties as above.
docker__pip_packages: []
```
*Properties prefixed with \* are required.*
- *`name` is the package name
- `version` is the package version to be installed (or "" if this is not defined)
- `path` is the destination path of the symlink
- `src` is the source path to be symlinked
- `state` defaults to "present", other values can be "forcereinstall" or "absent"
##### PIP package state
- When set to `"present"`, the package will be installed but not updated on
future runs
- When set to `"forcereinstall"`, the package will always be (re)installed and
updated on future runs
- When set to `"absent"`, the package will be removed
```yml
docker__pip_docker_state: "present"
docker__pip_docker_compose_state: "present"
```
#### Working with Ansible's `docker_*` modules
This role uses `docker_login` to login to a Docker registry, but you may also
use the other `docker_*` modules in your own roles. They are not going to work
unless you instruct Ansible to use this role's Virtualenv.
At either the inventory, playbook or task level you'll need to set
`ansible_python_interpreter: "/usr/bin/env python-docker"`. This works because
this role symlinks the Virtualenv's Python binary to `python-docker`.
You can look at this role's `docker_login` task as an example on how to do it
at the task level.
## License
MIT

View File

@ -0,0 +1,65 @@
---
docker__edition: "ce"
docker__channel: ["stable"]
docker__version: ""
docker__state: "present"
docker__compose_version: ""
docker__users: ["{{ ansible_env.SUDO_USER | d('root') }}"]
docker__registries: []
docker__default_daemon_json: |
"log-driver": "journald"
docker__daemon_json: ""
docker__daemon_flags:
- "-H unix://"
docker__daemon_environment: []
docker__systemd_override: ""
docker__cron_jobs_prune_flags: "af"
docker__cron_jobs:
- name: "Docker disk clean up"
job: "docker system prune -{{ docker__cron_jobs_prune_flags }} > /dev/null 2>&1"
schedule: ["0", "0", "*", "*", "0"]
cron_file: "docker-disk-clean-up"
user: "{{ (docker__users | first) | d('root') }}"
docker__package_dependencies:
- "apt-transport-https"
- "ca-certificates"
- "cron"
- "gnupg2"
- "software-properties-common"
docker__apt_key_id: "9DC858229FC7DD38854AE2D88D81803C0EBFCD88"
docker__apt_key_url: "https://download.docker.com/linux/{{ ansible_distribution | lower }}/gpg"
docker__apt_repository: >
deb [arch=amd64]
https://download.docker.com/linux/{{ ansible_distribution | lower }}
{{ ansible_distribution_release }} {{ docker__channel | join (' ') }}
docker__pip_dependencies:
- "python-setuptools"
- "python{{ '3' if ansible_python.version.major == 3 else '' }}-pip"
docker__pip_virtualenv: "/usr/local/lib/docker/virtualenv"
docker__default_pip_packages:
- name: "docker"
state: "{{ docker__pip_docker_state }}"
- name: "docker-compose"
version: "{{ docker__compose_version }}"
path: "/usr/local/bin/docker-compose"
src: "{{ docker__pip_virtualenv + '/bin/docker-compose' }}"
state: "{{ docker__pip_docker_compose_state }}"
docker__pip_packages: []
docker__pip_docker_state: "present"
docker__pip_docker_compose_state: "present"

View File

@ -0,0 +1,6 @@
---
- name: Restart Docker
systemd:
name: "docker"
state: "restarted"

View File

@ -0,0 +1 @@
{install_date: 'Fri Apr 12 21:50:33 2019', version: v1.8.0}

View File

@ -0,0 +1,26 @@
---
galaxy_info:
role_name: "docker"
author: "Nick Janetakis"
description: "Install and configure Docker / Docker Compose."
license: "MIT"
min_ansible_version: 2.5
platforms:
- name: "Ubuntu"
versions:
- "xenial"
- "bionic"
- name: "Debian"
versions:
- "stretch"
galaxy_tags:
- "containers"
- "compose"
- "docker"
- "packaging"
- "system"
dependencies: []

View File

@ -0,0 +1,193 @@
---
- name: Disable pinned Docker version
file:
dest: "/etc/apt/preferences.d/docker-ce.pref"
state: "absent"
when: not docker__version | d()
- name: Enable pinned Docker version
template:
src: "etc/apt/preferences.d/docker-ce.pref.j2"
dest: "/etc/apt/preferences.d/docker-ce.pref"
owner: "root"
group: "root"
mode: "0644"
when: docker__version | d()
- name: Install Docker's dependencies
apt:
name: "{{ docker__package_dependencies + docker__pip_dependencies }}"
- name: Add Docker's public PGP key to the APT keyring
apt_key:
id: "{{ docker__apt_key_id }}"
url: "{{ docker__apt_key_url }}"
- name: Configure Docker's upstream APT repository
apt_repository:
repo: "{{ docker__apt_repository }}"
update_cache: true
- name: Install Docker
apt:
name: "docker-{{ docker__edition }}"
state: "{{ docker__state }}"
- name: Check for existing Docker Compose file
stat:
path: "/usr/local/bin/docker-compose"
register: docker__register_docker_compose
- name: Remove Docker Compose if it's been installed without PIP
file:
path: "/usr/local/bin/docker-compose"
state: "absent"
when:
- docker__register_docker_compose.stat.exists
- docker__register_docker_compose.stat.isreg | d(false)
- name: Install Virtualenv
pip:
name: "virtualenv"
- name: Install Python packages
pip:
name: >
{{ item.name }}{% if item.version | d() %}=={{ item.version }}{% endif %}
virtualenv: "{{ docker__pip_virtualenv }}"
state: "{{ item.state | d('present') }}"
loop: "{{ docker__default_pip_packages + docker__pip_packages }}"
when: item.name | d()
- name: Symlink Python binary to /usr/local/bin/python-docker
file:
path: "/usr/local/bin/python-docker"
src: "{{ docker__pip_virtualenv }}/bin/python"
state: "link"
- name: Symlink selected Python package binaries to /usr/local/bin
file:
path: "{{ item.path }}"
src: "{{ item.src }}"
state: "link"
loop: "{{ docker__default_pip_packages + docker__pip_packages }}"
when:
- item.state | d("present") != "absent"
- item.path | d() and item.src | d()
- name: Add user(s) to "docker" group
user:
name: "{{ item }}"
groups: "docker"
append: true
loop: "{{ docker__users }}"
- name: Create Docker configuration directories
file:
path: "{{ item }}"
state: "directory"
owner: "root"
group: "root"
mode: "0755"
loop:
- "/etc/docker"
- "/etc/systemd/system/docker.service.d"
- name: Configure Docker daemon options (json)
template:
src: "etc/docker/daemon.json.j2"
dest: "/etc/docker/daemon.json"
owner: "root"
group: "root"
mode: "0644"
when: docker__default_daemon_json or docker__daemon_json
notify: ["Restart Docker"]
- name: Configure Docker daemon options (flags)
template:
src: "etc/systemd/system/docker.service.d/options.conf.j2"
dest: "/etc/systemd/system/docker.service.d/options.conf"
owner: "root"
group: "root"
mode: "0644"
register: docker__register_daemon_flags
when: docker__daemon_flags
notify: ["Restart Docker"]
- name: Configure Docker daemon environment variables
template:
src: "etc/systemd/system/docker.service.d/environment.conf.j2"
dest: "/etc/systemd/system/docker.service.d/environment.conf"
owner: "root"
group: "root"
mode: "0644"
register: docker__register_daemon_environment
when: docker__daemon_environment
notify: ["Restart Docker"]
- name: Configure custom systemd unit file override
template:
src: "etc/systemd/system/docker.service.d/custom.conf.j2"
dest: "/etc/systemd/system/docker.service.d/custom.conf"
owner: "root"
group: "root"
mode: "0644"
register: docker__register_custom_override
when: docker__systemd_override | d()
notify: ["Restart Docker"]
- name: Reload systemd daemon
systemd:
daemon_reload: true
when: (docker__register_daemon_flags | d() and
docker__register_daemon_flags is changed)
or (docker__register_daemon_environment | d() and
docker__register_daemon_environment is changed)
or (docker__register_custom_override | d() and
docker__register_custom_override is changed)
notify: ["Restart Docker"]
- name: Restart Docker now to make sure `docker login` works
meta: "flush_handlers"
- name: Manage Docker registry login credentials
docker_login:
registry_url: "{{ item.registry_url | d(omit) }}"
username: "{{ item.username }}"
password: "{{ item.password }}"
email: "{{ item.email | d(omit) }}"
reauthorize: "{{ item.reauthorize | d(omit) }}"
config_path: "{{ item.config_path | d((ansible_env.PWD | d('/root')) + '/.docker/config.json') }}"
state: "{{ item.state | d('present') }}"
loop: "{{ docker__registries }}"
when: item.username | d() and item.password | d()
vars:
ansible_python_interpreter: "{{ '/usr/bin/env python-docker' if docker__pip_virtualenv | d() else ansible_python.executable }}"
- name: Remove Docker related cron jobs
file:
path: "/etc/cron.d/{{ item.cron_file }}"
state: "absent"
loop: "{{ docker__cron_jobs }}"
when:
- item.state | d("present") == "absent"
- item.name | d() and item.job | d()
- item.schedule | d() and item.cron_file | d()
- name: Create Docker related cron jobs
cron:
name: "{{ item.name }}"
job: "{{ item.job }}"
minute: "{{ item.schedule[0] }}"
hour: "{{ item.schedule[1] }}"
day: "{{ item.schedule[2] }}"
month: "{{ item.schedule[3] }}"
weekday: "{{ item.schedule[4] }}"
cron_file: "{{ item.cron_file }}"
user: "{{ item.user | d('root') }}"
loop: "{{ docker__cron_jobs }}"
when:
- item.state | d("present") != "absent"
- item.name | d() and item.job | d()
- item.schedule | d() and item.cron_file | d()

View File

@ -0,0 +1,4 @@
Explanation: Pin added by Ansible role "{{ role_name }}"
Package: docker-ce
Pin: version {{ docker__version }}*
Pin-Priority: 600

View File

@ -0,0 +1,11 @@
{
{%- if docker__default_daemon_json | d() -%}
{{ docker__default_daemon_json | indent(2, true) }}
{%- endif -%}
{%- if (docker__default_daemon_json | d()) and (docker__daemon_json | d()) -%}
,
{%- endif -%}
{%- if docker__daemon_json | d() -%}
{{ docker__daemon_json | indent(2, true) }}
{%- endif -%}
}

View File

@ -0,0 +1,3 @@
# {{ ansible_managed }}
{{ docker__systemd_override }}

View File

@ -0,0 +1,4 @@
# {{ ansible_managed }}
[Service]
Environment="{{ docker__daemon_environment | join('" "') }}"

View File

@ -0,0 +1,5 @@
# {{ ansible_managed }}
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd {{ docker__daemon_flags | join(" ") }}

View File

@ -0,0 +1,5 @@
---
extends: "default"
rules:
line-length: "disable"

View File

@ -0,0 +1,61 @@
import re
def test_docker_version(host):
assert 0 == host.run("docker --version").rc
def test_pinned_docker_version(host):
existing_docker_version = host.check_output("docker --version")
host.run("sudo apt-get update")
host.run("sudo apt-get upgrade")
docker_version_after_apt_update = host.check_output("docker --version")
assert existing_docker_version == docker_version_after_apt_update
def test_able_to_access_docker_without_root(host):
assert "docker" in host.user("test").groups
def test_daemon_json_is_configured(host):
daemon_json = host.file("/etc/docker/daemon.json")
assert daemon_json.contains("journald")
assert daemon_json.contains("8.8.8.8")
def test_customized_environment_systemd_unit_file(host):
unit_file = "/etc/systemd/system/docker.service.d/environment.conf"
file_contents = host.file(unit_file).content_string
assert re.search(r"HTTP_PROXY=.*HTTPS_PROXY=.*", file_contents)
def test_customized_daemon_flags_systemd_unit_file(host):
unit_file = "/etc/systemd/system/docker.service.d/options.conf"
file_contents = host.file(unit_file).content_string
assert "-H fd://" in file_contents
assert "--debug" in file_contents
def test_customized_systemd_override(host):
unit_file = "/etc/systemd/system/docker.service.d/custom.conf"
file_contents = host.file(unit_file).content_string
assert "ATest" in file_contents
def test_docker_compose_is_pip_installed_and_symlinked(host):
assert 0 == host.run("docker-compose --version").rc
def test_python_docker_is_symlinked(host):
assert 0 == host.run("python-docker --version").rc
def test_docker_clean_up_cron_job(host):
cron_conf = host.file("/etc/cron.d/docker-disk-clean-up").content_string
assert "test docker system prune -af" in cron_conf

View File

@ -0,0 +1,41 @@
---
- hosts: "all"
become: true
vars:
docker__version: "18.06"
docker__users: ["test"]
docker__daemon_json: |
"dns": ["8.8.8.8"]
docker__daemon_environment:
- "HTTP_PROXY=http://proxy.a.com:80"
- "HTTPS_PROXY=https://proxy.a.com:443"
docker__daemon_flags:
- "-H fd://"
- "--debug"
docker__systemd_override: |
[Unit]
Invalid=Directive
[Service]
ThisIsJust=ATest
roles:
- role: "role_under_test"
pre_tasks:
- name: Add test user
user:
name: "test"
shell: "/bin/bash"
- name: Run the equivalent of "apt-get update"
apt:
update_cache: true
changed_when: false

9
terra.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/sh
# Generate SSH keys
ssh-keygen -f terraform/ssh/key -q -P ""
# Run Terraform
cd terraform
terraform init
terraform apply

41
terraform/main.tf Normal file
View File

@ -0,0 +1,41 @@
variable "hcloud_token" {}
provider "hcloud" {
token = "${var.hcloud_token}"
}
resource "hcloud_ssh_key" "main" {
name = "main_key"
public_key = "${file("./ssh/key.pub")}"
}
resource "hcloud_server" "game_node" {
name = "game-node"
image = "debian-9"
server_type = "cx11"
ssh_keys = ["${hcloud_ssh_key.main.id}"]
provisioner "remote-exec" {
inline = [
"uname -a",
]
connection {
host = "${self.ipv4_address}"
type = "ssh"
user = "root"
private_key = "${file("./ssh/key")}"
}
}
provisioner "local-exec" {
environment {
PUBLIC_IP = "${self.ipv4_address}"
}
working_dir = "."
command = "ansible-playbook -u root --private-key ./ssh/key ../playbook.yml -i ${self.ipv4_address},"
}
}

27
terraform/ssh/key Normal file
View File

@ -0,0 +1,27 @@
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAABFwAAAAdzc2gtcn
NhAAAAAwEAAQAAAQEAoIp7IVBt+ZsPnPOLmxN/NpDK1m2dugLtdYNgrbbdKYaCYwkfMZuq
SFikUF3sJJSMm7py4pXaFehCxjf+vGyZIxREeLikNRbDkncW8PiWsOpbWM2Ito+/af0jbx
jFndcwoQLnLxNRT3ZtVokKKpMFY921NLPINumDsmDrRKOFNneEFDCdeqiO2uWGinvJSMk8
2ONqSm0Pim78V+kbJuGJ9dW9IzR+BDC13gCwW1bAzri8zK09G1RlQRyzL2cDQ2l/ToEdUa
LXgGLA0tGScWdjjCAkSldPAXlfWtnY0gaOp8EPJ2cf0ReR1UZEhHJBDxxp2RBD5+he135m
8sQ/w7qhQQAAA8Cw0a1CsNGtQgAAAAdzc2gtcnNhAAABAQCginshUG35mw+c84ubE382kM
rWbZ26Au11g2Cttt0phoJjCR8xm6pIWKRQXewklIybunLildoV6ELGN/68bJkjFER4uKQ1
FsOSdxbw+Jaw6ltYzYi2j79p/SNvGMWd1zChAucvE1FPdm1WiQoqkwVj3bU0s8g26YOyYO
tEo4U2d4QUMJ16qI7a5YaKe8lIyTzY42pKbQ+KbvxX6Rsm4Yn11b0jNH4EMLXeALBbVsDO
uLzMrT0bVGVBHLMvZwNDaX9OgR1RoteAYsDS0ZJxZ2OMICRKV08BeV9a2djSBo6nwQ8nZx
/RF5HVRkSEckEPHGnZEEPn6F7XfmbyxD/DuqFBAAAAAwEAAQAAAQEAgXAl5q5afS2wYPNc
VCRcJTqI0GqBCUDjBCRxBp6xopF4/zCTngPMP5h4ovOXOccrt0OU7Wu08oTZkcgD8xf8QH
RO4Ka+fq9j7+tk69UCapIKJIdS+x7bTjFzKFfovWKLKsaUbzg8Dr2FWogTUlBHwEU5nMx3
WQ7dyCyshCLzfP2I7HX/Mm2waAOQ6xaavaelfigXoOZxJ/Vm4wqerj3Sv5FDmeyNaClAfY
xBW8HRunAyS+dYEEcvk4P0PtSbgD6nV2e0I78OxXyQgBqNfta0I7aYIRjc7aJYbF+qQCIW
2cYZMjX/juTzESFY0z1dV6FyCiV2IS9URpINfOoaTYlFoQAAAIEAo+2rDZMwOsPs9N7yN4
g0bS5htLTXIvpPFOO09LxXtQfZ4UxZqYD440Rww2L6xvcqXrMAEla9qbcAxLB27AcdMuIL
bJ0yMpoy3RHxGcnmoPmhrUX3Dl5uR4X1eReHxMwVoxuZAv9uloVfweqUYT3gEnhkBPDWtF
Tu+lwjzm6mlOwAAACBAMyRh3SsiB1e9of97PqcSW4TYMCvCa8vScN/6HT/0IfErbmawOQ8
dlqjD+t+V9PKDgmXX/KDvkkzPxA82ysItWk0JdoYHU2EKlrZ3YK1HDpvvj2EOt1h24QtuR
s9goGdRXYiKJ3Gn5QM0LPF/ErVQq9eNOaXErmgWRPu/H0vh/4PAAAAgQDI5z6ORd3rgc49
Jow4lIjwgIgtTbm4bFKJTeYNZq+kcqOFl1WG/4v1kozurwNHa9UoC5b9qIcIgbyTn9Taua
CN1mDxY4U3fC9Mwb8XF8g4SuEghorWcRI3+Gp3Re5ow33ylwTTpIMRGBYr1VZLFTrFjCVG
kjGXxsETOSccHOG7rwAAAAhhM3hAaWR1bgE=
-----END OPENSSH PRIVATE KEY-----

1
terraform/ssh/key.pub Normal file
View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCginshUG35mw+c84ubE382kMrWbZ26Au11g2Cttt0phoJjCR8xm6pIWKRQXewklIybunLildoV6ELGN/68bJkjFER4uKQ1FsOSdxbw+Jaw6ltYzYi2j79p/SNvGMWd1zChAucvE1FPdm1WiQoqkwVj3bU0s8g26YOyYOtEo4U2d4QUMJ16qI7a5YaKe8lIyTzY42pKbQ+KbvxX6Rsm4Yn11b0jNH4EMLXeALBbVsDOuLzMrT0bVGVBHLMvZwNDaX9OgR1RoteAYsDS0ZJxZ2OMICRKV08BeV9a2djSBo6nwQ8nZx/RF5HVRkSEckEPHGnZEEPn6F7XfmbyxD/DuqFB a3x@idun

View File

@ -0,0 +1,2 @@
# Enter Hetzner Cloud Token
hcloud_token = ""