Allow skipping data source in service account module (#3450)
* test implementation * wip * service account reuse * fix fast stage test * revert cicd changes * remove unused dep * add comment on extra condition
This commit is contained in:
committed by
GitHub
parent
7b272da6b6
commit
7ea9612b07
@@ -138,8 +138,8 @@ module "service-account-with-tags" {
|
||||
| [iam_storage_roles](variables-iam.tf#L103) | Storage roles granted to this service account, by bucket name. | <code>map(list(string))</code> | | <code>{}</code> |
|
||||
| [prefix](variables.tf#L60) | Prefix applied to service account names. | <code>string</code> | | <code>null</code> |
|
||||
| [project_number](variables.tf#L75) | Project number of var.project_id. Set this to avoid permadiffs when creating tag bindings. | <code>string</code> | | <code>null</code> |
|
||||
| [service_account_create](variables.tf#L81) | Create service account. When set to false, uses a data source to reference an existing service account. | <code>bool</code> | | <code>true</code> |
|
||||
| [tag_bindings](variables.tf#L88) | Tag bindings for this service accounts, in key => tag value id format. | <code>map(string)</code> | | <code>{}</code> |
|
||||
| [service_account_reuse](variables.tf#L81) | Reuse existing service account if not null. Data source can be forced disabled if tag bindings are not used, or unique id is set. | <code title="object({ use_data_source = optional(bool, true) attributes = optional(object({ unique_id = string })) })">object({…})</code> | | <code>null</code> |
|
||||
| [tag_bindings](variables.tf#L92) | Tag bindings for this service accounts, in key => tag value id format. | <code>map(string)</code> | | <code>{}</code> |
|
||||
|
||||
## Outputs
|
||||
|
||||
@@ -150,4 +150,5 @@ module "service-account-with-tags" {
|
||||
| [id](outputs.tf#L33) | Fully qualified service account id. | |
|
||||
| [name](outputs.tf#L41) | Service account name. | |
|
||||
| [service_account](outputs.tf#L49) | Service account resource. | |
|
||||
| [unique_id](outputs.tf#L54) | Fully qualified service account id. | |
|
||||
<!-- END TFDOC -->
|
||||
|
||||
@@ -37,20 +37,30 @@ locals {
|
||||
"projects/${local.project_id}/serviceAccounts/${local.static_email}"
|
||||
)
|
||||
service_account = (
|
||||
var.service_account_create
|
||||
? try(google_service_account.service_account[0], null)
|
||||
: try(data.google_service_account.service_account[0], null)
|
||||
local.use_data_source
|
||||
? try(data.google_service_account.service_account[0], null)
|
||||
: try(google_service_account.service_account[0], null)
|
||||
)
|
||||
# universe-related locals
|
||||
universe = try(regex("^([^:]*):[a-z]", local.project_id)[0], "")
|
||||
universe = try(regex("^([^:]*):[a-z]", local.project_id)[0], "")
|
||||
use_data_source = (
|
||||
try(var.service_account_reuse.use_data_source, null) == true
|
||||
)
|
||||
project_id_no_universe = element(split(":", local.project_id), 1)
|
||||
sa_domain = join(".", compact([
|
||||
local.project_id_no_universe, local.universe
|
||||
]))
|
||||
# the condition here avoids referring to attributes not known at plan time
|
||||
tag_bindings = (
|
||||
var.service_account_reuse != null ||
|
||||
try(var.service_account_reuse.attributes.unique_id, null) != null
|
||||
? {}
|
||||
: var.tag_bindings
|
||||
)
|
||||
}
|
||||
|
||||
data "google_service_account" "service_account" {
|
||||
count = var.service_account_create ? 0 : 1
|
||||
count = local.use_data_source ? 1 : 0
|
||||
project = (
|
||||
strcontains(local.project_id, ":")
|
||||
? join(".", reverse(split(":", local.project_id)))
|
||||
@@ -60,7 +70,7 @@ data "google_service_account" "service_account" {
|
||||
}
|
||||
|
||||
resource "google_service_account" "service_account" {
|
||||
count = var.service_account_create ? 1 : 0
|
||||
count = local.use_data_source ? 0 : 1
|
||||
project = local.project_id
|
||||
account_id = "${local.prefix}${local.name}"
|
||||
display_name = var.display_name
|
||||
@@ -69,7 +79,7 @@ resource "google_service_account" "service_account" {
|
||||
}
|
||||
|
||||
resource "google_tags_tag_binding" "binding" {
|
||||
for_each = var.tag_bindings
|
||||
for_each = local.tag_bindings
|
||||
parent = "//iam.googleapis.com/projects/${coalesce(var.project_number, var.project_id)}/serviceAccounts/${local.service_account.unique_id}"
|
||||
tag_value = lookup(local.ctx.tag_values, each.value, each.value)
|
||||
}
|
||||
|
||||
@@ -50,3 +50,8 @@ output "service_account" {
|
||||
description = "Service account resource."
|
||||
value = local.service_account
|
||||
}
|
||||
|
||||
output "unique_id" {
|
||||
description = "Fully qualified service account id."
|
||||
value = local.service_account.unique_id
|
||||
}
|
||||
|
||||
@@ -35,8 +35,8 @@ variable "create_ignore_already_exists" {
|
||||
type = bool
|
||||
default = null
|
||||
validation {
|
||||
condition = !(var.create_ignore_already_exists == true && var.service_account_create == false)
|
||||
error_message = "Cannot set create_ignore_already_exists when service_account_create is false."
|
||||
condition = !(var.create_ignore_already_exists == true && var.service_account_reuse == null)
|
||||
error_message = "Cannot set create_ignore_already_exists when service_account_reuse is null."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,11 +78,15 @@ variable "project_number" {
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "service_account_create" {
|
||||
description = "Create service account. When set to false, uses a data source to reference an existing service account."
|
||||
type = bool
|
||||
default = true
|
||||
nullable = false
|
||||
variable "service_account_reuse" {
|
||||
description = "Reuse existing service account if not null. Data source can be forced disabled if tag bindings are not used, or unique id is set."
|
||||
type = object({
|
||||
use_data_source = optional(bool, true)
|
||||
attributes = optional(object({
|
||||
unique_id = string
|
||||
}))
|
||||
})
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "tag_bindings" {
|
||||
|
||||
@@ -156,8 +156,13 @@ module "automation-service-accounts-iam" {
|
||||
project_id = (
|
||||
module.automation-service-accounts[each.key].service_account.project
|
||||
)
|
||||
name = module.automation-service-accounts[each.key].name
|
||||
service_account_create = false
|
||||
name = module.automation-service-accounts[each.key].name
|
||||
service_account_reuse = {
|
||||
use_data_source = false
|
||||
attributes = {
|
||||
unique_id = module.automation-service-accounts[each.key].unique_id
|
||||
}
|
||||
}
|
||||
context = merge(local.ctx, {
|
||||
service_account_ids = local.project_sas_ids
|
||||
})
|
||||
|
||||
@@ -84,8 +84,13 @@ module "service_accounts-iam" {
|
||||
project_id = (
|
||||
module.service-accounts[each.key].service_account.project
|
||||
)
|
||||
name = each.value.name
|
||||
service_account_create = false
|
||||
name = each.value.name
|
||||
service_account_reuse = {
|
||||
use_data_source = false
|
||||
attributes = {
|
||||
unique_id = module.service-accounts[each.key].unique_id
|
||||
}
|
||||
}
|
||||
context = merge(local.ctx, {
|
||||
project_ids = local.ctx_project_ids
|
||||
iam_principals = merge(
|
||||
|
||||
@@ -530,12 +530,14 @@ values:
|
||||
members:
|
||||
- serviceAccount:iac-org-ro@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
role: organizations/1234567890/roles/storageViewer
|
||||
timeouts: null
|
||||
? module.factory.module.buckets["iac-0/iac-org-state"].google_storage_bucket_iam_binding.authoritative["roles/storage.admin"]
|
||||
: bucket: ft0-prod-iac-core-0-iac-org-state
|
||||
condition: []
|
||||
members:
|
||||
- serviceAccount:iac-org-rw@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
role: roles/storage.admin
|
||||
timeouts: null
|
||||
module.factory.module.buckets["iac-0/iac-outputs"].google_storage_bucket.bucket[0]:
|
||||
autoclass: []
|
||||
cors: []
|
||||
@@ -576,6 +578,7 @@ values:
|
||||
- serviceAccount:iac-security-ro@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
- serviceAccount:iac-vpcsc-ro@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
role: organizations/1234567890/roles/storageViewer
|
||||
timeouts: null
|
||||
module.factory.module.buckets["iac-0/iac-outputs"].google_storage_bucket_iam_binding.authoritative["roles/storage.admin"]:
|
||||
bucket: ft0-prod-iac-core-0-iac-outputs
|
||||
condition: []
|
||||
@@ -587,6 +590,7 @@ values:
|
||||
- serviceAccount:iac-security-rw@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
- serviceAccount:iac-vpcsc-rw@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
role: roles/storage.admin
|
||||
timeouts: null
|
||||
module.factory.module.buckets["iac-0/iac-stage-state"].google_storage_bucket.bucket[0]:
|
||||
autoclass: []
|
||||
cors: []
|
||||
@@ -1630,8 +1634,13 @@ values:
|
||||
member: serviceAccount:iac-vpcsc-rw@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
project: ft0-prod-iac-core-0
|
||||
timeouts: null
|
||||
module.factory.module.service_accounts-iam["iac-0/iac-org-cicd-ro"].data.google_service_account.service_account[0]:
|
||||
module.factory.module.service_accounts-iam["iac-0/iac-org-cicd-ro"].google_service_account.service_account[0]:
|
||||
account_id: iac-org-cicd-ro
|
||||
create_ignore_already_exists: null
|
||||
description: null
|
||||
disabled: false
|
||||
display_name: Terraform-managed.
|
||||
timeouts: null
|
||||
? module.factory.module.service_accounts-iam["iac-0/iac-org-cicd-ro"].google_service_account_iam_member.additive["$service_account_ids:iac-0/iac-org-ro-roles/iam.serviceAccountTokenCreator"]
|
||||
: condition: []
|
||||
role: roles/iam.serviceAccountTokenCreator
|
||||
@@ -1640,8 +1649,13 @@ values:
|
||||
: condition: []
|
||||
role: roles/iam.workloadIdentityUser
|
||||
service_account_id: projects/ft0-prod-iac-core-0/serviceAccounts/iac-org-ro@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
module.factory.module.service_accounts-iam["iac-0/iac-org-cicd-rw"].data.google_service_account.service_account[0]:
|
||||
module.factory.module.service_accounts-iam["iac-0/iac-org-cicd-rw"].google_service_account.service_account[0]:
|
||||
account_id: iac-org-cicd-rw
|
||||
create_ignore_already_exists: null
|
||||
description: null
|
||||
disabled: false
|
||||
display_name: Terraform-managed.
|
||||
timeouts: null
|
||||
? module.factory.module.service_accounts-iam["iac-0/iac-org-cicd-rw"].google_service_account_iam_member.additive["$service_account_ids:iac-0/iac-org-rw-roles/iam.serviceAccountTokenCreator"]
|
||||
: condition: []
|
||||
role: roles/iam.serviceAccountTokenCreator
|
||||
@@ -2395,6 +2409,12 @@ values:
|
||||
- group:fabric-fast-owners@google.com
|
||||
org_id: '1234567890'
|
||||
role: roles/compute.osLoginExternalUser
|
||||
module.organization-iam[0].google_organization_iam_binding.authoritative["roles/compute.viewer"]:
|
||||
condition: []
|
||||
members:
|
||||
- serviceAccount:iac-networking-ro@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
org_id: '1234567890'
|
||||
role: roles/compute.viewer
|
||||
module.organization-iam[0].google_organization_iam_binding.authoritative["roles/compute.xpnAdmin"]:
|
||||
condition: []
|
||||
members:
|
||||
@@ -2402,12 +2422,6 @@ values:
|
||||
- serviceAccount:iac-networking-rw@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
org_id: '1234567890'
|
||||
role: roles/compute.xpnAdmin
|
||||
module.organization-iam[0].google_organization_iam_binding.authoritative["roles/compute.viewer"]:
|
||||
condition: []
|
||||
members:
|
||||
- serviceAccount:iac-networking-ro@ft0-prod-iac-core-0.iam.gserviceaccount.com
|
||||
org_id: '1234567890'
|
||||
role: roles/compute.viewer
|
||||
module.organization-iam[0].google_organization_iam_binding.authoritative["roles/essentialcontacts.admin"]:
|
||||
condition: []
|
||||
members:
|
||||
@@ -2623,6 +2637,66 @@ values:
|
||||
role_id: networkFirewallPoliciesAdmin
|
||||
stage: GA
|
||||
title: Custom role networkFirewallPoliciesAdmin
|
||||
module.organization[0].google_organization_iam_custom_role.roles["ngfw_enterprise_admin"]:
|
||||
description: Terraform-managed.
|
||||
org_id: '1234567890'
|
||||
permissions:
|
||||
- networksecurity.firewallEndpoints.create
|
||||
- networksecurity.firewallEndpoints.delete
|
||||
- networksecurity.firewallEndpoints.get
|
||||
- networksecurity.firewallEndpoints.list
|
||||
- networksecurity.firewallEndpoints.update
|
||||
- networksecurity.firewallEndpoints.use
|
||||
- networksecurity.locations.get
|
||||
- networksecurity.locations.list
|
||||
- networksecurity.operations.cancel
|
||||
- networksecurity.operations.delete
|
||||
- networksecurity.operations.get
|
||||
- networksecurity.operations.list
|
||||
- networksecurity.securityProfileGroups.create
|
||||
- networksecurity.securityProfileGroups.delete
|
||||
- networksecurity.securityProfileGroups.get
|
||||
- networksecurity.securityProfileGroups.list
|
||||
- networksecurity.securityProfileGroups.update
|
||||
- networksecurity.securityProfileGroups.use
|
||||
- networksecurity.securityProfiles.create
|
||||
- networksecurity.securityProfiles.delete
|
||||
- networksecurity.securityProfiles.get
|
||||
- networksecurity.securityProfiles.list
|
||||
- networksecurity.securityProfiles.update
|
||||
- networksecurity.securityProfiles.use
|
||||
- networksecurity.tlsInspectionPolicies.create
|
||||
- networksecurity.tlsInspectionPolicies.delete
|
||||
- networksecurity.tlsInspectionPolicies.get
|
||||
- networksecurity.tlsInspectionPolicies.list
|
||||
- networksecurity.tlsInspectionPolicies.update
|
||||
- networksecurity.tlsInspectionPolicies.use
|
||||
role_id: ngfwEnterpriseAdmin
|
||||
stage: GA
|
||||
title: Custom role ngfwEnterpriseAdmin
|
||||
module.organization[0].google_organization_iam_custom_role.roles["ngfw_enterprise_viewer"]:
|
||||
description: Terraform-managed.
|
||||
org_id: '1234567890'
|
||||
permissions:
|
||||
- networksecurity.firewallEndpoints.get
|
||||
- networksecurity.firewallEndpoints.list
|
||||
- networksecurity.firewallEndpoints.use
|
||||
- networksecurity.locations.get
|
||||
- networksecurity.locations.list
|
||||
- networksecurity.operations.get
|
||||
- networksecurity.operations.list
|
||||
- networksecurity.securityProfileGroups.get
|
||||
- networksecurity.securityProfileGroups.list
|
||||
- networksecurity.securityProfileGroups.use
|
||||
- networksecurity.securityProfiles.get
|
||||
- networksecurity.securityProfiles.list
|
||||
- networksecurity.securityProfiles.use
|
||||
- networksecurity.tlsInspectionPolicies.get
|
||||
- networksecurity.tlsInspectionPolicies.list
|
||||
- networksecurity.tlsInspectionPolicies.use
|
||||
role_id: ngfwEnterpriseViewer
|
||||
stage: GA
|
||||
title: Custom role ngfwEnterpriseViewer
|
||||
module.organization[0].google_organization_iam_custom_role.roles["organization_admin_viewer"]:
|
||||
description: Terraform-managed.
|
||||
org_id: '1234567890'
|
||||
@@ -2764,6 +2838,7 @@ values:
|
||||
input: null
|
||||
output: null
|
||||
triggers_replace: null
|
||||
|
||||
counts:
|
||||
google_bigquery_dataset: 1
|
||||
google_bigquery_default_service_account: 2
|
||||
|
||||
@@ -273,9 +273,6 @@ values:
|
||||
- serviceAccount:app-0-be@test-pf-dev-tb-app0-1.iam.gserviceaccount.com
|
||||
project: test-pf-dev-tb-app0-1
|
||||
role: roles/run.developer
|
||||
module.project-factory.module.projects["dev-ta-app0-be"].data.google_storage_project_service_account.gcs_sa[0]:
|
||||
project: test-pf-dev-ta-app0-be
|
||||
user_project: null
|
||||
module.project-factory.module.projects["dev-ta-app0-be"].google_essential_contacts_contact.contact["admin@example.org"]:
|
||||
email: admin@example.org
|
||||
language_tag: en
|
||||
@@ -405,9 +402,6 @@ values:
|
||||
module.project-factory.module.projects["dev-tb-app0-0"].google_project_service_identity.default["run.googleapis.com"]:
|
||||
project: test-pf-dev-tb-app0-0
|
||||
service: run.googleapis.com
|
||||
module.project-factory.module.projects["dev-tb-app0-1"].data.google_storage_project_service_account.gcs_sa[0]:
|
||||
project: test-pf-dev-tb-app0-1
|
||||
user_project: null
|
||||
module.project-factory.module.projects["dev-tb-app0-1"].google_essential_contacts_contact.contact["admin@example.org"]:
|
||||
email: admin@example.org
|
||||
language_tag: en
|
||||
@@ -462,9 +456,6 @@ values:
|
||||
? module.project-factory.module.projects["dev-tb-app0-1"].google_project_service_identity.default["container.googleapis.com"]
|
||||
: project: test-pf-dev-tb-app0-1
|
||||
service: container.googleapis.com
|
||||
module.project-factory.module.projects["teams-iac-0"].data.google_storage_project_service_account.gcs_sa[0]:
|
||||
project: test-pf-teams-iac-0
|
||||
user_project: null
|
||||
module.project-factory.module.projects["teams-iac-0"].google_essential_contacts_contact.contact["admin@example.org"]:
|
||||
email: admin@example.org
|
||||
language_tag: en
|
||||
@@ -604,8 +595,6 @@ values:
|
||||
email: app-0-be@test-pf-dev-tb-app0-1.iam.gserviceaccount.com
|
||||
member: serviceAccount:app-0-be@test-pf-dev-tb-app0-1.iam.gserviceaccount.com
|
||||
project: test-pf-dev-tb-app0-1
|
||||
? module.project-factory.module.service_accounts-iam["dev-tb-app0-0/vm-default"].data.google_service_account.service_account[0]
|
||||
: account_id: vm-default
|
||||
? module.project-factory.module.service_accounts-iam["dev-tb-app0-0/vm-default"].google_service_account_iam_binding.authoritative["roles/iam.serviceAccountTokenCreator"]
|
||||
: condition: []
|
||||
members:
|
||||
|
||||
Reference in New Issue
Block a user