fix(octavia): switch to cert-manager issuer certs
diff --git a/atmosphere/tasks/constants.py b/atmosphere/tasks/constants.py
index 9cc9fd7..b121bff 100644
--- a/atmosphere/tasks/constants.py
+++ b/atmosphere/tasks/constants.py
@@ -341,6 +341,7 @@
HELM_RELEASE_CERT_MANAGER_VERSION = "v1.7.1"
HELM_RELEASE_CERT_MANAGER_VALUES = {
"installCRDs": True,
+ "featureGates": "AdditionalCertificateOutputFormats=true",
"volumes": [
{
"name": "etc-ssl-certs",
@@ -358,6 +359,9 @@
],
"nodeSelector": NODE_SELECTOR_CONTROL_PLANE,
"webhook": {
+ "extraArgs": [
+ "--feature-gates=AdditionalCertificateOutputFormats=true",
+ ],
"nodeSelector": NODE_SELECTOR_CONTROL_PLANE,
},
"cainjector": {
diff --git a/atmosphere/tasks/kubernetes/cert_manager.py b/atmosphere/tasks/kubernetes/cert_manager.py
index 2d2caca..40e9082 100644
--- a/atmosphere/tasks/kubernetes/cert_manager.py
+++ b/atmosphere/tasks/kubernetes/cert_manager.py
@@ -79,7 +79,15 @@
def issuer_tasks_from_config(config: config.Issuer) -> list:
- objects = []
+ objects = [
+ ApplyIssuerTask(
+ namespace=constants.NAMESPACE_OPENSTACK,
+ name="self-signed",
+ spec={
+ "selfSigned": {},
+ },
+ )
+ ]
if config.type == "acme":
spec = {
@@ -184,13 +192,6 @@
elif config.type == "self-signed":
# NOTE(mnaser): We have to setup the self-signed CA in this case
objects += [
- ApplyIssuerTask(
- namespace=constants.NAMESPACE_OPENSTACK,
- name="self-signed",
- spec={
- "selfSigned": {},
- },
- ),
ApplyCertificateTask(
namespace=constants.NAMESPACE_OPENSTACK,
name="self-signed-ca",
diff --git a/roles/openstack_helm_octavia/tasks/main.yml b/roles/openstack_helm_octavia/tasks/main.yml
index 967da01..dce8c18 100644
--- a/roles/openstack_helm_octavia/tasks/main.yml
+++ b/roles/openstack_helm_octavia/tasks/main.yml
@@ -86,6 +86,8 @@
ansible.builtin.set_fact:
_openstack_helm_octavia_controller_ip_port_list: "{{ _openstack_helm_octavia_controller_ip_port_list | d([]) + [item.openstack_ports[0].fixed_ips[0].ip_address + ':5555'] }}"
loop: "{{ _openstack_helm_octavia_health_manager_ports.results }}"
+ loop_control:
+ label: "{{ item.openstack_ports[0].name }}"
- name: Create amphora security group
openstack.cloud.security_group:
@@ -134,91 +136,61 @@
- "amphora"
register: _openstack_helm_octavia_amphora_image
-- name: Check if certificate secret exists
- kubernetes.core.k8s_info:
- kind: Secret
- name: octavia-certs
- namespace: openstack
- register: _openstack_helm_octavia_cert_secret
+- name: Create CAs & Issuers
+ kubernetes.core.k8s:
+ state: present
+ definition:
+ - apiVersion: cert-manager.io/v1
+ kind: Certificate
+ metadata:
+ name: "{{ item }}-ca"
+ namespace: openstack
+ spec:
+ isCA: true
+ commonName: "{{ item }}"
+ secretName: "{{ item }}-ca"
+ duration: 87600h
+ renewBefore: 720h
+ privateKey:
+ algorithm: ECDSA
+ size: 256
+ issuerRef:
+ name: self-signed
+ kind: Issuer
+ group: cert-manager.io
-# TODO(mnaser): we should just use cert-manager for this?
-- name: Create certificate secret
- when: (_openstack_helm_octavia_cert_secret.resources | length) == 0
- block:
- - name: Create CA private key
- community.crypto.openssl_privatekey_pipe:
- type: RSA
- register: _openstack_helm_octavia_ca_key
+ - apiVersion: cert-manager.io/v1
+ kind: Issuer
+ metadata:
+ name: "{{ item }}"
+ namespace: openstack
+ spec:
+ ca:
+ secretName: "{{ item }}-ca"
+ loop:
+ - octavia-client
+ - octavia-server
- - name: Create certificate signing request (CSR) for CA
- community.crypto.openssl_csr_pipe:
- basic_constraints:
- - 'CA:TRUE'
- basic_constraints_critical: true
- common_name: "octavia"
- key_usage:
- - "keyEncipherment"
- - "digitalSignature"
- - "keyCertSign"
- key_usage_critical: true
- organization_name: "VEXXHOST OpenStack - Octavia"
- privatekey_content: "{{ _openstack_helm_octavia_ca_key.privatekey }}"
- use_common_name_for_san: false
- register: _openstack_helm_octavia_ca_csr
-
- - name: Create self-signed CA certificate from CSR
- community.crypto.x509_certificate_pipe:
- csr_content: "{{ _openstack_helm_octavia_ca_csr.csr }}"
- entrust_not_after: "+3650d"
- privatekey_content: "{{ _openstack_helm_octavia_ca_key.privatekey }}"
- provider: selfsigned
- register: _openstack_helm_octavia_ca
-
- - name: Create client private key
- community.crypto.openssl_privatekey_pipe:
- type: RSA
- register: _openstack_helm_octavia_client_ca_key
-
- - name: Create certificate signing request (CSR) for client
- community.crypto.openssl_csr_pipe:
- common_name: "octavia-node"
- key_usage:
- - "keyEncipherment"
- - "digitalSignature"
- - "keyCertSign"
- organization_name: "VEXXHOST OpenStack - Octavia"
- privatekey_content: "{{ _openstack_helm_octavia_client_ca_key.privatekey }}"
- use_common_name_for_san: false
- register: _openstack_helm_octavia_client_csr
-
- - name: Create self-signed client certificate
- community.crypto.x509_certificate_pipe:
- csr_content: "{{ _openstack_helm_octavia_client_csr.csr }}"
- ownca_content: "{{ _openstack_helm_octavia_ca.certificate }}"
- ownca_privatekey_content: "{{ _openstack_helm_octavia_ca_key.privatekey }}"
- ownca_not_after: "+3650d"
- entrust_not_after: "+3650d"
- privatekey_content: "{{ _openstack_helm_octavia_client_ca_key.privatekey }}"
- provider: ownca
- register: _openstack_helm_octavia_client_ca
-
- - name: Createa kubernetes secret
- kubernetes.core.k8s:
- state: present
- definition:
- apiVersion: v1
- kind: Secret
- metadata:
- name: octavia-certs
- namespace: openstack
- stringData:
- ca_01.pem: |
- {{ _openstack_helm_octavia_ca.certificate }}
- cakey.pem: |
- {{ _openstack_helm_octavia_ca_key.privatekey }}
- client.pem: |
- {{ _openstack_helm_octavia_client_ca.certificate }}
- {{ _openstack_helm_octavia_client_ca_key.privatekey }}
+- name: Create certificate for Octavia clients
+ kubernetes.core.k8s:
+ state: present
+ definition:
+ apiVersion: cert-manager.io/v1
+ kind: Certificate
+ metadata:
+ name: octavia-client-certs
+ namespace: openstack
+ spec:
+ commonName: octavia-client
+ secretName: octavia-client-certs
+ additionalOutputFormats:
+ - type: CombinedPEM
+ duration: 87600h
+ renewBefore: 720h
+ issuerRef:
+ name: octavia-client
+ kind: Issuer
+ group: cert-manager.io
- name: Create admin compute quotaset
openstack.cloud.quota:
diff --git a/roles/openstack_helm_octavia/vars/main.yml b/roles/openstack_helm_octavia/vars/main.yml
index e34a990..002101f 100644
--- a/roles/openstack_helm_octavia/vars/main.yml
+++ b/roles/openstack_helm_octavia/vars/main.yml
@@ -36,67 +36,59 @@
octavia_api:
octavia_api:
volumeMounts:
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/private/cakey.pem"
- subPath: "cakey.pem"
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/ca_01.pem"
- subPath: "ca_01.pem"
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/client.pem"
- subPath: "client.pem"
+ - name: octavia-server-ca
+ mountPath: /etc/octavia/certs/server
+ - name: octavia-client-certs
+ mountPath: /etc/octavia/certs/client
volumes:
- - name: octavia-certs
+ - name: octavia-server-ca
secret:
- secretName: octavia-certs
+ secretName: octavia-server-ca
+ - name: octavia-client-certs
+ secret:
+ secretName: octavia-client-certs
octavia_worker:
octavia_worker:
volumeMounts:
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/private/cakey.pem"
- subPath: "cakey.pem"
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/ca_01.pem"
- subPath: "ca_01.pem"
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/client.pem"
- subPath: "client.pem"
+ - name: octavia-server-ca
+ mountPath: /etc/octavia/certs/server
+ - name: octavia-client-certs
+ mountPath: /etc/octavia/certs/client
volumes:
- - name: octavia-certs
+ - name: octavia-server-ca
secret:
- secretName: octavia-certs
+ secretName: octavia-server-ca
+ - name: octavia-client-certs
+ secret:
+ secretName: octavia-client-certs
octavia_housekeeping:
octavia_housekeeping:
volumeMounts:
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/private/cakey.pem"
- subPath: "cakey.pem"
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/ca_01.pem"
- subPath: "ca_01.pem"
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/client.pem"
- subPath: "client.pem"
+ - name: octavia-server-ca
+ mountPath: /etc/octavia/certs/server
+ - name: octavia-client-certs
+ mountPath: /etc/octavia/certs/client
volumes:
- - name: octavia-certs
+ - name: octavia-server-ca
secret:
- secretName: octavia-certs
+ secretName: octavia-server-ca
+ - name: octavia-client-certs
+ secret:
+ secretName: octavia-client-certs
octavia_health_manager:
octavia_health_manager:
volumeMounts:
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/private/cakey.pem"
- subPath: "cakey.pem"
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/ca_01.pem"
- subPath: "ca_01.pem"
- - name: octavia-certs
- mountPath: "/etc/octavia/certs/client.pem"
- subPath: "client.pem"
+ - name: octavia-server-ca
+ mountPath: /etc/octavia/certs/server
+ - name: octavia-client-certs
+ mountPath: /etc/octavia/certs/client
volumes:
- - name: octavia-certs
+ - name: octavia-server-ca
secret:
- secretName: octavia-certs
+ secretName: octavia-server-ca
+ - name: octavia-client-certs
+ secret:
+ secretName: octavia-client-certs
replicas:
api: 3
worker: 3
@@ -106,6 +98,8 @@
DEFAULT:
log_config_append: null
certificates:
+ ca_certificate: /etc/octavia/certs/server/ca.crt
+ ca_private_key: /etc/octavia/certs/server/tls.key
ca_private_key_passphrase: null
endpoint_type: internalURL
cinder:
@@ -116,9 +110,13 @@
amp_image_owner_id: "{{ _openstack_helm_octavia_amphora_image.image.owner }}"
amp_secgroup_list: "{{ _openstack_helm_octavia_amphora_sg.id }}"
amp_ssh_key_name: null
+ client_ca: /etc/octavia/certs/client/ca.crt
workers: 4
glance:
endpoint_type: internalURL
+ haproxy_amphora:
+ client_cert: /etc/octavia/certs/client/tls-combined.pem
+ server_ca: /etc/octavia/certs/server/ca.crt
health_manager:
controller_ip_port_list: "{{ _openstack_helm_octavia_controller_ip_port_list | join(',') }}"
heartbeat_key: "{{ openstack_helm_octavia_heartbeat_key }}"