Skip to content

Instantly share code, notes, and snippets.

@jdickey
Created September 7, 2017 18:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jdickey/fc74013319e61520c9127a1ef039b03f to your computer and use it in GitHub Desktop.
Save jdickey/fc74013319e61520c9127a1ef039b03f to your computer and use it in GitHub Desktop.

I've been trying to use Ansible to create and set up a Droplet based on your docker-16-04 image. Creating the droplet using the Ansible digital_ocean module works as expected, but I can't access the Droplet afterwards, as I get an error from ssh.

I can't believe that I'm the first or only customer to try to set things up like this. I've been knocking my head against any information source I can find for two weeks now. Perhaps you can advise?

I've attached my Playbooks and command output as listed below. The dynamic-inventory script referenced as digital_ocean.py is that supplied in the Ansible repo.

  1. Command Output 1 - Create Droplet.log - output from running the new_droplet Playbook (see Item 3);
  2. Command Output 2 - Attempted Provisioning of Droplet.md — output from running the playbook Playbook (see Item 4);
  3. new_droplet.yml - Ansible Playbook tasked with creating and tagging a new Droplet
  4. playbook.yml - Ansible Playbook (excerpt) intended to continue with provisioning the new, tagged Droplet

What am I misunderstanding? I've seen your tuts for setting up Ubuntu, but those don't seem to match the docker-16-04 image in key respects — particularly with regard to setting up sshd.

Help?

$ ansible-playbook new_droplet.yml --vault-password=./.vault-password -v
No config file found; using defaults
[WARNING]: Host file not found: /etc/ansible/hosts
[WARNING]: provided hosts list is empty, only localhost is available
PLAY [Initialise a new DigitalOcean Droplet as a Docker app host] ******************************************************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************************************************************************************************************
ok: [localhost]
TASK [Deploy new Droplet] **********************************************************************************************************************************************************************************************************************
changed: [localhost] => {"changed": true, "droplet": {"backup_ids": [], "created_at": "2017-09-07T18:11:49Z", "disk": 20, "features": ["private_networking"], "id": 61398050, "image": {"created_at": "2017-09-01T15:47:34Z", "distribution": "Ubuntu", "id": 27493072, "min_disk_size": 20, "name": "Docker 17.05.0-ce on 16.04", "public": true, "regions": ["nyc1", "sfo1", "nyc2", "ams2", "sgp1", "lon1", "nyc3", "ams3", "fra1", "tor1", "sfo2", "blr1"], "size_gigabytes": 0.68, "slug": "docker-16-04", "type": "snapshot"}, "ip_address": "10.130.26.11", "kernel": null, "locked": false, "memory": 512, "name": "new-demo", "networks": {"v4": [{"gateway": "10.130.1.1", "ip_address": "10.130.26.11", "netmask": "255.255.0.0", "type": "private"}, {"gateway": "188.166.240.1", "ip_address": "188.166.253.163", "netmask": "255.255.240.0", "type": "public"}], "v6": []}, "next_backup_window": null, "region": {"available": true, "features": ["private_networking", "backups", "ipv6", "metadata", "install_agent", "storage"], "name": "Singapore 1", "sizes": ["512mb", "1gb", "2gb", "4gb", "8gb", "16gb", "32gb", "48gb", "64gb"], "slug": "sgp1"}, "size": {"available": true, "disk": 20, "memory": 512, "price_hourly": 0.00744, "price_monthly": 5.0, "regions": ["ams2", "ams3", "blr1", "fra1", "lon1", "nyc1", "nyc2", "nyc3", "sfo1", "sfo2", "sgp1", "tor1"], "slug": "512mb", "transfer": 1.0, "vcpus": 1}, "size_slug": "512mb", "snapshot_ids": [], "status": "active", "tags": [], "vcpus": 1, "volume_ids": []}}
TASK [Create in_process tag if not already created] ********************************************************************************************************************************************************************************************
changed: [localhost] => {"changed": true, "data": {"tag": {"name": "in_process", "resources": {"droplets": {"count": 0, "last_tagged": null}}}}}
TASK [Tag new droplet as in_process] ***********************************************************************************************************************************************************************************************************
changed: [localhost] => {"changed": true}
TASK [Remove IP address from local known_hosts file if it exists] ******************************************************************************************************************************************************************************
ok: [localhost] => {"changed": false, "gid": 20, "group": "staff", "hash_host": false, "key": null, "mode": "0600", "name": "188.166.253.163", "owner": "jeffdickey", "path": "/Users/jeffdickey/.ssh/known_hosts", "size": 17823, "state": "file", "uid": 501}
PLAY RECAP *************************************************************************************************************************************************************************************************************************************
localhost : ok=5 changed=3 unreachable=0 failed=0
$

$ ansible-playbook -i ./digital_ocean.py -u jeff playbook.yml --vault-password-file=./.vault-password -vv ansible-playbook -i ./digital_ocean.py -u jeff playbook.yml --vault-password-file=./.vault-password -vv No config file found; using defaults

PLAYBOOK: playbook.yml ************************************************************************************************************************************************************************************************************************* 1 plays in playbook.yml

PLAY [Get a Docker image up and running on a new Droplet] **************************************************************************************************************************************************************************************

TASK [Gathering Facts] ************************************************************************************************************************************************************************************************************************* The authenticity of host '188.166.253.163 (188.166.253.163)' can't be established. ECDSA key fingerprint is SHA256:Z8cKRRZASYNfBgGVlflUl0lISl4szC/Wblx9yVHBkbU. Are you sure you want to continue connecting (yes/no)? yes fatal: [188.166.253.163]: UNREACHABLE! => {"changed": false, "msg": "Failed to connect to the host via ssh: Warning: Permanently added '188.166.253.163' (ECDSA) to the list of known hosts.\r\nPermission denied (publickey).\r\n", "unreachable": true} to retry, use: --limit @/Users/jeffdickey/src/docker/docker-ansible-test/playbook.retry

PLAY RECAP ************************************************************************************************************************************************************************************************************************************* 188.166.253.163 : ok=0 changed=0 unreachable=1 failed=0

$

# Run this Playbook with the command line
# ansible-playbook new_droplet.yml --vault-password=./.vault-password
#
# The vault password file is required to unlock the vars file `secret`. That
# file contains the `do_ssh_key_id` variable used to identify which SSH key is
# to be added to the new Droplet.
---
- name: Initialise a new DigitalOcean Droplet as a Docker app host
connection: local
hosts: localhost
vars_files:
- secret
vars:
droplet_name: 'new-demo'
image_id: 'docker-16-04'
region_id: 'sgp1'
size_id: '512mb'
ssh_key_ids: ['{{ do_ssh_key_id }}']
tasks:
- name: Deploy new Droplet
digital_ocean:
command: droplet
name: '{{ droplet_name }}'
unique_name: yes
image_id: '{{ image_id }}'
region_id: '{{ region_id }}'
size_id: '{{ size_id }}'
private_networking: yes
state: active
ssh_key_ids: '{{ ssh_key_ids }}'
register: do_response
- name: Create in_process tag if not already created
digital_ocean_tag:
name: in_process
state: present
- name: Tag new droplet as in_process
digital_ocean_tag:
resource_id: '{{ do_response.droplet.id }}'
name: in_process
state: present
- name: Remove IP address from local known_hosts file if it exists
known_hosts:
name: '{{ do_response.droplet.networks.v4[1].ip_address }}'
state: absent
---
# Reinitialize a Droplet, set up Docker, and get our app running in it
#
# Ensure that:
# 1. A named Droplet exists, and is running (from localhost);
# 2. The regular user exists (on the remote);
# 3. The user's `authorized_keys` file exists with correct contents (on the remote);
# 4. The `/etc/ssh/sshd_config` file has the correct contents (on the remote);
# 5. The SSH daemon is reloaded *if* the configuration was changed (on the remote);
# 6. The `apt` package cache is updated/upgraded (on the remote);
# 7. The `ufw` firewall is configured correctly (on the remote);
# 8. The desired Docker image has been pulled if not already on the remote;
# 9. The desired Docker image has been started (on the remote);
# 10. Content is available from the Web server hosted by the named Droplet;
#
# THINGS TO BE FIXED:
# 11. The desired Floating IP already exists;
# 12. The desired Floating IP is reassigned to the named Droplet;
# 13. Content is available from the Web server addressed by the Floating IP.
- name: Get a Docker image up and running on a new Droplet
hosts: in_process
remote_user: '{{ droplet_user_name }}'
vars_files:
- secret
# vars: # Look, ma; no vars! Almost certainly a FIXME (roles?)
tasks:
- name: Verify that the specified Droplet is running
delegate_to: localhost
digital_ocean:
command: droplet
name: '{{ ansible_hostname }}'
unique_name: yes
image_id: 'docker-16-04'
region_id: 'sgp1'
size_id: '512mb'
private_networking: yes
state: active
ssh_key_ids: ['{{ do_ssh_key_id }}']
- name: Verify that the normal user exists on the Droplet
become: true
# delegate_to: '{{ ansible_hostname }}'
user:
name: '{{ droplet_user_name }}'
- name: Verify that the user's .authorized_keys file exists and is correct
# delegate_to: '{{ ansible_hostname }}'
authorized_key:
exclusive: no
key: https://github.com/jdickey.keys
state: present
user: '{{ droplet_user_name }}'
# remaining tasks omitted, as we never get this far
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment