commit
85c237bc1d
18 changed files with 294 additions and 290 deletions
|
@ -366,6 +366,8 @@ before_script:
|
|||
|
||||
.ubuntu_vault_sep_variables: &ubuntu_vault_sep_variables
|
||||
# stage: deploy-gce-part1
|
||||
AUTHORIZATION_MODES: "{ 'authorization_modes': [ 'RBAC' ] }"
|
||||
CLOUD_MACHINE_TYPE: "n1-standard-2"
|
||||
KUBE_NETWORK_PLUGIN: canal
|
||||
CERT_MGMT: vault
|
||||
CLOUD_IMAGE: ubuntu-1604-xenial
|
||||
|
|
|
@ -7,51 +7,14 @@
|
|||
when: inventory_hostname in etcd_node_cert_hosts
|
||||
tags: etcd-secrets
|
||||
|
||||
- name: gen_certs_vault | Read in the local credentials
|
||||
command: cat /etc/vault/roles/etcd/userpass
|
||||
register: etcd_vault_creds_cat
|
||||
delegate_to: "{{ groups['vault'][0] }}"
|
||||
|
||||
- name: gen_certs_vault | Set facts for read Vault Creds
|
||||
set_fact:
|
||||
etcd_vault_creds: "{{ etcd_vault_creds_cat.stdout|from_json }}"
|
||||
delegate_to: "{{ groups['vault'][0] }}"
|
||||
|
||||
- name: gen_certs_vault | Log into Vault and obtain an token
|
||||
uri:
|
||||
url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}/v1/auth/userpass/login/{{ etcd_vault_creds.username }}"
|
||||
headers:
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
method: POST
|
||||
body_format: json
|
||||
body:
|
||||
password: "{{ etcd_vault_creds.password }}"
|
||||
register: etcd_vault_login_result
|
||||
delegate_to: "{{ groups['vault'][0] }}"
|
||||
|
||||
- name: gen_certs_vault | Set fact for vault_client_token
|
||||
set_fact:
|
||||
vault_client_token: "{{ etcd_vault_login_result.get('json', {}).get('auth', {}).get('client_token') }}"
|
||||
run_once: true
|
||||
|
||||
- name: gen_certs_vault | Set fact for Vault API token
|
||||
set_fact:
|
||||
etcd_vault_headers:
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
X-Vault-Token: "{{ vault_client_token }}"
|
||||
run_once: true
|
||||
when: vault_client_token != ""
|
||||
|
||||
# Issue master certs to Etcd nodes
|
||||
- include: ../../vault/tasks/shared/issue_cert.yml
|
||||
vars:
|
||||
issue_cert_common_name: "etcd:master:{{ item.rsplit('/', 1)[1].rsplit('.', 1)[0] }}"
|
||||
issue_cert_alt_names: "{{ groups.etcd + ['localhost'] }}"
|
||||
issue_cert_copy_ca: "{{ item == etcd_master_certs_needed|first }}"
|
||||
issue_cert_file_group: "{{ etcd_cert_group }}"
|
||||
issue_cert_file_owner: kube
|
||||
issue_cert_headers: "{{ etcd_vault_headers }}"
|
||||
issue_cert_hosts: "{{ groups.etcd }}"
|
||||
issue_cert_ip_sans: >-
|
||||
[
|
||||
|
@ -74,11 +37,11 @@
|
|||
# Issue node certs to everyone else
|
||||
- include: ../../vault/tasks/shared/issue_cert.yml
|
||||
vars:
|
||||
issue_cert_common_name: "etcd:node:{{ item.rsplit('/', 1)[1].rsplit('.', 1)[0] }}"
|
||||
issue_cert_alt_names: "{{ etcd_node_cert_hosts }}"
|
||||
issue_cert_copy_ca: "{{ item == etcd_node_certs_needed|first }}"
|
||||
issue_cert_file_group: "{{ etcd_cert_group }}"
|
||||
issue_cert_file_owner: kube
|
||||
issue_cert_headers: "{{ etcd_vault_headers }}"
|
||||
issue_cert_hosts: "{{ etcd_node_cert_hosts }}"
|
||||
issue_cert_ip_sans: >-
|
||||
[
|
||||
|
|
|
@ -1,56 +1,23 @@
|
|||
---
|
||||
- include: sync_kube_master_certs.yml
|
||||
when: inventory_hostname in groups['kube-master']
|
||||
tags: k8s-secrets
|
||||
|
||||
- include: sync_kube_node_certs.yml
|
||||
when: inventory_hostname in groups['k8s-cluster']
|
||||
tags: k8s-secrets
|
||||
|
||||
- name: gen_certs_vault | Read in the local credentials
|
||||
command: cat /etc/vault/roles/kube/userpass
|
||||
register: kube_vault_creds_cat
|
||||
delegate_to: "{{ groups['k8s-cluster'][0] }}"
|
||||
|
||||
- name: gen_certs_vault | Set facts for read Vault Creds
|
||||
set_fact:
|
||||
kube_vault_creds: "{{ kube_vault_creds_cat.stdout|from_json }}"
|
||||
delegate_to: "{{ groups['k8s-cluster'][0] }}"
|
||||
|
||||
- name: gen_certs_vault | Log into Vault and obtain an token
|
||||
uri:
|
||||
url: "{{ hostvars[groups['vault'][0]]['vault_leader_url'] }}/v1/auth/userpass/login/{{ kube_vault_creds.username }}"
|
||||
headers:
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
method: POST
|
||||
body_format: json
|
||||
body:
|
||||
password: "{{ kube_vault_creds.password }}"
|
||||
register: kube_vault_login_result
|
||||
delegate_to: "{{ groups['k8s-cluster'][0] }}"
|
||||
|
||||
- name: gen_certs_vault | Set fact for Vault API token
|
||||
set_fact:
|
||||
kube_vault_headers:
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
X-Vault-Token: "{{ kube_vault_login_result.get('json',{}).get('auth', {}).get('client_token') }}"
|
||||
run_once: true
|
||||
|
||||
# Issue certs to kube-master nodes
|
||||
# Issue admin certs to kube-master hosts
|
||||
- include: ../../../vault/tasks/shared/issue_cert.yml
|
||||
vars:
|
||||
issue_cert_copy_ca: "{{ item == kube_master_certs_needed|first }}"
|
||||
issue_cert_common_name: "admin"
|
||||
issue_cert_copy_ca: "{{ item == kube_admin_certs_needed|first }}"
|
||||
issue_cert_file_group: "{{ kube_cert_group }}"
|
||||
issue_cert_file_owner: kube
|
||||
issue_cert_headers: "{{ kube_vault_headers }}"
|
||||
issue_cert_hosts: "{{ groups['kube-master'] }}"
|
||||
issue_cert_path: "{{ item }}"
|
||||
issue_cert_role: kube
|
||||
issue_cert_role: kube-master
|
||||
issue_cert_url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}"
|
||||
issue_cert_mount_path: "{{ kube_vault_mount_path }}"
|
||||
with_items: "{{ kube_master_certs_needed|d([]) }}"
|
||||
with_items: "{{ kube_admin_certs_needed|d([]) }}"
|
||||
when: inventory_hostname in groups['kube-master']
|
||||
|
||||
- name: gen_certs_vault | Set fact about certificate alt names
|
||||
|
@ -69,12 +36,13 @@
|
|||
when: loadbalancer_apiserver is defined and apiserver_loadbalancer_domain_name is defined
|
||||
run_once: true
|
||||
|
||||
# Issue master components certs to kube-master hosts
|
||||
- include: ../../../vault/tasks/shared/issue_cert.yml
|
||||
vars:
|
||||
issue_cert_common_name: "kubernetes"
|
||||
issue_cert_alt_names: "{{ kube_cert_alt_names }}"
|
||||
issue_cert_file_group: "{{ kube_cert_group }}"
|
||||
issue_cert_file_owner: kube
|
||||
issue_cert_headers: "{{ kube_vault_headers }}"
|
||||
issue_cert_hosts: "{{ groups['kube-master'] }}"
|
||||
issue_cert_ip_sans: >-
|
||||
[
|
||||
|
@ -87,7 +55,7 @@
|
|||
"127.0.0.1","::1","{{ kube_apiserver_ip }}"
|
||||
]
|
||||
issue_cert_path: "{{ item }}"
|
||||
issue_cert_role: kube
|
||||
issue_cert_role: kube-master
|
||||
issue_cert_url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}"
|
||||
issue_cert_mount_path: "{{ kube_vault_mount_path }}"
|
||||
with_items: "{{ kube_master_components_certs_needed|d([]) }}"
|
||||
|
@ -97,27 +65,28 @@
|
|||
# Issue node certs to k8s-cluster nodes
|
||||
- include: ../../../vault/tasks/shared/issue_cert.yml
|
||||
vars:
|
||||
issue_cert_common_name: "system:node:{{ item.rsplit('/', 1)[1].rsplit('.', 1)[0] }}"
|
||||
issue_cert_copy_ca: "{{ item == kube_node_certs_needed|first }}"
|
||||
issue_cert_file_group: "{{ kube_cert_group }}"
|
||||
issue_cert_file_owner: kube
|
||||
issue_cert_headers: "{{ kube_vault_headers }}"
|
||||
issue_cert_hosts: "{{ groups['k8s-cluster'] }}"
|
||||
issue_cert_path: "{{ item }}"
|
||||
issue_cert_role: kube
|
||||
issue_cert_role: kube-node
|
||||
issue_cert_url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}"
|
||||
issue_cert_mount_path: "{{ kube_vault_mount_path }}"
|
||||
with_items: "{{ kube_node_certs_needed|d([]) }}"
|
||||
when: inventory_hostname in groups['k8s-cluster']
|
||||
|
||||
# Issue proxy certs to k8s-cluster nodes
|
||||
- include: ../../../vault/tasks/shared/issue_cert.yml
|
||||
vars:
|
||||
issue_cert_common_name: "system:kube-proxy"
|
||||
issue_cert_copy_ca: "{{ item == kube_proxy_certs_needed|first }}"
|
||||
issue_cert_file_group: "{{ kube_cert_group }}"
|
||||
issue_cert_file_owner: kube
|
||||
issue_cert_headers: "{{ kube_vault_headers }}"
|
||||
issue_cert_hosts: "{{ groups['k8s-cluster'] }}"
|
||||
issue_cert_path: "{{ item }}"
|
||||
issue_cert_role: kube
|
||||
issue_cert_role: kube-proxy
|
||||
issue_cert_url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}"
|
||||
issue_cert_mount_path: "{{ kube_vault_mount_path }}"
|
||||
with_items: "{{ kube_proxy_certs_needed|d([]) }}"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
- name: sync_kube_master_certs | Create list of needed kube admin certs
|
||||
set_fact:
|
||||
kube_master_cert_list: "{{ kube_master_cert_list|d([]) + ['admin-' + item + '.pem'] }}"
|
||||
kube_admin_cert_list: "{{ kube_admin_cert_list|d([]) + ['admin-' + item + '.pem'] }}"
|
||||
with_items: "{{ groups['kube-master'] }}"
|
||||
|
||||
- include: ../../../vault/tasks/shared/sync_file.yml
|
||||
|
@ -13,11 +13,11 @@
|
|||
sync_file_hosts: "{{ groups['kube-master'] }}"
|
||||
sync_file_is_cert: true
|
||||
sync_file_owner: kube
|
||||
with_items: "{{ kube_master_cert_list|d([]) }}"
|
||||
with_items: "{{ kube_admin_cert_list|d([]) }}"
|
||||
|
||||
- name: sync_kube_master_certs | Set facts for kube admin sync_file results
|
||||
set_fact:
|
||||
kube_master_certs_needed: "{{ kube_master_certs_needed|default([]) + [item.path] }}"
|
||||
kube_admin_certs_needed: "{{ kube_admin_certs_needed|default([]) + [item.path] }}"
|
||||
with_items: "{{ sync_file_results|d([]) }}"
|
||||
when: item.no_srcs|bool
|
||||
|
||||
|
|
|
@ -135,3 +135,10 @@ rbac_enabled: "{{ 'RBAC' in authorization_modes }}"
|
|||
## List of key=value pairs that describe feature gates for
|
||||
## the k8s cluster.
|
||||
kube_feature_gates: []
|
||||
|
||||
# Vault data dirs.
|
||||
vault_base_dir: /etc/vault
|
||||
vault_cert_dir: "{{ vault_base_dir }}/ssl"
|
||||
vault_config_dir: "{{ vault_base_dir }}/config"
|
||||
vault_roles_dir: "{{ vault_base_dir }}/roles"
|
||||
vault_secrets_dir: "{{ vault_base_dir }}/secrets"
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
---
|
||||
vault_bootstrap: false
|
||||
vault_deployment_type: docker
|
||||
|
||||
vault_adduser_vars:
|
||||
comment: "Hashicorp Vault User"
|
||||
|
@ -6,41 +8,18 @@ vault_adduser_vars:
|
|||
name: vault
|
||||
shell: /sbin/nologin
|
||||
system: yes
|
||||
|
||||
# This variables redefined in kubespray-defaults for using shared tasks
|
||||
# in etcd and kubernetes/secrets roles
|
||||
vault_base_dir: /etc/vault
|
||||
# https://releases.hashicorp.com/vault/0.6.4/vault_0.6.4_SHA256SUMS
|
||||
vault_version: 0.6.4
|
||||
vault_binary_checksum: 04d87dd553aed59f3fe316222217a8d8777f40115a115dac4d88fac1611c51a6
|
||||
vault_bootstrap: false
|
||||
vault_ca_options:
|
||||
common_name: vault
|
||||
format: pem
|
||||
ttl: 87600h
|
||||
vault_cert_dir: "{{ vault_base_dir }}/ssl"
|
||||
vault_client_headers:
|
||||
Accept: "application/json"
|
||||
Content-Type: "application/json"
|
||||
vault_config:
|
||||
backend:
|
||||
etcd:
|
||||
address: "{{ vault_etcd_url }}"
|
||||
ha_enabled: "true"
|
||||
redirect_addr: "https://{{ ansible_default_ipv4.address }}:{{ vault_port }}"
|
||||
tls_ca_file: "{{ vault_etcd_cert_dir }}/ca.pem"
|
||||
cluster_name: "kubernetes-vault"
|
||||
default_lease_ttl: "{{ vault_default_lease_ttl }}"
|
||||
listener:
|
||||
tcp:
|
||||
address: "0.0.0.0:{{ vault_port }}"
|
||||
tls_cert_file: "{{ vault_cert_dir }}/api.pem"
|
||||
tls_key_file: "{{ vault_cert_dir }}/api-key.pem"
|
||||
max_lease_ttl: "{{ vault_max_lease_ttl }}"
|
||||
vault_config_dir: "{{ vault_base_dir }}/config"
|
||||
vault_container_name: kube-hashicorp-vault
|
||||
# This variable is meant to match the GID of vault inside Hashicorp's official Vault Container
|
||||
vault_default_lease_ttl: 720h
|
||||
vault_default_role_permissions:
|
||||
allow_any_name: true
|
||||
vault_deployment_type: docker
|
||||
vault_roles_dir: "{{ vault_base_dir }}/roles"
|
||||
vault_secrets_dir: "{{ vault_base_dir }}/secrets"
|
||||
vault_log_dir: "/var/log/vault"
|
||||
|
||||
vault_version: 0.8.1
|
||||
vault_binary_checksum: 3c4d70ba71619a43229e65c67830e30e050eab7a81ac6b28325ff707e5914188
|
||||
vault_download_url: "https://releases.hashicorp.com/vault/{{ vault_version }}/vault_{{ vault_version }}_linux_amd64.zip"
|
||||
vault_download_vars:
|
||||
container: "{{ vault_deployment_type != 'host' }}"
|
||||
|
@ -55,17 +34,19 @@ vault_download_vars:
|
|||
unarchive: true
|
||||
url: "{{ vault_download_url }}"
|
||||
version: "{{ vault_version }}"
|
||||
vault_etcd_url: "https://{{ hostvars[groups.etcd[0]]['ip']|d(hostvars[groups.etcd[0]]['ansible_default_ipv4']['address']) }}:2379"
|
||||
|
||||
vault_container_name: kube-hashicorp-vault
|
||||
vault_temp_container_name: vault-temp
|
||||
vault_image_repo: "vault"
|
||||
vault_image_tag: "{{ vault_version }}"
|
||||
vault_log_dir: "/var/log/vault"
|
||||
vault_max_lease_ttl: 87600h
|
||||
vault_needs_gen: false
|
||||
|
||||
vault_bind_address: 0.0.0.0
|
||||
vault_port: 8200
|
||||
vault_roles_dir: "{{ vault_base_dir }}/roles"
|
||||
vault_secret_shares: 1
|
||||
vault_secret_threshold: 1
|
||||
vault_secrets_dir: "{{ vault_base_dir }}/secrets"
|
||||
vault_etcd_url: "https://{{ hostvars[groups.etcd[0]]['ip']|d(hostvars[groups.etcd[0]]['ansible_default_ipv4']['address']) }}:2379"
|
||||
|
||||
vault_default_lease_ttl: 720h
|
||||
vault_max_lease_ttl: 87600h
|
||||
|
||||
vault_temp_config:
|
||||
backend:
|
||||
file:
|
||||
|
@ -73,29 +54,109 @@ vault_temp_config:
|
|||
default_lease_ttl: "{{ vault_default_lease_ttl }}"
|
||||
listener:
|
||||
tcp:
|
||||
address: "0.0.0.0:{{ vault_port }}"
|
||||
address: "{{ vault_bind_address }}:{{ vault_port }}"
|
||||
tls_disable: "true"
|
||||
max_lease_ttl: "{{ vault_max_lease_ttl }}"
|
||||
vault_temp_container_name: vault-temp
|
||||
# etcd pki mount options
|
||||
|
||||
vault_config:
|
||||
backend:
|
||||
etcd:
|
||||
address: "{{ vault_etcd_url }}"
|
||||
ha_enabled: "true"
|
||||
redirect_addr: "https://{{ ansible_default_ipv4.address }}:{{ vault_port }}"
|
||||
tls_ca_file: "{{ vault_etcd_cert_dir }}/ca.pem"
|
||||
cluster_name: "kubernetes-vault"
|
||||
default_lease_ttl: "{{ vault_default_lease_ttl }}"
|
||||
max_lease_ttl: "{{ vault_max_lease_ttl }}"
|
||||
listener:
|
||||
tcp:
|
||||
address: "{{ vault_bind_address }}:{{ vault_port }}"
|
||||
tls_cert_file: "{{ vault_cert_dir }}/api.pem"
|
||||
tls_key_file: "{{ vault_cert_dir }}/api-key.pem"
|
||||
|
||||
vault_secret_shares: 1
|
||||
vault_secret_threshold: 1
|
||||
|
||||
vault_ca_options:
|
||||
vault:
|
||||
common_name: vault
|
||||
format: pem
|
||||
ttl: "{{ vault_max_lease_ttl }}"
|
||||
exclude_cn_from_sans: true
|
||||
etcd:
|
||||
common_name: etcd
|
||||
format: pem
|
||||
ttl: "{{ vault_max_lease_ttl }}"
|
||||
exclude_cn_from_sans: true
|
||||
kube:
|
||||
common_name: kube
|
||||
format: pem
|
||||
ttl: "{{ vault_max_lease_ttl }}"
|
||||
exclude_cn_from_sans: true
|
||||
|
||||
vault_client_headers:
|
||||
Accept: "application/json"
|
||||
Content-Type: "application/json"
|
||||
|
||||
vault_etcd_cert_dir: /etc/ssl/etcd/ssl
|
||||
vault_etcd_mount_path: etcd
|
||||
vault_etcd_default_lease_ttl: 720h
|
||||
vault_etcd_max_lease_ttl: 87600h
|
||||
vault_etcd_role:
|
||||
vault_kube_cert_dir: /etc/kubernetes/ssl
|
||||
|
||||
vault_pki_mounts:
|
||||
vault:
|
||||
name: vault
|
||||
default_lease_ttl: "{{ vault_default_lease_ttl }}"
|
||||
max_lease_ttl: "{{ vault_max_lease_ttl }}"
|
||||
description: "Vault Root CA"
|
||||
cert_dir: "{{ vault_cert_dir }}"
|
||||
roles:
|
||||
- name: vault
|
||||
group: vault
|
||||
password: "{{ lookup('pipe','date +%Y%m%d%H%M%S' + cluster_name + 'vault') | to_uuid }}"
|
||||
policy_rules: default
|
||||
role_options: default
|
||||
etcd:
|
||||
name: etcd
|
||||
default_lease_ttl: "{{ vault_default_lease_ttl }}"
|
||||
max_lease_ttl: "{{ vault_max_lease_ttl }}"
|
||||
description: "Etcd Root CA"
|
||||
cert_dir: "{{ vault_etcd_cert_dir }}"
|
||||
roles:
|
||||
- name: etcd
|
||||
group: etcd
|
||||
password: "{{ lookup('pipe','date +%Y%m%d%H%M%S' + cluster_name + 'etcd') | to_uuid }}"
|
||||
policy_rules: default
|
||||
role_options: default
|
||||
mount_path: "{{ vault_etcd_mount_path }}"
|
||||
# kubernetes pki mount options
|
||||
vault_kube_cert_dir: "{{ kube_cert_dir }}"
|
||||
vault_kube_mount_path: kube
|
||||
vault_kube_default_lease_ttl: 720h
|
||||
vault_kube_max_lease_ttl: 87600h
|
||||
vault_kube_role:
|
||||
role_options:
|
||||
allow_any_name: true
|
||||
enforce_hostnames: false
|
||||
organization: "kube:etcd"
|
||||
kube:
|
||||
name: kube
|
||||
group: k8s-cluster
|
||||
default_lease_ttl: "{{ vault_default_lease_ttl }}"
|
||||
max_lease_ttl: "{{ vault_max_lease_ttl }}"
|
||||
description: "Kubernetes Root CA"
|
||||
cert_dir: "{{ vault_kube_cert_dir }}"
|
||||
roles:
|
||||
- name: kube-master
|
||||
group: kube-master
|
||||
password: "{{ lookup('pipe','date +%Y%m%d%H%M%S' + cluster_name + 'kube-master') | to_uuid }}"
|
||||
policy_rules: default
|
||||
role_options: default
|
||||
mount_path: "{{ vault_kube_mount_path }}"
|
||||
role_options:
|
||||
allow_any_name: true
|
||||
enforce_hostnames: false
|
||||
organization: "system:masters"
|
||||
- name: kube-node
|
||||
group: k8s-cluster
|
||||
password: "{{ lookup('pipe','date +%Y%m%d%H%M%S' + cluster_name + 'kube-node') | to_uuid }}"
|
||||
policy_rules: default
|
||||
role_options:
|
||||
allow_any_name: true
|
||||
enforce_hostnames: false
|
||||
organization: "system:nodes"
|
||||
- name: kube-proxy
|
||||
group: k8s-cluster
|
||||
password: "{{ lookup('pipe', 'date +%Y%m%d%H%M%S' + cluster_name + 'kube-proxy') | to_uuid }}"
|
||||
policy_rules: default
|
||||
role_options:
|
||||
allow_any_name: true
|
||||
enforce_hostnames: false
|
||||
organization: "system:node-proxier"
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
- include: ../shared/auth_backend.yml
|
||||
vars:
|
||||
auth_backend_description: A Username/Password Auth Backend primarily used for services needing to issue certificates
|
||||
auth_backend_path: userpass
|
||||
auth_backend_type: userpass
|
||||
delegate_to: "{{ groups.vault|first }}"
|
||||
run_once: true
|
||||
|
||||
- include: ../shared/create_role.yml
|
||||
vars:
|
||||
create_role_name: "{{ vault_etcd_role.name }}"
|
||||
create_role_group: "{{ vault_etcd_role.group }}"
|
||||
create_role_policy_rules: "{{ vault_etcd_role.policy_rules }}"
|
||||
create_role_options: "{{ vault_etcd_role.role_options }}"
|
||||
create_role_mount_path: "{{ vault_etcd_role.mount_path }}"
|
||||
when: inventory_hostname in groups.etcd
|
12
roles/vault/tasks/bootstrap/create_mounts.yml
Normal file
12
roles/vault/tasks/bootstrap/create_mounts.yml
Normal file
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
- include: ../shared/create_mount.yml
|
||||
vars:
|
||||
create_mount_path: "{{ item.name }}"
|
||||
create_mount_default_lease_ttl: "{{ item.default_lease_ttl }}"
|
||||
create_mount_max_lease_ttl: "{{ item.max_lease_ttl }}"
|
||||
create_mount_description: "{{ item.description }}"
|
||||
create_mount_cert_dir: "{{ item.cert_dir }}"
|
||||
create_mount_config_ca_needed: "{{ item.config_ca }}"
|
||||
with_items:
|
||||
- "{{ vault_pki_mounts.vault|combine({'config_ca': not vault_ca_cert_needed}) }}"
|
||||
- "{{ vault_pki_mounts.etcd|combine({'config_ca': not vault_etcd_ca_cert_needed}) }}"
|
10
roles/vault/tasks/bootstrap/create_roles.yml
Normal file
10
roles/vault/tasks/bootstrap/create_roles.yml
Normal file
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
- include: ../shared/create_role.yml
|
||||
vars:
|
||||
create_role_name: "{{ item.name }}"
|
||||
create_role_group: "{{ item.group }}"
|
||||
create_role_policy_rules: "{{ item.policy_rules }}"
|
||||
create_role_password: "{{ item.password }}"
|
||||
create_role_options: "{{ item.role_options }}"
|
||||
create_role_mount_path: "{{ mount.name }}"
|
||||
with_items: "{{ mount.roles }}"
|
|
@ -1,29 +1,21 @@
|
|||
---
|
||||
|
||||
- name: boostrap/gen_vault_certs | Add the vault role
|
||||
uri:
|
||||
url: "{{ vault_leader_url }}/v1/{{ vault_ca_options.common_name }}/roles/vault"
|
||||
headers: "{{ vault_headers }}"
|
||||
method: POST
|
||||
body_format: json
|
||||
body: "{{ vault_default_role_permissions }}"
|
||||
status_code: 204
|
||||
when: inventory_hostname == groups.vault|first and vault_api_cert_needed
|
||||
|
||||
- include: ../shared/issue_cert.yml
|
||||
vars:
|
||||
issue_cert_common_name: "{{ vault_pki_mounts.vault.roles[0].name }}"
|
||||
issue_cert_alt_names: "{{ groups.vault + ['localhost'] }}"
|
||||
issue_cert_hosts: "{{ groups.vault }}"
|
||||
issue_cert_ip_sans: >-
|
||||
[
|
||||
{%- for host in groups.vault -%}
|
||||
"{{ hostvars[host]['ansible_default_ipv4']['address'] }}",
|
||||
{%- if hostvars[host]['ip'] is defined -%}
|
||||
"{{ hostvars[host]['ip'] }}",
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
"127.0.0.1","::1"
|
||||
]
|
||||
issue_cert_mount_path: "{{ vault_ca_options.common_name }}"
|
||||
issue_cert_mount_path: "{{ vault_pki_mounts.vault.name }}"
|
||||
issue_cert_path: "{{ vault_cert_dir }}/api.pem"
|
||||
issue_cert_headers: "{{ hostvars[groups.vault|first]['vault_headers'] }}"
|
||||
issue_cert_role: vault
|
||||
issue_cert_role: "{{ vault_pki_mounts.vault.roles[0].name }}"
|
||||
issue_cert_url: "{{ vault_leader_url }}"
|
||||
when: vault_api_cert_needed
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
|
||||
- include: ../shared/check_vault.yml
|
||||
when: inventory_hostname in groups.vault
|
||||
|
||||
|
@ -7,9 +6,7 @@
|
|||
when: inventory_hostname in groups.vault
|
||||
|
||||
- include: ../shared/find_leader.yml
|
||||
when: inventory_hostname in groups.vault and vault_cluster_is_initialized|d()
|
||||
|
||||
## Sync Certs
|
||||
when: inventory_hostname in groups.vault and vault_cluster_is_initialized
|
||||
|
||||
- include: sync_vault_certs.yml
|
||||
when: inventory_hostname in groups.vault
|
||||
|
@ -17,64 +14,52 @@
|
|||
- include: sync_etcd_certs.yml
|
||||
when: inventory_hostname in groups.etcd
|
||||
|
||||
## Generate Certs
|
||||
|
||||
# Start a temporary instance of Vault
|
||||
- include: start_vault_temp.yml
|
||||
when: >-
|
||||
inventory_hostname == groups.vault|first and
|
||||
not vault_cluster_is_initialized
|
||||
when: inventory_hostname == groups.vault|first and not vault_cluster_is_initialized
|
||||
|
||||
# Set vault_leader_url for all nodes based on above
|
||||
- name: vault | bootstrap
|
||||
- name: vault | Set fact about vault leader url
|
||||
set_fact:
|
||||
vault_leader_url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}"
|
||||
when: not vault_cluster_is_initialized
|
||||
|
||||
# Ensure vault PKI mounts exists
|
||||
- include: ../shared/create_mount.yml
|
||||
vars:
|
||||
create_mount_path: "{{ vault_ca_options.common_name }}"
|
||||
create_mount_default_lease_ttl: "{{ vault_default_lease_ttl }}"
|
||||
create_mount_max_lease_ttl: "{{ vault_max_lease_ttl }}"
|
||||
create_mount_description: "Vault Root CA"
|
||||
create_mount_cert_dir: "{{ vault_cert_dir }}"
|
||||
create_mount_config_ca_needed: "{{ not vault_ca_cert_needed }}"
|
||||
- include: create_mounts.yml
|
||||
when: inventory_hostname == groups.vault|first
|
||||
|
||||
# Generate root CA certs for Vault if none exist
|
||||
- include: ../shared/auth_backend.yml
|
||||
vars:
|
||||
auth_backend_description: A Username/Password Auth Backend primarily used for services needing to issue certificates
|
||||
auth_backend_path: userpass
|
||||
auth_backend_type: userpass
|
||||
when: inventory_hostname == groups.vault|first
|
||||
|
||||
- include: create_roles.yml
|
||||
with_items:
|
||||
- "{{ vault_pki_mounts.vault }}"
|
||||
- "{{ vault_pki_mounts.etcd }}"
|
||||
loop_control:
|
||||
loop_var: mount
|
||||
when: inventory_hostname in groups.vault
|
||||
|
||||
- include: ../shared/gen_ca.yml
|
||||
vars:
|
||||
gen_ca_cert_dir: "{{ vault_cert_dir }}"
|
||||
gen_ca_mount_path: "{{ vault_ca_options.common_name }}"
|
||||
gen_ca_cert_dir: "{{ vault_pki_mounts.vault.cert_dir }}"
|
||||
gen_ca_mount_path: "{{ vault_pki_mounts.vault.name }}"
|
||||
gen_ca_vault_headers: "{{ vault_headers }}"
|
||||
gen_ca_vault_options: "{{ vault_ca_options.vault }}"
|
||||
when: >-
|
||||
inventory_hostname in groups.vault and
|
||||
not vault_cluster_is_initialized and
|
||||
vault_ca_cert_needed
|
||||
inventory_hostname in groups.vault
|
||||
and not vault_cluster_is_initialized
|
||||
and vault_ca_cert_needed
|
||||
|
||||
- include: ../shared/gen_ca.yml
|
||||
vars:
|
||||
gen_ca_cert_dir: "{{ vault_pki_mounts.etcd.cert_dir }}"
|
||||
gen_ca_mount_path: "{{ vault_pki_mounts.etcd.name }}"
|
||||
gen_ca_vault_headers: "{{ vault_headers }}"
|
||||
gen_ca_vault_options: "{{ vault_ca_options.etcd }}"
|
||||
when: inventory_hostname in groups.etcd and vault_etcd_ca_cert_needed
|
||||
|
||||
# Generate Vault API certs
|
||||
- include: gen_vault_certs.yml
|
||||
when: inventory_hostname in groups.vault and vault_api_cert_needed
|
||||
|
||||
# Ensure etcd PKI mounts exists
|
||||
- include: ../shared/create_mount.yml
|
||||
vars:
|
||||
create_mount_path: "{{ vault_etcd_mount_path }}"
|
||||
create_mount_default_lease_ttl: "{{ vault_etcd_default_lease_ttl }}"
|
||||
create_mount_max_lease_ttl: "{{ vault_etcd_max_lease_ttl }}"
|
||||
create_mount_description: "Etcd Root CA"
|
||||
create_mount_cert_dir: "{{ vault_etcd_cert_dir }}"
|
||||
create_mount_config_ca_needed: "{{ not vault_etcd_ca_cert_needed }}"
|
||||
when: inventory_hostname == groups.vault|first
|
||||
|
||||
# Generate root CA certs for etcd if none exist
|
||||
- include: ../shared/gen_ca.yml
|
||||
vars:
|
||||
gen_ca_cert_dir: "{{ vault_etcd_cert_dir }}"
|
||||
gen_ca_mount_path: "{{ vault_etcd_mount_path }}"
|
||||
when: inventory_hostname in groups.etcd and vault_etcd_ca_cert_needed
|
||||
|
||||
- include: create_etcd_role.yml
|
||||
|
||||
# Update all host's CA bundle, etcd CA will be added in etcd role
|
||||
- include: ca_trust.yml
|
||||
|
|
13
roles/vault/tasks/cluster/create_mounts.yml
Normal file
13
roles/vault/tasks/cluster/create_mounts.yml
Normal file
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
- include: ../shared/create_mount.yml
|
||||
vars:
|
||||
create_mount_path: "{{ item.name }}"
|
||||
create_mount_default_lease_ttl: "{{ item.default_lease_ttl }}"
|
||||
create_mount_max_lease_ttl: "{{ item.max_lease_ttl }}"
|
||||
create_mount_description: "{{ item.description }}"
|
||||
create_mount_cert_dir: "{{ item.cert_dir }}"
|
||||
create_mount_config_ca_needed: "{{ item.name != vault_pki_mounts.kube.name }}"
|
||||
with_items:
|
||||
- "{{ vault_pki_mounts.vault }}"
|
||||
- "{{ vault_pki_mounts.etcd }}"
|
||||
- "{{ vault_pki_mounts.kube }}"
|
|
@ -1,18 +1,10 @@
|
|||
---
|
||||
- include: ../shared/auth_backend.yml
|
||||
vars:
|
||||
auth_backend_description: A Username/Password Auth Backend primarily used for services needing to issue certificates
|
||||
auth_backend_path: userpass
|
||||
auth_backend_type: userpass
|
||||
when: inventory_hostname == groups.vault|first
|
||||
|
||||
- include: ../shared/create_role.yml
|
||||
vars:
|
||||
create_role_name: "{{ item.name }}"
|
||||
create_role_group: "{{ item.group }}"
|
||||
create_role_password: "{{ item.password }}"
|
||||
create_role_policy_rules: "{{ item.policy_rules }}"
|
||||
create_role_options: "{{ item.role_options }}"
|
||||
create_role_mount_path: "{{ item.mount_path }}"
|
||||
with_items:
|
||||
- "{{ vault_etcd_role }}"
|
||||
- "{{ vault_kube_role }}"
|
||||
create_role_mount_path: "{{ vault_pki_mounts.kube.name }}"
|
||||
with_items: "{{ vault_pki_mounts.kube.roles }}"
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
- include: ../shared/check_etcd.yml
|
||||
when: inventory_hostname in groups.vault
|
||||
|
||||
## Vault Cluster Setup
|
||||
|
||||
- include: configure.yml
|
||||
when: inventory_hostname in groups.vault
|
||||
|
||||
|
@ -25,42 +23,23 @@
|
|||
- include: ../shared/find_leader.yml
|
||||
when: inventory_hostname in groups.vault
|
||||
|
||||
- include: ../shared/create_mount.yml
|
||||
vars:
|
||||
create_mount_path: "{{ vault_ca_options.common_name }}"
|
||||
create_mount_default_lease_ttl: "{{ vault_default_lease_ttl }}"
|
||||
create_mount_max_lease_ttl: "{{ vault_max_lease_ttl }}"
|
||||
create_mount_description: "Vault Root CA"
|
||||
create_mount_cert_dir: "{{ vault_cert_dir }}"
|
||||
create_mount_config_ca_needed: true
|
||||
when: inventory_hostname == groups.vault|first
|
||||
|
||||
- include: ../shared/create_mount.yml
|
||||
vars:
|
||||
create_mount_path: "{{ vault_etcd_mount_path }}"
|
||||
create_mount_default_lease_ttl: "{{ vault_etcd_default_lease_ttl }}"
|
||||
create_mount_max_lease_ttl: "{{ vault_etcd_max_lease_ttl }}"
|
||||
create_mount_description: "Etcd Root CA"
|
||||
create_mount_cert_dir: "{{ vault_etcd_cert_dir }}"
|
||||
create_mount_config_ca_needed: true
|
||||
when: inventory_hostname == groups.vault|first
|
||||
|
||||
- include: ../shared/create_mount.yml
|
||||
vars:
|
||||
create_mount_path: "{{ vault_kube_mount_path }}"
|
||||
create_mount_default_lease_ttl: "{{ vault_kube_default_lease_ttl }}"
|
||||
create_mount_max_lease_ttl: "{{ vault_kube_max_lease_ttl }}"
|
||||
create_mount_description: "Kubernetes Root CA"
|
||||
create_mount_cert_dir: "{{ vault_kube_cert_dir }}"
|
||||
create_mount_config_ca_needed: false
|
||||
- include: create_mounts.yml
|
||||
when: inventory_hostname == groups.vault|first
|
||||
|
||||
- include: ../shared/gen_ca.yml
|
||||
vars:
|
||||
gen_ca_cert_dir: "{{ vault_kube_cert_dir }}"
|
||||
gen_ca_mount_path: "{{ vault_kube_mount_path }}"
|
||||
gen_ca_cert_dir: "{{ vault_pki_mounts.kube.cert_dir }}"
|
||||
gen_ca_mount_path: "{{ vault_pki_mounts.kube.name }}"
|
||||
gen_ca_vault_headers: "{{ vault_headers }}"
|
||||
gen_ca_vault_options: "{{ vault_ca_options.kube }}"
|
||||
when: inventory_hostname in groups.vault
|
||||
|
||||
## Vault Policies, Roles, and Auth Backends
|
||||
- include: ../shared/auth_backend.yml
|
||||
vars:
|
||||
auth_backend_description: A Username/Password Auth Backend primarily used for services needing to issue certificates
|
||||
auth_backend_path: userpass
|
||||
auth_backend_type: userpass
|
||||
when: inventory_hostname == groups.vault|first
|
||||
|
||||
- include: create_roles.yml
|
||||
when: inventory_hostname in groups.vault
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
|
||||
# The JSON inside JSON here is intentional (Vault API wants it)
|
||||
- name: create_role | Create a policy for the new role allowing issuing
|
||||
uri:
|
||||
|
@ -20,9 +19,10 @@
|
|||
{{ create_role_policy_rules | to_json + '\n' }}
|
||||
{%- endif -%}
|
||||
status_code: 204
|
||||
when: inventory_hostname == groups[create_role_group]|first
|
||||
delegate_to: "{{ groups.vault|first }}"
|
||||
run_once: true
|
||||
|
||||
- name: create_role | Create the new role in the {{ create_role_mount_path }} pki mount
|
||||
- name: create_role | Create {{ create_role_name }} role in the {{ create_role_mount_path }} pki mount
|
||||
uri:
|
||||
url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}/v1/{{ create_role_mount_path }}/roles/{{ create_role_name }}"
|
||||
headers: "{{ hostvars[groups.vault|first]['vault_headers'] }}"
|
||||
|
@ -35,15 +35,14 @@
|
|||
{{ create_role_options }}
|
||||
{%- endif -%}
|
||||
status_code: 204
|
||||
when: inventory_hostname == groups[create_role_group]|first
|
||||
delegate_to: "{{ groups.vault|first }}"
|
||||
run_once: true
|
||||
|
||||
## Userpass based auth method
|
||||
|
||||
- include: gen_userpass.yml
|
||||
vars:
|
||||
gen_userpass_group: "{{ create_role_group }}"
|
||||
gen_userpass_password: "{{ create_role_password|d(''|to_uuid) }}"
|
||||
gen_userpass_password: "{{ create_role_password }}"
|
||||
gen_userpass_policies: "{{ create_role_name }}"
|
||||
gen_userpass_role: "{{ create_role_name }}"
|
||||
gen_userpass_username: "{{ create_role_name }}"
|
||||
when: inventory_hostname in groups[create_role_group]
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
- name: "bootstrap/gen_ca | Generate {{ gen_ca_mount_path }} root CA"
|
||||
uri:
|
||||
url: "{{ vault_leader_url }}/v1/{{ gen_ca_mount_path }}/root/generate/exported"
|
||||
headers: "{{ vault_headers }}"
|
||||
headers: "{{ gen_ca_vault_headers }}"
|
||||
method: POST
|
||||
body_format: json
|
||||
body: "{{ vault_ca_options }}"
|
||||
body: "{{ gen_ca_vault_options }}"
|
||||
register: vault_ca_gen
|
||||
delegate_to: "{{ groups.vault|first }}"
|
||||
run_once: true
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
---
|
||||
|
||||
- name: shared/gen_userpass | Create the Username/Password combo for the role
|
||||
uri:
|
||||
url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}/v1/auth/userpass/users/{{ gen_userpass_username }}"
|
||||
|
@ -11,13 +10,13 @@
|
|||
password: "{{ gen_userpass_password }}"
|
||||
policies: "{{ gen_userpass_role }}"
|
||||
status_code: 204
|
||||
when: inventory_hostname == groups[gen_userpass_group]|first
|
||||
delegate_to: "{{ groups.vault|first }}"
|
||||
run_once: true
|
||||
|
||||
- name: shared/gen_userpass | Ensure destination directory exists
|
||||
file:
|
||||
path: "{{ vault_roles_dir }}/{{ gen_userpass_role }}"
|
||||
state: directory
|
||||
when: inventory_hostname in groups[gen_userpass_group]
|
||||
|
||||
- name: shared/gen_userpass | Copy credentials to all hosts in the group
|
||||
copy:
|
||||
|
@ -27,4 +26,3 @@
|
|||
'password': gen_userpass_password} | to_nice_json(indent=4)
|
||||
}}
|
||||
dest: "{{ vault_roles_dir }}/{{ gen_userpass_role }}/userpass"
|
||||
when: inventory_hostname in groups[gen_userpass_group]
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
# issue_cert_file_mode: Mode of the placed cert file
|
||||
# issue_cert_file_owner: Owner of the placed cert file and directory
|
||||
# issue_cert_format: Format for returned data. Can be pem, der, or pem_bundle
|
||||
# issue_cert_headers: Headers passed into the issue request
|
||||
# issue_cert_hosts: List of hosts to distribute the cert to
|
||||
# issue_cert_ip_sans: Requested IP Subject Alternative Names, in a list
|
||||
# issue_cert_mount_path: Mount point in Vault to make the request to
|
||||
|
@ -27,7 +26,47 @@
|
|||
mode: "{{ issue_cert_dir_mode | d('0755') }}"
|
||||
owner: "{{ issue_cert_file_owner | d('root') }}"
|
||||
|
||||
- name: "issue_cert | Generate the cert for {{ issue_cert_role }}"
|
||||
- name: "issue_cert | Read in the local credentials"
|
||||
command: cat {{ vault_roles_dir }}/{{ issue_cert_role }}/userpass
|
||||
register: vault_creds_cat
|
||||
delegate_to: "{{ groups.vault|first }}"
|
||||
run_once: true
|
||||
|
||||
- name: gen_certs_vault | Set facts for read Vault Creds
|
||||
set_fact:
|
||||
user_vault_creds: "{{ vault_creds_cat.stdout|from_json }}"
|
||||
delegate_to: "{{ groups.vault|first }}"
|
||||
run_once: true
|
||||
|
||||
- name: gen_certs_vault | Log into Vault and obtain an token
|
||||
uri:
|
||||
url: "{{ hostvars[groups.vault|first]['vault_leader_url'] }}/v1/auth/userpass/login/{{ user_vault_creds.username }}"
|
||||
headers:
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
method: POST
|
||||
body_format: json
|
||||
body:
|
||||
password: "{{ user_vault_creds.password }}"
|
||||
register: vault_login_result
|
||||
delegate_to: "{{ groups.vault|first }}"
|
||||
run_once: true
|
||||
|
||||
- name: gen_certs_vault | Set fact for vault_client_token
|
||||
set_fact:
|
||||
vault_client_token: "{{ vault_login_result.get('json', {}).get('auth', {}).get('client_token') }}"
|
||||
run_once: true
|
||||
|
||||
- name: gen_certs_vault | Set fact for Vault API token
|
||||
set_fact:
|
||||
issue_cert_headers:
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
X-Vault-Token: "{{ vault_client_token }}"
|
||||
run_once: true
|
||||
when: vault_client_token != ""
|
||||
|
||||
- name: "issue_cert | Generate {{ issue_cert_path }} for {{ issue_cert_role }} role"
|
||||
uri:
|
||||
url: "{{ issue_cert_url }}/v1/{{ issue_cert_mount_path|d('pki') }}/issue/{{ issue_cert_role }}"
|
||||
headers: "{{ issue_cert_headers }}"
|
||||
|
@ -69,8 +108,8 @@
|
|||
|
||||
- name: issue_cert | Copy certificate serial to all hosts
|
||||
copy:
|
||||
content: "{{ hostvars[issue_cert_hosts|first]['issue_cert_result']['json']['data']['serial_number'] }}"
|
||||
dest: "{{ issue_cert_path.rsplit('.', 1)|first }}.serial }}"
|
||||
content: "{{ issue_cert_result['json']['data']['serial_number'] }}"
|
||||
dest: "{{ issue_cert_path.rsplit('.', 1)|first }}.serial"
|
||||
group: "{{ issue_cert_file_group | d('root' )}}"
|
||||
mode: "{{ issue_cert_file_mode | d('0640') }}"
|
||||
owner: "{{ issue_cert_file_owner | d('root') }}"
|
||||
|
|
Loading…
Reference in a new issue