Adds a new certification authority service (CAS) module (#2481)

This commit is contained in:
Luca Prete
2024-08-08 09:55:48 +02:00
committed by GitHub
parent 9880c0b64d
commit 092053b517
20 changed files with 664 additions and 12 deletions

View File

@@ -35,7 +35,7 @@ Currently available modules:
- **compute** - [VM/VM group](./modules/compute-vm), [MIG](./modules/compute-mig), [COS container](./modules/cloud-config-container/cos-generic-metadata/) (coredns, mysql, onprem, squid), [GKE cluster](./modules/gke-cluster-standard), [GKE hub](./modules/gke-hub), [GKE nodepool](./modules/gke-nodepool), [GCVE private cloud](./modules/gcve-private-cloud)
- **data** - <!-- [AlloyDB instance](./modules/alloydb-instance), --> [Analytics Hub](./modules/analytics-hub), [BigQuery dataset](./modules/bigquery-dataset), [Bigtable instance](./modules/bigtable-instance), [Dataplex](./modules/dataplex), [Dataplex DataScan](./modules/dataplex-datascan), [Cloud SQL instance](./modules/cloudsql-instance), [Spanner instance](./modules/spanner-instance), [Firestore](./modules/firestore), [Data Catalog Policy Tag](./modules/data-catalog-policy-tag), [Data Catalog Tag](./modules/data-catalog-tag), [Data Catalog Tag Template](./modules/data-catalog-tag-template), [Datafusion](./modules/datafusion), [Dataproc](./modules/dataproc), [GCS](./modules/gcs), [Pub/Sub](./modules/pubsub), [Dataform Repository](./modules/dataform-repository/)
- **development** - [API Gateway](./modules/api-gateway), [Apigee](./modules/apigee), [Artifact Registry](./modules/artifact-registry), [Container Registry](./modules/container-registry), [Cloud Source Repository](./modules/source-repository), [Workstation cluster](./modules/workstation-cluster)
- **security** - [Binauthz](./modules/binauthz/), [KMS](./modules/kms), [SecretManager](./modules/secret-manager), [VPC Service Control](./modules/vpc-sc), [Certificate Manager](./modules/certificate-manager/)
- **security** - [Binauthz](./modules/binauthz/), [Certificate Authority Service (CAS)](./modules/certificate-authority-service), [KMS](./modules/kms), [SecretManager](./modules/secret-manager), [VPC Service Control](./modules/vpc-sc), [Certificate Manager](./modules/certificate-manager/)
- **serverless** - [Cloud Function v1](./modules/cloud-function-v1), [Cloud Function v2](./modules/cloud-function-v2), [Cloud Run](./modules/cloud-run), [Cloud Run v2](./modules/cloud-run-v2)
For more information and usage examples see each module's README file.

View File

@@ -109,6 +109,7 @@ These modules are used in the examples included in this repository. If you are u
## Security
- [Binauthz](./binauthz/)
- [Certificate Authority Service (CAS)](./certificate-authority-service)
- [KMS](./kms)
- [SecretManager](./secret-manager)
- [VPC Service Control](./vpc-sc)

View File

@@ -0,0 +1,125 @@
# Certificate Authority Service (CAS)
The module allows you to create one or more CAs and an optional CA pool.
<!-- BEGIN TOC -->
- [Examples](#examples)
- [Basic CA infrastructure](#basic-ca-infrastructure)
- [Create custom CAs](#create-custom-cas)
- [Reference an existing CA pool](#reference-an-existing-ca-pool)
- [IAM](#iam)
- [Variables](#variables)
- [Outputs](#outputs)
<!-- END TOC -->
## Examples
### Basic CA infrastructure
This is enough to create a test CA pool and a self-signed root CA.
```hcl
module "cas" {
source = "./fabric/modules/certificate-authority-service"
project_id = var.project_id
location = "europe-west1"
ca_pool_config = {
name = "test-cas"
}
}
# tftest modules=1 resources=2 inventory=basic.yaml
```
### Create custom CAs
You can create multiple, custom CAs.
```hcl
module "cas" {
source = "./fabric/modules/certificate-authority-service"
project_id = var.project_id
location = "europe-west1"
ca_pool_config = {
name = "test-cas"
}
ca_configs = {
root_ca_1 = {
key_spec_algorithm = "RSA_PKCS1_4096_SHA256"
key_usage = {
client_auth = true
server_auth = true
}
}
root_ca_2 = {
subject = {
common_name = "test2.example.com"
organization = "Example"
}
}
}
}
# tftest modules=1 resources=3 inventory=custom_cas.yaml
```
### Reference an existing CA pool
```hcl
module "cas" {
source = "./fabric/modules/certificate-authority-service"
project_id = var.project_id
location = "europe-west1"
ca_pool_config = {
ca_pool_id = var.ca_pool_id
}
}
# tftest modules=1 resources=1 inventory=existing_ca.yaml
```
### IAM
You can assign authoritative and addittive IAM roles to identities on the CA pool, using the usual fabric interface (`iam`, `iam_bindings`, `iam_binding_addittive`, `iam_by_principals`).
```hcl
module "cas" {
source = "./fabric/modules/certificate-authority-service"
project_id = var.project_id
location = "europe-west1"
ca_pool_config = {
name = "test-cas"
}
iam = {
"roles/privateca.certificateManager" = [
var.service_account.iam_email
]
}
iam_bindings_additive = {
cert-manager = {
member = "group:${var.group_email}"
role = "roles/privateca.certificateManager"
}
}
}
# tftest modules=1 resources=4 inventory=iam.yaml
```
<!-- BEGIN TFDOC -->
## Variables
| name | description | type | required | default |
|---|---|:---:|:---:|:---:|
| [ca_pool_config](variables.tf#L116) | The CA pool config. If you pass ca_pool_id, an existing pool is used. | <code title="object&#40;&#123;&#10; ca_pool_id &#61; optional&#40;string, null&#41;&#10; name &#61; optional&#40;string, null&#41;&#10; tier &#61; optional&#40;string, &#34;DEVOPS&#34;&#41;&#10;&#125;&#41;">object&#40;&#123;&#8230;&#125;&#41;</code> | ✓ | |
| [location](variables.tf#L140) | The location of the CAs. | <code>string</code> | ✓ | |
| [project_id](variables.tf#L145) | Project id. | <code>string</code> | ✓ | |
| [ca_configs](variables.tf#L17) | The CA configurations. | <code title="map&#40;object&#40;&#123;&#10; deletion_protection &#61; optional&#40;string, true&#41;&#10; type &#61; optional&#40;string, &#34;SELF_SIGNED&#34;&#41;&#10; is_ca &#61; optional&#40;bool, true&#41;&#10; lifetime &#61; optional&#40;string, null&#41;&#10; pem_ca_certificate &#61; optional&#40;string, null&#41;&#10; ignore_active_certificates_on_deletion &#61; optional&#40;bool, false&#41;&#10; skip_grace_period &#61; optional&#40;bool, true&#41;&#10; labels &#61; optional&#40;map&#40;string&#41;, &#123;&#125;&#41;&#10; gcs_bucket &#61; optional&#40;string, null&#41;&#10; key_spec &#61; optional&#40;object&#40;&#123;&#10; algorithm &#61; optional&#40;string, &#34;RSA_PKCS1_2048_SHA256&#34;&#41;&#10; kms_key_id &#61; optional&#40;string, null&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; key_usage &#61; optional&#40;object&#40;&#123;&#10; cert_sign &#61; optional&#40;bool, true&#41;&#10; client_auth &#61; optional&#40;bool, false&#41;&#10; code_signing &#61; optional&#40;bool, false&#41;&#10; content_commitment &#61; optional&#40;bool, false&#41;&#10; crl_sign &#61; optional&#40;bool, true&#41;&#10; data_encipherment &#61; optional&#40;bool, false&#41;&#10; decipher_only &#61; optional&#40;bool, false&#41;&#10; digital_signature &#61; optional&#40;bool, false&#41;&#10; email_protection &#61; optional&#40;bool, false&#41;&#10; encipher_only &#61; optional&#40;bool, false&#41;&#10; key_agreement &#61; optional&#40;bool, false&#41;&#10; key_encipherment &#61; optional&#40;bool, true&#41;&#10; ocsp_signing &#61; optional&#40;bool, false&#41;&#10; server_auth &#61; optional&#40;bool, true&#41;&#10; time_stamping &#61; optional&#40;bool, false&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; subject &#61; optional&#40;object&#40;&#123;&#10; common_name &#61; string&#10; organization &#61; string&#10; country_code &#61; optional&#40;string&#41;&#10; locality &#61; optional&#40;string&#41;&#10; organizational_unit &#61; optional&#40;string&#41;&#10; postal_code &#61; optional&#40;string&#41;&#10; province &#61; optional&#40;string&#41;&#10; street_address &#61; optional&#40;string&#41;&#10; &#125;&#41;, &#123;&#10; common_name &#61; &#34;test.example.com&#34;&#10; organization &#61; &#34;Test Example&#34;&#10; &#125;&#41;&#10; subject_alt_name &#61; optional&#40;object&#40;&#123;&#10; dns_names &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; email_addresses &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; ip_addresses &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; uris &#61; optional&#40;list&#40;string&#41;, &#91;&#93;&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10; subordinate_config &#61; optional&#40;object&#40;&#123;&#10; root_ca_id &#61; optional&#40;string&#41;&#10; pem_issuer_certificates &#61; optional&#40;list&#40;string&#41;&#41;&#10; &#125;&#41;, &#123;&#125;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code title="&#123;&#10; test-ca &#61; &#123;&#125;&#10;&#125;">&#123;&#8230;&#125;</code> |
| [iam](variables-iam.tf#L17) | IAM bindings in {ROLE => [MEMBERS]} format. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_bindings](variables-iam.tf#L24) | Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary. | <code title="map&#40;object&#40;&#123;&#10; members &#61; list&#40;string&#41;&#10; role &#61; string&#10; condition &#61; optional&#40;object&#40;&#123;&#10; expression &#61; string&#10; title &#61; string&#10; description &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_bindings_additive](variables-iam.tf#L39) | Individual additive IAM bindings. Keys are arbitrary. | <code title="map&#40;object&#40;&#123;&#10; member &#61; string&#10; role &#61; string&#10; condition &#61; optional&#40;object&#40;&#123;&#10; expression &#61; string&#10; title &#61; string&#10; description &#61; optional&#40;string&#41;&#10; &#125;&#41;&#41;&#10;&#125;&#41;&#41;">map&#40;object&#40;&#123;&#8230;&#125;&#41;&#41;</code> | | <code>&#123;&#125;</code> |
| [iam_by_principals](variables-iam.tf#L54) | Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable. | <code>map&#40;list&#40;string&#41;&#41;</code> | | <code>&#123;&#125;</code> |
## Outputs
| name | description | sensitive |
|---|---|:---:|
| [ca_ids](outputs.tf#L17) | The CA ids. | |
| [ca_pool_id](outputs.tf#L25) | The CA pool id. | |
| [cas](outputs.tf#L30) | The CAs. | |
<!-- END TFDOC -->

View File

@@ -0,0 +1,71 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
# tfdoc:file:description IAM bindings.
locals {
_iam_principal_roles = distinct(flatten(values(var.iam_by_principals)))
_iam_principals = {
for r in local._iam_principal_roles : r => [
for k, v in var.iam_by_principals :
k if try(index(v, r), null) != null
]
}
iam = {
for role in distinct(concat(keys(var.iam), keys(local._iam_principals))) :
role => concat(
try(var.iam[role], []),
try(local._iam_principals[role], [])
)
}
}
resource "google_privateca_ca_pool_iam_binding" "authoritative" {
for_each = local.iam
ca_pool = local.ca_pool_id
role = each.key
members = each.value
}
resource "google_privateca_ca_pool_iam_binding" "bindings" {
for_each = var.iam_bindings
ca_pool = local.ca_pool_id
role = each.value.role
members = each.value.members
dynamic "condition" {
for_each = each.value.condition == null ? [] : [""]
content {
expression = each.value.condition.expression
title = each.value.condition.title
description = each.value.condition.description
}
}
}
resource "google_privateca_ca_pool_iam_member" "bindings" {
for_each = var.iam_bindings_additive
ca_pool = local.ca_pool_id
role = each.value.role
member = each.value.member
dynamic "condition" {
for_each = each.value.condition == null ? [] : [""]
content {
expression = each.value.condition.expression
title = each.value.condition.title
description = each.value.condition.description
}
}
}

View File

@@ -0,0 +1,104 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
locals {
ca_pool_id = coalesce(
var.ca_pool_config.ca_pool_id == null,
try(google_privateca_ca_pool.ca_pool[0].name, null)
)
}
resource "google_privateca_ca_pool" "ca_pool" {
count = var.ca_pool_config.ca_pool_id == null ? 1 : 0
name = var.ca_pool_config.name
project = var.project_id
location = "europe-west8"
tier = "DEVOPS"
}
resource "google_privateca_certificate_authority" "cas" {
for_each = var.ca_configs
pool = local.ca_pool_id
certificate_authority_id = each.key
project = var.project_id
location = var.location
type = each.value.type
deletion_protection = each.value.deletion_protection
lifetime = each.value.lifetime
pem_ca_certificate = each.value.pem_ca_certificate
ignore_active_certificates_on_deletion = each.value.ignore_active_certificates_on_deletion
skip_grace_period = each.value.skip_grace_period
gcs_bucket = each.value.gcs_bucket
labels = each.value.labels
config {
subject_config {
subject {
common_name = each.value.subject.common_name
country_code = each.value.subject.country_code
organizational_unit = each.value.subject.organizational_unit
locality = each.value.subject.locality
organization = each.value.subject.organization
province = each.value.subject.province
street_address = each.value.subject.street_address
postal_code = each.value.subject.postal_code
}
subject_alt_name {
dns_names = each.value.subject_alt_name.dns_names
email_addresses = each.value.subject_alt_name.email_addresses
ip_addresses = each.value.subject_alt_name.ip_addresses
uris = each.value.subject_alt_name.uris
}
}
x509_config {
ca_options {
is_ca = each.value.is_ca
}
key_usage {
base_key_usage {
cert_sign = each.value.key_usage.cert_sign
content_commitment = each.value.key_usage.content_commitment
crl_sign = each.value.key_usage.crl_sign
data_encipherment = each.value.key_usage.data_encipherment
decipher_only = each.value.key_usage.decipher_only
digital_signature = each.value.key_usage.digital_signature
encipher_only = each.value.key_usage.encipher_only
key_agreement = each.value.key_usage.key_agreement
key_encipherment = each.value.key_usage.key_encipherment
}
extended_key_usage {
client_auth = each.value.key_usage.client_auth
code_signing = each.value.key_usage.code_signing
email_protection = each.value.key_usage.email_protection
ocsp_signing = each.value.key_usage.ocsp_signing
server_auth = each.value.key_usage.server_auth
time_stamping = each.value.key_usage.time_stamping
}
}
}
}
key_spec {
algorithm = each.value.key_spec.algorithm
cloud_kms_key_version = each.value.key_spec.kms_key_id
}
subordinate_config {
certificate_authority = each.value.subordinate_config.root_ca_id
pem_issuer_chain {
pem_certificates = each.value.subordinate_config.pem_issuer_certificates
}
}
}

View File

@@ -0,0 +1,36 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
output "ca_ids" {
description = "The CA ids."
value = {
for k, v in google_privateca_certificate_authority.cas
: k => v.id
}
}
output "ca_pool_id" {
description = "The CA pool id."
value = local.ca_pool_id
}
output "cas" {
description = "The CAs."
value = {
for k, v in google_privateca_certificate_authority.cas
: k => v
}
}

View File

@@ -0,0 +1,59 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
variable "iam" {
description = "IAM bindings in {ROLE => [MEMBERS]} format."
type = map(list(string))
default = {}
nullable = false
}
variable "iam_bindings" {
description = "Authoritative IAM bindings in {KEY => {role = ROLE, members = [], condition = {}}}. Keys are arbitrary."
type = map(object({
members = list(string)
role = string
condition = optional(object({
expression = string
title = string
description = optional(string)
}))
}))
nullable = false
default = {}
}
variable "iam_bindings_additive" {
description = "Individual additive IAM bindings. Keys are arbitrary."
type = map(object({
member = string
role = string
condition = optional(object({
expression = string
title = string
description = optional(string)
}))
}))
nullable = false
default = {}
}
variable "iam_by_principals" {
description = "Authoritative IAM binding in {PRINCIPAL => [ROLES]} format. Principals need to be statically defined to avoid cycle errors. Merged internally with the `iam` variable."
type = map(list(string))
default = {}
nullable = false
}

View File

@@ -0,0 +1,148 @@
/**
* Copyright 2024 Google LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
variable "ca_configs" {
description = "The CA configurations."
type = map(object({
deletion_protection = optional(string, true)
type = optional(string, "SELF_SIGNED")
is_ca = optional(bool, true)
lifetime = optional(string, null)
pem_ca_certificate = optional(string, null)
ignore_active_certificates_on_deletion = optional(bool, false)
skip_grace_period = optional(bool, true)
labels = optional(map(string), {})
gcs_bucket = optional(string, null)
key_spec = optional(object({
algorithm = optional(string, "RSA_PKCS1_2048_SHA256")
kms_key_id = optional(string, null)
}), {})
key_usage = optional(object({
cert_sign = optional(bool, true)
client_auth = optional(bool, false)
code_signing = optional(bool, false)
content_commitment = optional(bool, false)
crl_sign = optional(bool, true)
data_encipherment = optional(bool, false)
decipher_only = optional(bool, false)
digital_signature = optional(bool, false)
email_protection = optional(bool, false)
encipher_only = optional(bool, false)
key_agreement = optional(bool, false)
key_encipherment = optional(bool, true)
ocsp_signing = optional(bool, false)
server_auth = optional(bool, true)
time_stamping = optional(bool, false)
}), {})
subject = optional(object({
common_name = string
organization = string
country_code = optional(string)
locality = optional(string)
organizational_unit = optional(string)
postal_code = optional(string)
province = optional(string)
street_address = optional(string)
}), {
common_name = "test.example.com"
organization = "Test Example"
})
subject_alt_name = optional(object({
dns_names = optional(list(string), [])
email_addresses = optional(list(string), [])
ip_addresses = optional(list(string), [])
uris = optional(list(string), [])
}), {})
subordinate_config = optional(object({
root_ca_id = optional(string)
pem_issuer_certificates = optional(list(string))
}), {})
}))
nullable = false
default = {
test-ca = {}
}
validation {
condition = (
length([
for _, v in var.ca_configs
: v.type
if v.type != null
&& !contains(["SELF_SIGNED", "SUBORDINATE"], v.type)
]) == 0
)
error_message = "Type can only be `SELF_SIGNED` or `SUBORDINATE`."
}
validation {
condition = (
length([
for _, v in var.ca_configs
: v.key_spec.algorithm
if v.key_spec.algorithm != null
&& !contains([
"EC_P256_SHA256",
"EC_P384_SHA384",
"RSA_PSS_2048_SHA256",
"RSA_PSS_3072_SHA256",
"RSA_PSS_4096_SHA256",
"RSA_PKCS1_2048_SHA256",
"RSA_PKCS1_3072_SHA256",
"RSA_PKCS1_4096_SHA256",
"SIGN_HASH_ALGORITHM_UNSPECIFIED"
], v.key_spec.algorithm)
]) == 0
)
error_message = <<EOT
Algorithm can only be `SIGN_HASH_ALGORITHM_UNSPECIFIED`,
`RSA_PSS_2048_SHA256`, `RSA_PSS_3072_SHA256`, `RSA_PSS_4096_SHA256`, `RSA_PKCS1_2048_SHA256`,
`RSA_PKCS1_3072_SHA256`, `RSA_PKCS1_4096_SHA256`, `EC_P256_SHA256`, `EC_P384_SHA384`.
EOT
}
}
variable "ca_pool_config" {
description = "The CA pool config. If you pass ca_pool_id, an existing pool is used."
type = object({
ca_pool_id = optional(string, null)
name = optional(string, null)
tier = optional(string, "DEVOPS")
})
validation {
condition = (
var.ca_pool_config.ca_pool_id != null ||
var.ca_pool_config.name != null
)
error_message = "Tier can only be `DEVOPS` or `ENTERPRISE`."
}
validation {
condition = (
var.ca_pool_config.tier == "DEVOPS" ||
var.ca_pool_config.tier == "ENTERPRISE"
)
error_message = "Tier can only be `DEVOPS` or `ENTERPRISE`."
}
nullable = false
}
variable "location" {
description = "The location of the CAs."
type = string
}
variable "project_id" {
description = "Project id."
type = string
}

View File

@@ -0,0 +1,27 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
terraform {
required_version = ">= 1.7.4"
required_providers {
google = {
source = "hashicorp/google"
version = ">= 5.40.0, < 6.0.0" # tftest
}
google-beta = {
source = "hashicorp/google-beta"
version = ">= 5.40.0, < 6.0.0" # tftest
}
}
}

View File

@@ -22,6 +22,10 @@ variable "billing_account_id" {
default = "123456-123456-123456"
}
variable "ca_pool_id" {
default = "ca-pool-id"
}
variable "group_email" {
default = "organization-admins@example.org"
}
@@ -72,8 +76,8 @@ variable "regions" {
variable "service_account" {
default = {
id = "service_account_id"
email = "service_account_email"
iam_email = "service_account_iam_email"
email = "sa1@sa.example"
iam_email = "serviceAccount:sa1@sa.example"
}
}

View File

@@ -0,0 +1,19 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
counts:
google_privateca_ca_pool: 1
google_privateca_certificate_authority: 1
modules: 1
resources: 2

View File

@@ -0,0 +1,19 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
counts:
google_privateca_ca_pool: 1
google_privateca_certificate_authority: 2
modules: 1
resources: 3

View File

@@ -0,0 +1,18 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
counts:
google_privateca_certificate_authority: 1
modules: 1
resources: 1

View File

@@ -0,0 +1,21 @@
# Copyright 2024 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
counts:
google_privateca_ca_pool: 1
google_privateca_certificate_authority: 1
google_privateca_ca_pool_iam_binding: 1
google_privateca_ca_pool_iam_member: 1
modules: 1
resources: 4

View File

@@ -33,7 +33,7 @@ values:
liveness_probe: []
volume_mounts: []
working_dir: null
service_account_name: service_account_email
service_account_name: sa1@sa.example
volumes: []
counts:

View File

@@ -22,11 +22,11 @@ values:
module.folder.google_folder_iam_binding.authoritative["roles/owner"]:
condition: []
members:
- serviceAccount:service_account_email
- serviceAccount:sa1@sa.example
role: roles/owner
module.folder.google_folder_iam_member.bindings["am1-storage-admin"]:
condition: []
member: serviceAccount:service_account_email
member: serviceAccount:sa1@sa.example
role: roles/storage.admin
counts:
google_assured_workloads_workload: 1

View File

@@ -21,7 +21,7 @@ values:
condition: []
members:
- group:organization-admins@example.org
- serviceAccount:service_account_email
- serviceAccount:sa1@sa.example
role: roles/owner
module.folder.google_folder_iam_binding.authoritative["roles/resourcemanager.folderAdmin"]:
condition: []
@@ -35,7 +35,7 @@ values:
role: roles/resourcemanager.projectCreator
module.folder.google_folder_iam_member.bindings["am1-storage-admin"]:
condition: []
member: serviceAccount:service_account_email
member: serviceAccount:sa1@sa.example
role: roles/storage.admin
counts:

View File

@@ -32,7 +32,7 @@ values:
module.vpc-host.google_compute_subnetwork_iam_binding.authoritative["europe-west1/subnet-1.roles/compute.networkUser"]:
condition: []
members:
- serviceAccount:service_account_email
- serviceAccount:sa1@sa.example
project: project-id
region: europe-west1
role: roles/compute.networkUser
@@ -40,7 +40,7 @@ values:
module.vpc-host.google_compute_subnetwork_iam_binding.authoritative["europe-west1/subnet-1.roles/compute.securityAdmin"]:
condition: []
members:
- serviceAccount:service_account_email
- serviceAccount:sa1@sa.example
project: project-id
region: europe-west1
role: roles/compute.securityAdmin

View File

@@ -23,7 +23,7 @@ values:
module.pubsub.google_pubsub_topic_iam_binding.authoritative["roles/pubsub.subscriber"]:
condition: []
members:
- serviceAccount:service_account_email
- serviceAccount:sa1@sa.example
project: project-id
role: roles/pubsub.subscriber
topic: my-topic

View File

@@ -33,7 +33,7 @@ values:
module.pubsub.google_pubsub_subscription_iam_binding.authoritative["test-1.roles/pubsub.subscriber"]:
condition: []
members:
- serviceAccount:service_account_email
- serviceAccount:sa1@sa.example
project: project-id
role: roles/pubsub.subscriber
subscription: test-1