Browse Source

improve acme support

main
Nicolas Massé 5 years ago
parent
commit
514a3ba480
  1. 14
      README.md
  2. 20
      acme.tf
  3. 19
      cluster
  4. 16
      main.tf
  5. 18
      post-install.tf
  6. 5
      provider.tf
  7. 1
      terraform.tfvars.sample
  8. 4
      variables.tf

14
README.md

@ -36,11 +36,13 @@ make
make install
```
Install lego.
Install the acme terraform provider.
```sh
curl -Lo /tmp/lego.tgz https://github.com/go-acme/lego/releases/download/v4.3.1/lego_v4.3.1_linux_amd64.tar.gz
sudo tar zxvf /tmp/lego.tgz -C /usr/local/bin lego
git clone https://github.com/vancluever/terraform-provider-acme
cd terraform-provider-acme
mkdir -p ~/.terraform.d/plugins/vancluever/acme/2.3.0/linux_amd64/
GOBIN=$HOME/.terraform.d/plugins/vancluever/acme/2.3.0/linux_amd64/ make
```
Create the template files from their samples.
@ -57,6 +59,12 @@ Install the required Ansible collections.
ansible-galaxy collection install -r ansible/requirements.yaml
```
Initialize Terraform.
```sh
terraform init
```
### On the server
Install libvirt.

20
acme.tf

@ -0,0 +1,20 @@
resource "tls_private_key" "account_key" {
algorithm = "RSA"
rsa_bits = 2048
}
resource "acme_registration" "cluster_reg" {
account_key_pem = tls_private_key.account_key.private_key_pem
email_address = var.acme_account_email
}
resource "acme_certificate" "cluster_cert" {
account_key_pem = acme_registration.cluster_reg.account_key_pem
common_name = "api.${local.network_domain}"
subject_alternative_names = ["*.apps.${local.network_domain}"]
key_type = "2048" // RSA 2048
dns_challenge {
provider = "gandiv5"
}
}

19
cluster

@ -130,24 +130,21 @@ EOF
function post_install_le () {
local cluster_name="${1:-}"
# Generated by terraform
source "$cluster_name/dns.env"
# Get a certificate from Let's Encrypt
lego -m "nmasse@redhat.com" -d "$LE_API_HOSTNAME" -d "$LE_ROUTER_HOSTNAME" -a --dns gandiv5 run --no-bundle
cert_dn="$(openssl x509 -noout -subject -in "$cluster_name/cluster.crt")"
cert_cn="${cert_dn#subject=CN = }"
# Deploy certificate to ingress
oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" create secret tls router-certs-$(date "+%Y-%m-%d") --cert=.lego/certificates/$LE_API_HOSTNAME.crt --key=.lego/certificates/$LE_API_HOSTNAME.key -n openshift-ingress --dry-run -o yaml > "$cluster_name/router-certs.yaml"
oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" create secret tls router-certs-$(date "+%Y-%m-%d") --cert="$cluster_name/cluster.crt" --key="$cluster_name/cluster.key" -n openshift-ingress --dry-run -o yaml > "$cluster_name/router-certs.yaml"
oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" apply -f "$cluster_name/router-certs.yaml" -n openshift-ingress
oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" patch ingresscontroller default -n openshift-ingress-operator --type=merge --patch-file=/dev/fd/0 <<EOF
{"spec": { "defaultCertificate": { "name": "router-certs-$(date "+%Y-%m-%d")" }}}
EOF
# Deploy certificate to api
oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" create secret tls api-certs-$(date "+%Y-%m-%d") --cert=.lego/certificates/$LE_API_HOSTNAME.crt --key=.lego/certificates/$LE_API_HOSTNAME.key -n openshift-config --dry-run -o yaml > "$cluster_name/api-certs.yaml"
oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" create secret tls api-certs-$(date "+%Y-%m-%d") --cert="$cluster_name/cluster.crt" --key="$cluster_name/cluster.key" -n openshift-config --dry-run -o yaml > "$cluster_name/api-certs.yaml"
oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" apply -f "$cluster_name/api-certs.yaml" -n openshift-config
oc --insecure-skip-tls-verify --kubeconfig="$cluster_name/auth/kubeconfig" patch apiserver cluster --type=merge --patch-file=/dev/fd/0 <<EOF
{"spec":{"servingCerts":{"namedCertificates":[{"names":["$LE_API_HOSTNAME"],"servingCertificate":{"name": "api-certs-$(date "+%Y-%m-%d")"}}]}}}
{"spec":{"servingCerts":{"namedCertificates":[{"names":["$cert_cn"],"servingCertificate":{"name": "api-certs-$(date "+%Y-%m-%d")"}}]}}}
EOF
}
@ -205,7 +202,11 @@ function shell () {
export DEFAULT_HOST_LIST="$PWD/$cluster_name"
# Terraform
export TF_CLI_ARGS="-var-file=$cluster_name/terraform.tfvars -state=$cluster_name/terraform.tfstate"
export TF_CLI_ARGS_plan="-var-file=$cluster_name/terraform.tfvars -state=$cluster_name/terraform.tfstate"
export TF_CLI_ARGS_apply="-var-file=$cluster_name/terraform.tfvars -state=$cluster_name/terraform.tfstate"
export TF_CLI_ARGS_destroy="-var-file=$cluster_name/terraform.tfvars -state=$cluster_name/terraform.tfstate"
export TF_CLI_ARGS_state_list="-state=$cluster_name/terraform.tfstate"
export TF_CLI_ARGS_state_rm="-state=$cluster_name/terraform.tfstate"
# OpenShift
export KUBECONFIG="$PWD/$cluster_name/auth/kubeconfig"

16
main.tf

@ -21,14 +21,22 @@ terraform {
version = "2.0.0"
source = "github/go-gandi/gandi"
}
acme = {
source = "vancluever/acme"
version = "2.3.0"
}
tls = {
source = "hashicorp/tls"
version = ">=3.1.0"
}
}
}
locals {
master_nodes = [ for i in libvirt_domain.master : { name = i.name, ip = i.network_interface.0.addresses[0], role = "master" } ]
worker_nodes = [ for i in libvirt_domain.worker : { name = i.name, ip = i.network_interface.0.addresses[0], role = "worker" } ]
bootstrap_nodes = [ for i in libvirt_domain.bootstrap : { name = i.name, ip = i.network_interface.0.addresses[0], role = "bootstrap" } ]
additional_nodes = [ { name = (libvirt_domain.lb.name), ip = [ libvirt_domain.lb.network_interface.0.addresses[0], libvirt_domain.lb.network_interface.1.addresses[0] ], role = "lb" }, { name = (libvirt_domain.storage.name), ip = libvirt_domain.storage.network_interface.0.addresses[0], role = "storage" } ]
master_nodes = [for i in libvirt_domain.master : { name = i.name, ip = i.network_interface.0.addresses[0], role = "master" }]
worker_nodes = [for i in libvirt_domain.worker : { name = i.name, ip = i.network_interface.0.addresses[0], role = "worker" }]
bootstrap_nodes = [for i in libvirt_domain.bootstrap : { name = i.name, ip = i.network_interface.0.addresses[0], role = "bootstrap" }]
additional_nodes = [{ name = (libvirt_domain.lb.name), ip = [libvirt_domain.lb.network_interface.0.addresses[0], libvirt_domain.lb.network_interface.1.addresses[0]], role = "lb" }, { name = (libvirt_domain.storage.name), ip = libvirt_domain.storage.network_interface.0.addresses[0], role = "storage" }]
all_nodes = concat(local.additional_nodes, local.master_nodes, local.worker_nodes, local.bootstrap_nodes)
}

18
post-install.tf

@ -10,14 +10,20 @@ resource "local_file" "nfs_provisioner" {
file_permission = "0644"
}
resource "local_file" "dns_config" {
content = templatefile("${path.module}/templates/dns.env", { api_server = "api.${local.network_domain}", router = "*.apps.${local.network_domain}", dns_zone = var.base_domain, cluster_name = var.cluster_name })
filename = "${var.cluster_name}/dns.env"
file_permission = "0644"
}
resource "local_file" "ansible_inventory" {
content = templatefile("${path.module}/templates/inventory", { nodes = local.all_nodes, network_domain = local.network_domain, dns_server = cidrhost(var.network_ip_range, 1) })
filename = "${var.cluster_name}/inventory"
file_permission = "0644"
}
resource "local_file" "cluster_key" {
content = acme_certificate.cluster_cert.private_key_pem
filename = "${var.cluster_name}/cluster.key"
file_permission = "0600"
}
resource "local_file" "cluster_cert" {
content = "${acme_certificate.cluster_cert.certificate_pem}${acme_certificate.cluster_cert.issuer_pem}"
filename = "${var.cluster_name}/cluster.crt"
file_permission = "0644"
}

5
provider.tf

@ -5,3 +5,8 @@ provider "gandi" {
# key = "<livedns apikey>"
# sharing_id = "<sharing id>"
}
provider "acme" {
server_url = "https://acme-v02.api.letsencrypt.org/directory"
# server_url = "https://acme-staging-v02.api.letsencrypt.org/directory"
}

1
terraform.tfvars.sample

@ -3,3 +3,4 @@ external_mac_address = "02:00:00:00:00:04"
public_cluster_ip = "1.2.3.4"
cluster_name = "__CLUSTER_NAME__"
bootstrap_nodes = 1
acme_account_email = "your.username@redhat.com"

4
variables.tf

@ -136,6 +136,10 @@ variable "bootstrap_memory_size" {
default = 16 * 1024
}
variable "acme_account_email" {
type = string
}
locals {
master_format = "${var.cluster_name}-master-%02d"
worker_format = "${var.cluster_name}-worker-%02d"

Loading…
Cancel
Save