DEVOPS WORKFLOW A description of what the DevOps workflow is like This document assumes the reader has some Docker and Ansible knowledge. Please make sure your user is part of the `docker` group, and your `.docker` directory has the correct permissions. CH.1 OVERVIEW The word DevOps itself captures some of the intent behind the workflow: Development-Operations. This means the developer is responsible for the full lifetime of the software. From inception, to implementation, to deployment, the developer is expected to take care of making sure all tasks are completed. The goals of the workflow is: 1. Test the installation instructions are sane 2. Test the software works in the expected environment 3. Create an Ansible role to be used by an infrastructure team As usual, you start by gathering requirements and writing a specification, then implementation. Most developers then stop at just barely documenting the installation and deployment process. This is where a regular developer and a devops developer diverge. Using a configuration management tool like Ansible, and a container manager like Docker, the developer is now tasked with putting their installation and deployment documentation to the test. First the target operating system must be chosen. Some go as far as choosing the most minimal Linux distribution that Docker provides and building up from there. The real work is creating Ansible playbooks. As with any project, use the conventions already established. If the project uses Ansible in a certain way, try to continue. Otherwise all Ansilble projects should follow a similar structure: Inventories contain "global" variables and hosts Playbooks contain roles Roles contain tasks, default variables, templates, files, metadata The role's task/main.yml is what describes what tasks to execute. Most software should be packaged as a Debian package. The Debian package should be as "dumb" as possible, just placing files where they should be, and nothing more. Services (like a systemd service) should not be started using the Debian package's facilities. CH.2 USING CONTAINERS IN A DEVOPS CONTEXT The goal of using containers (Docker) is to have a reproducible installation enviroment. No matter how many times you try to install software, it will always be possible to start again from the same state. Most projects will have a particular image they wish to use. Downloading an image is very simple: docker image pull Be sure the images downloaded are the latest versions! It is advisable to probably make a shell function to abstract these for easier scripting. Here are some simple ones for POSIX `sh`: container_images() { docker images; } container_start() { docker run --tty --detach=true $1; } container_kill() { docker kill $1; } container_ip() { docker inspect -f "{{ .NetworkSettings.IPAddress }}" $1; } We use `--tty` since we want the container to continue running as we run Ansible tasks on it. We ask it to provide a pseudo-terminal so that the shell stays open. Passing `--detach` then backgrounds this process and gives us the container id to do further manipulations. CH.3 COMBINING CONTAINERS WITH CONFIGURATION MANAGEMENT Ansible has the ability to "connect" to Docker containers as a built-in feature. There are actually many connection types which can be used: ansible-doc -t connection -l When running `ansible-playbook` pass the `--connection docker` argument. This argument will use Docker conventions to connect. To keep Docker hosts separate from real hosts, create a new inventory configuration file with Docker hosts only, or if the configuration is short-lived then pass `--inventory host1,host2,`. And that's it! Now write your ansible roles as usual, and run the playbook on a container of your choice. First let's create another help function: container_ansible() { \ ansible-playbook -u root --connection docker \ --inventory "$CONTAINER_ID," $2 "$1"; } CONTAINER_ID=$(container_start YOUR_IMAGE) container_ansible playbooks/john-hancryptock.yml Now you can develop an application, and its deployment in an easily reproducible manner. CH.4 POSSIBLE ISSUES It is possible that the roles require some variables defined in the group_vars or host_vars files. If a variable is missing you can pass it with `--extra-vars="k=v"` to `ansible-playbook`.