diff --git a/modules/certificate-manager/README.md b/modules/certificate-manager/README.md index 1e7c3cf46..4445b1f0c 100644 --- a/modules/certificate-manager/README.md +++ b/modules/certificate-manager/README.md @@ -2,9 +2,17 @@ This module allows you to create a certificate manager map and associated entries, certificates, DNS authorizations and issueance configs. Map and associated entries creation is optional. -## Examples + +- [Self-managed certificate](#self-managed-certificate) +- [Certificate map with 1 entry with 1 self-managed certificate](#certificate-map-with-1-entry-with-1-self-managed-certificate) +- [Certificate map with 1 entry with 1 managed certificate with load balancer authorization](#certificate-map-with-1-entry-with-1-managed-certificate-with-load-balancer-authorization) +- [Certificate map with 1 entry with 1 managed certificate with DNS authorization](#certificate-map-with-1-entry-with-1-managed-certificate-with-dns-authorization) +- [Certificate map with 1 entry with 1 managed certificate with issued by a CA Service instance](#certificate-map-with-1-entry-with-1-managed-certificate-with-issued-by-a-ca-service-instance) +- [Variables](#variables) +- [Outputs](#outputs) + -### Self-managed certificate +## Self-managed certificate ```hcl resource "tls_private_key" "private_key" { @@ -41,7 +49,7 @@ module "certificate-manager" { # tftest modules=1 resources=3 inventory=self-managed-cert.yaml ``` -### Certificate map with 1 entry with 1 self-managed certificate +## Certificate map with 1 entry with 1 self-managed certificate ```hcl resource "tls_private_key" "private_key" { @@ -91,7 +99,7 @@ module "certificate-manager" { ``` -### Certificate map with 1 entry with 1 managed certificate with load balancer authorization +## Certificate map with 1 entry with 1 managed certificate with load balancer authorization ```hcl module "certificate-manager" { @@ -120,7 +128,7 @@ module "certificate-manager" { # tftest modules=1 resources=3 inventory=map-with-managed-cert-lb-authz.yaml ``` -### Certificate map with 1 entry with 1 managed certificate with DNS authorization +## Certificate map with 1 entry with 1 managed certificate with DNS authorization ```hcl module "certificate-manager" { @@ -156,52 +164,30 @@ module "certificate-manager" { # tftest modules=1 resources=4 inventory=map-with-managed-cert-dns-authz.yaml ``` -### Certificate map with 1 entry with 1 managed certificate with issued by a CA Service instance +## Certificate map with 1 entry with 1 managed certificate with issued by a CA Service instance ```hcl -resource "google_privateca_ca_pool" "pool" { - name = "ca-pool" - project = var.project_id - location = "us-central1" - tier = "ENTERPRISE" -} -resource "google_privateca_certificate_authority" "ca_authority" { - project = var.project_id - location = "us-central1" - pool = google_privateca_ca_pool.pool.name - certificate_authority_id = "ca-authority" - config { - subject_config { - subject { - organization = "My Company" - common_name = "my-company-authority" - } - subject_alt_name { - dns_names = ["mycompany.org"] - } +module "cas" { + source = "./fabric/modules/certificate-authority-service" + project_id = var.project_id + location = "europe-west1" + ca_pool_config = { + create_pool = { + name = "test-ca" } - x509_config { - ca_options { - is_ca = true + } + ca_configs = { + root_ca = { + subject = { + common_name = "example.com" + organization = "Example" } - key_usage { - base_key_usage { - cert_sign = true - crl_sign = true - } - extended_key_usage { - server_auth = true - } + subject_alt_name = { + dns_names = ["example.com"] } } } - key_spec { - algorithm = "RSA_PKCS1_4096_SHA256" - } - deletion_protection = false - skip_grace_period = true - ignore_active_certificates_on_deletion = true } module "certificate-manager" { @@ -211,46 +197,41 @@ module "certificate-manager" { name = "my-certificate-map" description = "My certificate map" entries = { - mydomain-mycompany-org = { - certificates = [ - "my-certificate-1" - ] - matcher = "PRIMARY" + cert-0 = { + certificates = ["cert-0"] + matcher = "PRIMARY" } } } certificates = { - my-certificate-1 = { + cert-0 = { managed = { - domains = ["mydomain.mycompany.org"] - issuance_config = "my-issuance-config" + domains = ["cert-0.example.com"] + issuance_config = "config-0" } } } issuance_configs = { - my-issuance-config = { - ca_pool = google_privateca_ca_pool.pool.id + config-0 = { + ca_pool = module.cas.ca_pool_id key_algorithm = "ECDSA_P256" lifetime = "1814400s" rotation_window_percentage = 34 } } - depends_on = [ - google_privateca_certificate_authority.ca_authority - ] } -# tftest modules=1 resources=6 inventory=map-with-managed-cert-ca-service.yaml +# tftest modules=2 resources=6 inventory=map-with-managed-cert-ca-service.yaml ``` ## Variables | name | description | type | required | default | |---|---|:---:|:---:|:---:| -| [project_id](variables.tf#L103) | Project id. | string | ✓ | | +| [project_id](variables.tf#L113) | Project id. | string | ✓ | | | [certificates](variables.tf#L17) | Certificates. | map(object({…})) | | {} | -| [dns_authorizations](variables.tf#L53) | DNS authorizations. | map(object({…})) | | {} | -| [issuance_configs](variables.tf#L66) | Issuance configs. | map(object({…})) | | {} | -| [map](variables.tf#L81) | Map attributes. | object({…}) | | null | +| [dns_authorizations](variables.tf#L63) | DNS authorizations. | map(object({…})) | | {} | +| [issuance_configs](variables.tf#L76) | Issuance configs. | map(object({…})) | | {} | +| [map](variables.tf#L91) | Map attributes. | object({…}) | | null | ## Outputs diff --git a/modules/certificate-manager/variables.tf b/modules/certificate-manager/variables.tf index d70169278..60478ca93 100644 --- a/modules/certificate-manager/variables.tf +++ b/modules/certificate-manager/variables.tf @@ -33,21 +33,31 @@ variable "certificates" { })) default = {} nullable = false - validation { - condition = alltrue([for k, v in var.certificates : ( - v.self_managed != null && v.managed == null - || v.self_managed == null && v.managed != null - )]) + condition = alltrue([ + for k, v in var.certificates : ( + (v.self_managed == null ? 0 : 1) + (v.managed == null ? 0 : 1) == 1 + ) + ]) error_message = "Either a self-managed or a managed configuration must be specified for a certificate." } validation { - condition = alltrue([for k, v in var.certificates : v.managed == null ? true : - !(v.managed.dns_authorizations != null - && v.managed.issuance_config != null) + condition = alltrue([ + for k, v in var.certificates : + try(v.managed.issuance_config, null) == null || + try(v.managed.dns_authorizations, null) == null ]) error_message = "Both DNS authorizations and issuance cannot be specified." } + validation { + condition = alltrue([ + for k, v in var.certificates : v.scope == null || contains( + ["ALL_REGIONS", "CLIENT_AUTH", "DEFAULT", "EDGE_CACHE"], + coalesce(v.scope, "-") + ) + ]) + error_message = "Invalid certificate scope." + } } variable "dns_authorizations" { diff --git a/tests/modules/certificate_manager/examples/map-with-managed-cert-ca-service.yaml b/tests/modules/certificate_manager/examples/map-with-managed-cert-ca-service.yaml index 9dde520f1..81043c989 100644 --- a/tests/modules/certificate_manager/examples/map-with-managed-cert-ca-service.yaml +++ b/tests/modules/certificate_manager/examples/map-with-managed-cert-ca-service.yaml @@ -13,31 +13,35 @@ # limitations under the License. values: - google_privateca_ca_pool.pool: + module.cas.google_privateca_ca_pool.default[0]: + effective_labels: + goog-terraform-provisioned: 'true' issuance_policy: [] labels: null - location: us-central1 - name: ca-pool + location: europe-west1 + name: test-ca project: project-id publishing_options: [] - tier: ENTERPRISE + terraform_labels: + goog-terraform-provisioned: 'true' + tier: DEVOPS timeouts: null - google_privateca_certificate_authority.ca_authority: - certificate_authority_id: ca-authority + module.cas.google_privateca_certificate_authority.default["root_ca"]: + certificate_authority_id: root_ca config: - subject_config: - subject: - - common_name: my-company-authority + - common_name: example.com country_code: null locality: null - organization: My Company + organization: Example organizational_unit: null postal_code: null province: null street_address: null subject_alt_name: - dns_names: - - mycompany.org + - example.com email_addresses: null ip_addresses: null uris: null @@ -53,81 +57,101 @@ values: key_usage: - base_key_usage: - cert_sign: true - content_commitment: null + content_commitment: false crl_sign: true - data_encipherment: null - decipher_only: null - digital_signature: null - encipher_only: null - key_agreement: null - key_encipherment: null + data_encipherment: false + decipher_only: false + digital_signature: false + encipher_only: false + key_agreement: false + key_encipherment: true extended_key_usage: - - client_auth: null - code_signing: null - email_protection: null - ocsp_signing: null + - client_auth: false + code_signing: false + email_protection: false + ocsp_signing: false server_auth: true - time_stamping: null + time_stamping: false unknown_extended_key_usages: [] name_constraints: [] policy_ids: [] - deletion_protection: false + deletion_protection: true desired_state: null + effective_labels: + goog-terraform-provisioned: 'true' gcs_bucket: null - ignore_active_certificates_on_deletion: true + ignore_active_certificates_on_deletion: false key_spec: - - algorithm: RSA_PKCS1_4096_SHA256 + - algorithm: RSA_PKCS1_2048_SHA256 cloud_kms_key_version: null labels: null lifetime: 315360000s - location: us-central1 + location: europe-west1 pem_ca_certificate: null - pool: ca-pool project: project-id skip_grace_period: true subordinate_config: [] + terraform_labels: + goog-terraform-provisioned: 'true' timeouts: null type: SELF_SIGNED - module.certificate-manager.google_certificate_manager_certificate.certificates["my-certificate-1"]: + user_defined_access_urls: [] + module.certificate-manager.google_certificate_manager_certificate.certificates["cert-0"]: description: null + effective_labels: + goog-terraform-provisioned: 'true' labels: null location: global managed: - dns_authorizations: null domains: - - mydomain.mycompany.org - name: my-certificate-1 + - cert-0.example.com + name: cert-0 project: project-id scope: null self_managed: [] + terraform_labels: + goog-terraform-provisioned: 'true' timeouts: null - module.certificate-manager.google_certificate_manager_certificate_issuance_config.default["my-issuance-config"]: + module.certificate-manager.google_certificate_manager_certificate_issuance_config.default["config-0"]: certificate_authority_config: - certificate_authority_service_config: - {} description: null + effective_labels: + goog-terraform-provisioned: 'true' key_algorithm: ECDSA_P256 labels: null lifetime: 1814400s location: global - name: my-issuance-config + name: config-0 project: project-id rotation_window_percentage: 34 + terraform_labels: + goog-terraform-provisioned: 'true' timeouts: null module.certificate-manager.google_certificate_manager_certificate_map.map[0]: description: My certificate map + effective_labels: + goog-terraform-provisioned: 'true' labels: null name: my-certificate-map project: project-id + terraform_labels: + goog-terraform-provisioned: 'true' timeouts: null - module.certificate-manager.google_certificate_manager_certificate_map_entry.entries["mydomain-mycompany-org"]: + module.certificate-manager.google_certificate_manager_certificate_map_entry.entries["cert-0"]: description: null + effective_labels: + goog-terraform-provisioned: 'true' hostname: null labels: null map: my-certificate-map matcher: PRIMARY - name: mydomain-mycompany-org + name: cert-0 project: project-id + terraform_labels: + goog-terraform-provisioned: 'true' timeouts: null counts: @@ -137,5 +161,5 @@ counts: google_certificate_manager_certificate_map_entry: 1 google_privateca_ca_pool: 1 google_privateca_certificate_authority: 1 - modules: 1 - resources: 6 \ No newline at end of file + modules: 2 + resources: 6