commit 1115ab329e89f662b0c86d8ad7e0b5eb31e4800a Author: Jan Koppe Date: Sat Jun 22 16:02:43 2019 +0200 🚀 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..791b0cb --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +files/ubuntu.img +.terraform +*.tfstate +*.tfstate.backup diff --git a/ansible/ansible.cfg b/ansible/ansible.cfg new file mode 100644 index 0000000..f1aedfc --- /dev/null +++ b/ansible/ansible.cfg @@ -0,0 +1,8 @@ +[defaults] +inventory = ./hosts +host_key_checking = False +remote_user = deploy +forks = 20 + +[ssh_connection] +pipelining = True diff --git a/ansible/hosts b/ansible/hosts new file mode 100644 index 0000000..9ff96a7 --- /dev/null +++ b/ansible/hosts @@ -0,0 +1,8 @@ +[managers] +swarm-1 +swarm-2 +swarm-3 + +[workers] + + diff --git a/ansible/provision.yaml b/ansible/provision.yaml new file mode 100644 index 0000000..ba3c226 --- /dev/null +++ b/ansible/provision.yaml @@ -0,0 +1,20 @@ +--- +- hosts: all + become: true + roles: + - docker + +- hosts: managers[0] + become: true + roles: + - swarm-init + +- hosts: managers:!managers[0] + become: true + roles: + - swarm-manager + +- hosts: workers + become: true + roles: + - swarm-worker diff --git a/ansible/roles/docker/tasks/main.yaml b/ansible/roles/docker/tasks/main.yaml new file mode 100644 index 0000000..3f4d2b9 --- /dev/null +++ b/ansible/roles/docker/tasks/main.yaml @@ -0,0 +1,20 @@ +--- +- name: install python3 docker wrapper + apt: + name: + - python3-docker + +- name: install docker apt gpg key + apt_key: + url: https://download.docker.com/linux/ubuntu/gpg + +- name: install docker apt repository + apt_repository: + repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable + +- name: install docker + apt: + name: + - docker-ce + - docker-ce-cli + - containerd.io diff --git a/ansible/roles/swarm-init/meta/main.yaml b/ansible/roles/swarm-init/meta/main.yaml new file mode 100644 index 0000000..128f19c --- /dev/null +++ b/ansible/roles/swarm-init/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - docker diff --git a/ansible/roles/swarm-init/tasks/main.yaml b/ansible/roles/swarm-init/tasks/main.yaml new file mode 100644 index 0000000..efda872 --- /dev/null +++ b/ansible/roles/swarm-init/tasks/main.yaml @@ -0,0 +1,28 @@ +--- +- name: get node status + command: "docker info -f '{{ '{{' }}.Swarm.LocalNodeState{{ '}}' }}'" + register: local_node_state + changed_when: false + +- name: initialize swarm + when: local_node_state.stdout == "inactive" + command: "docker swarm init --advertise-addr {{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }}" + +- name: get join token for managers + command: "docker swarm join-token -q manager" + register: token_managers + changed_when: false + +- name: set join token for managers as host fact + set_fact: + swarm_token_managers: "{{ token_managers.stdout }}" + +- name: get join token for workers + command: "docker swarm join-token -q worker" + register: token_workers + changed_when: false + +- name: set join token for workers as host fact + set_fact: + swarm_token_workers: "{{ token_workers.stdout }}" + diff --git a/ansible/roles/swarm-manager/meta/main.yaml b/ansible/roles/swarm-manager/meta/main.yaml new file mode 100644 index 0000000..128f19c --- /dev/null +++ b/ansible/roles/swarm-manager/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - docker diff --git a/ansible/roles/swarm-manager/tasks/main.yaml b/ansible/roles/swarm-manager/tasks/main.yaml new file mode 100644 index 0000000..fe6703f --- /dev/null +++ b/ansible/roles/swarm-manager/tasks/main.yaml @@ -0,0 +1,9 @@ +--- +- name: get node status + command: "docker info -f '{{ '{{' }}.Swarm.LocalNodeState{{ '}}' }}'" + register: local_node_state + changed_when: false + +- name: join swarm as manager + when: local_node_state.stdout == "inactive" + command: "docker swarm join --advertise-addr {{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }} --token {{ hostvars[groups['managers'][0]]['swarm_token_managers'] }} {{ hostvars[groups['managers'][0]]['ansible_default_ipv4']['address'] }}:2377" diff --git a/ansible/roles/swarm-worker/meta/main.yaml b/ansible/roles/swarm-worker/meta/main.yaml new file mode 100644 index 0000000..128f19c --- /dev/null +++ b/ansible/roles/swarm-worker/meta/main.yaml @@ -0,0 +1,3 @@ +--- +dependencies: + - docker diff --git a/ansible/roles/swarm-worker/tasks/main.yaml b/ansible/roles/swarm-worker/tasks/main.yaml new file mode 100644 index 0000000..e2b8c12 --- /dev/null +++ b/ansible/roles/swarm-worker/tasks/main.yaml @@ -0,0 +1,9 @@ +--- +- name: get node status + command: "docker info -f '{{ '{{' }}.Swarm.LocalNodeState{{ '}}' }}'" + register: local_node_state + changed_when: false + +- name: join swarm as worker + when: local_node_state.stdout == "inactive" + command: "docker swarm join --advertise-addr {{ hostvars[inventory_hostname]['ansible_default_ipv4']['address'] }} --token {{ hostvars[groups['managers'][0]]['swarm_token_workers'] }} {{ hostvars[groups['managers'][0]]['ansible_default_ipv4']['address'] }}:2377" diff --git a/ansible_inventory.tf b/ansible_inventory.tf new file mode 100644 index 0000000..9e894e7 --- /dev/null +++ b/ansible_inventory.tf @@ -0,0 +1,22 @@ +data "template_file" "inventory" { + template = "${file("files/ansible_hosts.tpl")}" + + depends_on = [ + "libvirt_domain.domain", + ] + + vars = { + managers = "${join("\n", slice(libvirt_domain.domain.*.name, 0, 3))}" + workers = "${join("\n", slice(libvirt_domain.domain.*.name, 3, length(libvirt_domain.domain.*.name)))}" + } +} + +resource "null_resource" "cmd" { + triggers = { + template_rendered = "${data.template_file.inventory.rendered}" + } + + provisioner "local-exec" { + command = "echo '${data.template_file.inventory.rendered}' > ansible/hosts" + } +} diff --git a/cloud-init.tf b/cloud-init.tf new file mode 100644 index 0000000..74d9296 --- /dev/null +++ b/cloud-init.tf @@ -0,0 +1,22 @@ +data "template_file" "user_data" { + count = var.node_count + template = file("${path.module}/files/user_data.cfg") + vars = { + pubkey = file("~/.ssh/id_rsa.pub") + } +} + +data "template_file" "meta_data" { + count = var.node_count + template = file("${path.module}/files/meta_data.cfg") + vars = { + hostname = "swarm-${count.index + 1}" + } +} + +resource "libvirt_cloudinit_disk" "cidata" { + count = var.node_count + name = "swarm-${count.index + 1}-cidata.iso" + user_data = data.template_file.user_data[count.index].rendered + meta_data = data.template_file.meta_data[count.index].rendered +} diff --git a/domain.tf b/domain.tf new file mode 100644 index 0000000..1dcecb9 --- /dev/null +++ b/domain.tf @@ -0,0 +1,29 @@ +resource "libvirt_domain" "domain" { + count = var.node_count + name = "swarm-${count.index + 1}" + vcpu = var.node_vcpu + memory = var.node_memory + + disk { + volume_id = libvirt_volume.root[count.index].id + } + + cloudinit = libvirt_cloudinit_disk.cidata[count.index].id + + console { + type = "pty" + target_port = "0" + target_type = "serial" + } + + console { + type = "pty" + target_type = "virtio" + target_port = "1" + } + + network_interface { + bridge = "br0" + } +} + diff --git a/files/ansible_hosts.tpl b/files/ansible_hosts.tpl new file mode 100644 index 0000000..c04fd40 --- /dev/null +++ b/files/ansible_hosts.tpl @@ -0,0 +1,5 @@ +[managers] +${managers} + +[workers] +${workers} diff --git a/files/meta_data.cfg b/files/meta_data.cfg new file mode 100644 index 0000000..4bb426e --- /dev/null +++ b/files/meta_data.cfg @@ -0,0 +1,3 @@ +#cloud-config + +local-hostname: ${hostname} diff --git a/files/user_data.cfg b/files/user_data.cfg new file mode 100644 index 0000000..8541ba7 --- /dev/null +++ b/files/user_data.cfg @@ -0,0 +1,25 @@ +#cloud-config +# vim: syntax=yaml + +debug: True +disable_root: False +ssh_deletekeys: False +ssh_pwauth: True + +timezone: Europe/Berlin +package_upgrade: True +package_reboot_if_required: True +packages: + - python3 + +users: + - name: deploy + primary_group: deploy + groups: sudo + shell: /bin/bash + uid: 1000 + lock_passwd: False + passwd: "$1$sEv2FKoG$2SAYYCepb/A3cvs/dYl8d." + ssh_authorized_keys: + - "${pubkey}" + diff --git a/provider.tf b/provider.tf new file mode 100644 index 0000000..5a75f98 --- /dev/null +++ b/provider.tf @@ -0,0 +1,3 @@ +provider "libvirt" { + uri = "qemu+ssh://j@luna/system" +} diff --git a/template.tf b/template.tf new file mode 100644 index 0000000..ee04030 --- /dev/null +++ b/template.tf @@ -0,0 +1,5 @@ +resource "libvirt_volume" "template" { + name = "swarm-template.qcow2" + source = "${path.module}/files/ubuntu.img" + format = "qcow2" +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..966da34 --- /dev/null +++ b/variables.tf @@ -0,0 +1,14 @@ +variable "node_count" { + type = number + default = 3 +} + +variable "node_vcpu" { + type = number + default = 8 +} + +variable "node_memory" { + type = number + default = 4096 +} diff --git a/volume.tf b/volume.tf new file mode 100644 index 0000000..d4fbec3 --- /dev/null +++ b/volume.tf @@ -0,0 +1,6 @@ +resource "libvirt_volume" "root" { + count = var.node_count + name = "swarm-${count.index + 1}-root.qcow2" + base_volume_id = libvirt_volume.template.id + size = "21474836480" +}