commit c32a303998d62b85059f6be3cff1dcbb7bdffb65 Author: sergio Date: Mon Sep 11 18:31:03 2023 +0200 first commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..5e26aaf --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Ansible HashiStack + +Instalación del stack de Hashicorp usando Ansible: +- Consul + +Por hacer: +- Nomad +- Vault + +## Configuración +Comprueba el contenido del archivo **proxmox-inv/hosts**. + +## Ejecución +Aplica el rol consul: +```bash +ansible-playbook consul.yml +``` diff --git a/ansible.cfg b/ansible.cfg new file mode 100644 index 0000000..c3533e3 --- /dev/null +++ b/ansible.cfg @@ -0,0 +1,2 @@ +[defaults] +inventory = proxmox-inv diff --git a/consul.yml b/consul.yml new file mode 100644 index 0000000..93e4ad8 --- /dev/null +++ b/consul.yml @@ -0,0 +1,7 @@ +- name: Instala Consul + hosts: consul_node + any_errors_fatal: true + become: true + become_user: root + roles: + - consul diff --git a/proxmox-inv/hosts b/proxmox-inv/hosts new file mode 100644 index 0000000..bb5c73f --- /dev/null +++ b/proxmox-inv/hosts @@ -0,0 +1,11 @@ +[all:vars] +ansible_connection=ssh +ansible_user=alpine +ansible_ssh_private_key_file=~/.ssh/alpine-cloud + +[consul_node] +192.168.1.71 consul_iface=eth0 consul_node_role=server vm_name=hashi-1 vm_ip=192.168.1.71 +192.168.1.72 consul_iface=eth0 consul_node_role=client vm_name=hashi-2 vm_ip=192.168.1.72 + +[consul_node:vars] +consul_dc_name=tr4ck diff --git a/roles/consul/defaults/main.yml b/roles/consul/defaults/main.yml new file mode 100644 index 0000000..89edd87 --- /dev/null +++ b/roles/consul/defaults/main.yml @@ -0,0 +1,4 @@ +--- +consul_version: v1.16.1 +consul_install_path: /opt/consul +consul_data_path: "{{ consul_install_path }}/data" diff --git a/roles/consul/handlers/main.yml b/roles/consul/handlers/main.yml new file mode 100644 index 0000000..946e93d --- /dev/null +++ b/roles/consul/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: restart consul + ansible.builtin.service: + name: consul + state: restarted + become: true diff --git a/roles/consul/tasks/install_alpine_binary.yml b/roles/consul/tasks/install_alpine_binary.yml new file mode 100644 index 0000000..7820cef --- /dev/null +++ b/roles/consul/tasks/install_alpine_binary.yml @@ -0,0 +1,7 @@ +--- +- name: install consul apk package + community.general.apk: + name: consul + state: present + update_cache: yes + become: true diff --git a/roles/consul/tasks/main.yml b/roles/consul/tasks/main.yml new file mode 100644 index 0000000..1a819a1 --- /dev/null +++ b/roles/consul/tasks/main.yml @@ -0,0 +1,70 @@ +--- +- name: setup prerequisites + ansible.builtin.include_tasks: "prereq_{{ ansible_distribution|lower }}.yml" + +- name: setup python-consul + ansible.builtin.pip: + name: python-consul + state: latest + executable: /usr/bin/pip3 + become: true + +- name: check if consul is the correct version + ansible.builtin.command: + cmd: "/usr/bin/consul" + register: consul_installed_version + changed_when: false + failed_when: false + +- block: + - name: Include base install + include_tasks: "install_{{ ansible_distribution|lower }}_binary.yml" + when: consul_installed_version is not defined or consul_version not in consul_installed_version.stdout + +- name: ensure the consul folders exist + ansible.builtin.file: + path: "{{ item }}" + state: directory + owner: consul + group: consul + mode: 0755 + with_items: + - "{{ consul_install_path }}" + - "{{ consul_data_path }}" + - "/etc/consul/" + become: true + +- name: touch env file + ansible.builtin.file: + path: "/etc/consul/consul.env" + state: touch + owner: consul + group: consul + mode: 0770 + become: true + +- name: setup key for encryption + include_tasks: "setup_encrypt_key.yml" + run_once: true + +- name: setup consul ca + include_tasks: "setup_ca.yml" + run_once: true + +- name: setup server cert + include_tasks: "setup_server_cert.yml" + +- name: setup client cert + include_tasks: "setup_client_cert.yml" + +- name: setup consul config + include_tasks: "setup_consul_config.yml" + +- name: enable and start consul + ansible.builtin.service: + name: consul + enabled: true + state: restarted + async: 600 + poll: 5 + become: true diff --git a/roles/consul/tasks/prereq_alpine.yml b/roles/consul/tasks/prereq_alpine.yml new file mode 100644 index 0000000..376a127 --- /dev/null +++ b/roles/consul/tasks/prereq_alpine.yml @@ -0,0 +1,7 @@ +--- +- name: setup pip3 + community.general.apk: + name: py3-pip + state: present + update_cache: yes + become: true diff --git a/roles/consul/tasks/setup_ca.yml b/roles/consul/tasks/setup_ca.yml new file mode 100644 index 0000000..2eaa686 --- /dev/null +++ b/roles/consul/tasks/setup_ca.yml @@ -0,0 +1,46 @@ +--- +- name: generate the consul CA + ansible.builtin.command: + cmd: consul tls ca create + args: + chdir: /etc/consul + creates: /etc/consul/consul-agent-ca.pem + become: true + +- name: set the key as fact + ansible.builtin.command: + cmd: cat /etc/consul/consul-agent-ca-key.pem + changed_when: false + register: ca_key + become: true + +- name: set the pem as fact + ansible.builtin.command: + cmd: cat /etc/consul/consul-agent-ca.pem + changed_when: false + register: ca_pem + become: true + +- name: store key onto other systems + ansible.builtin.copy: + content: "{{ ca_key.stdout }}" + mode: 0640 + owner: consul + group: consul + dest: /etc/consul/consul-agent-ca-key.pem + delegate_to: "{{ item }}" + become: true + loop: "{{ groups['consul_node'] }}" + when: ansible_fqdn != item + +- name: store ca cert onto other systems + ansible.builtin.copy: + content: "{{ ca_pem.stdout }}" + mode: 0640 + owner: consul + group: consul + dest: /etc/consul/consul-agent-ca.pem + delegate_to: "{{ item }}" + become: true + loop: "{{ groups['consul_node'] }}" + when: ansible_fqdn != item diff --git a/roles/consul/tasks/setup_client_cert.yml b/roles/consul/tasks/setup_client_cert.yml new file mode 100644 index 0000000..6d95ea7 --- /dev/null +++ b/roles/consul/tasks/setup_client_cert.yml @@ -0,0 +1,19 @@ +--- +- name: generate the client dc cert + ansible.builtin.command: + cmd: consul tls cert create -client -dc {{ consul_dc_name }} -ca /etc/consul/consul-agent-ca.pem + args: + chdir: /etc/consul + creates: "/etc/consul/{{consul_dc_name}}-client-consul-0.pem" + become: true + +- name: set permissions on generated files + ansible.builtin.file: + path: "{{ item }}" + mode: 0640 + owner: consul + group: consul + become: true + loop: + - "/etc/consul/{{ consul_dc_name }}-client-consul-0.pem" + - "/etc/consul/{{ consul_dc_name }}-client-consul-0-key.pem" diff --git a/roles/consul/tasks/setup_consul_config.yml b/roles/consul/tasks/setup_consul_config.yml new file mode 100644 index 0000000..7f3710f --- /dev/null +++ b/roles/consul/tasks/setup_consul_config.yml @@ -0,0 +1,15 @@ +--- +- name: get the encrypt_key + ansible.builtin.command: + cmd: cat /etc/consul/gossip.key + register: gossip + become: true + changed_when: false + +- name: set the consul.json config file + ansible.builtin.template: + src: consul.json.j2 + dest: /etc/consul/consul.json + mode: 0600 + owner: consul + become: true diff --git a/roles/consul/tasks/setup_encrypt_key.yml b/roles/consul/tasks/setup_encrypt_key.yml new file mode 100644 index 0000000..3b15933 --- /dev/null +++ b/roles/consul/tasks/setup_encrypt_key.yml @@ -0,0 +1,39 @@ +--- +- name: debug + ansible.builtin.debug: + msg: "{{ groups['consul_node'] }}" + +- name: check whether keygen has already ran + ansible.builtin.stat: + path: /etc/consul/gossip.key + become: true + register: keygen_stat + +- block: + - name: ensure /etc/consul is exists + ansible.builtin.file: + path: /etc/consul + state: directory + mode: 0755 + delegate_to: "{{ item }}" + become: true + loop: "{{ groups['consul_node'] }}" + when: ansible_fqdn != item + + - name: setup the key for encryption + ansible.builtin.command: + cmd: consul keygen + register: consul_keygen + run_once: true + + - name: store key onto system + ansible.builtin.copy: + content: "{{ consul_keygen.stdout }}" + mode: 0600 + dest: /etc/consul/gossip.key + owner: consul + delegate_to: "{{ item }}" + loop: "{{ groups['consul_node'] }}" + run_once: true + when: keygen_stat.stat.exists == false + become: true diff --git a/roles/consul/tasks/setup_server_cert.yml b/roles/consul/tasks/setup_server_cert.yml new file mode 100644 index 0000000..ea1cb5c --- /dev/null +++ b/roles/consul/tasks/setup_server_cert.yml @@ -0,0 +1,19 @@ +--- +- name: generate the server dc cert + ansible.builtin.command: + cmd: consul tls cert create -server -dc {{ consul_dc_name }} -ca /etc/consul/consul-agent-ca.pem + args: + chdir: /etc/consul + creates: "/etc/consul/{{ consul_dc_name }}-server-consul-0.pem" + become: true + +- name: set permissions on generated files + ansible.builtin.file: + path: "{{ item }}" + mode: 0640 + owner: consul + group: consul + become: true + loop: + - "/etc/consul/{{ consul_dc_name }}-server-consul-0.pem" + - "/etc/consul/{{ consul_dc_name }}-server-consul-0-key.pem" diff --git a/roles/consul/templates/consul.json.j2 b/roles/consul/templates/consul.json.j2 new file mode 100644 index 0000000..898fada --- /dev/null +++ b/roles/consul/templates/consul.json.j2 @@ -0,0 +1,35 @@ +{ + "datacenter": "{{ consul_dc_name }}", + "node_name": "{{ vm_name }}", + "data_dir": "/opt/consul", + "encrypt": "{{ gossip.stdout }}", + "ca_file": "/etc/consul/consul-agent-ca.pem", + "cert_file": "/etc/consul/{{ consul_dc_name }}-server-consul-0.pem", + "key_file": "/etc/consul/{{ consul_dc_name }}-server-consul-0-key.pem", + "verify_incoming": false, + "verify_outgoing": true, + "verify_server_hostname": false, + "bind_addr": "{{ vm_ip }}", + "addresses": { + "https": "{{ vm_ip }}", + "http": "{{ vm_ip }}", + "dns": "{{ vm_ip }}", + "grpc": "{{ vm_ip }}" + }, + "ports": { + "grpc_tls": 8502 + }, + {% if 'server' in consul_node_role %} + "server": true, + {% if consul_bootstrap_node is defined %} + "bootstrap": true, + {% endif %} + {% endif %} + "retry_join": [{% for host in groups['consul_node'] %}"{{ hostvars[host]['vm_ip'] }}"{% if not loop.last %},{% endif %}{% endfor %}], + "ui_config": { + "enabled": true + }, + "connect": { + "enabled": true + } +}