Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: create service account as part of instance template module #475

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions examples/instance_template/simple_with_sa_creation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# instance-template-simple

This is a simple, minimal example of how to use the instance_template module.

<!-- BEGINNING OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
## Inputs

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| enable\_nested\_virtualization | Defines whether the instance should have nested virtualization enabled. | `bool` | `false` | no |
| labels | Labels, provided as a map | `map(string)` | n/a | yes |
| project\_id | The GCP project to use for integration tests | `string` | n/a | yes |
| region | The GCP region to create and test resources in | `string` | `"us-central1"` | no |
| subnetwork | The name of the subnetwork create this instance in. | `string` | `""` | no |
| tags | Network tags, provided as a list | `list(string)` | n/a | yes |
| threads\_per\_core | The number of threads per physical core. To disable simultaneous multithreading (SMT) set this to 1. | `string` | `null` | no |

## Outputs

| Name | Description |
|------|-------------|
| name | Name of the instance templates |
| self\_link | Self-link to the instance template |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
47 changes: 47 additions & 0 deletions examples/instance_template/simple_with_sa_creation/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/**
* Copyright 2019 Google LLC
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: update

*
* 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.
*/

provider "google" {

project = var.project_id
region = var.region
}

resource "google_compute_address" "ip_address" {
name = "external-ip"
}

locals {
access_config = {
nat_ip = google_compute_address.ip_address.address
network_tier = "PREMIUM"
}
}

module "instance_template" {
source = "../../../modules/instance_template"

project_id = var.project_id
region = var.region
subnetwork = var.subnetwork
stack_type = "IPV4_ONLY"
name_prefix = "simple"
tags = var.tags
labels = var.labels
access_config = [local.access_config]
enable_nested_virtualization = var.enable_nested_virtualization
threads_per_core = var.threads_per_core
}
26 changes: 26 additions & 0 deletions examples/instance_template/simple_with_sa_creation/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/**
* Copyright 2018 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 "self_link" {
description = "Self-link to the instance template"
value = module.instance_template.self_link
}

output "name" {
description = "Name of the instance templates"
value = module.instance_template.name
}

55 changes: 55 additions & 0 deletions examples/instance_template/simple_with_sa_creation/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/**
* Copyright 2019 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 "project_id" {
description = "The GCP project to use for integration tests"
type = string
}

variable "region" {
description = "The GCP region to create and test resources in"
type = string
default = "us-central1"
}

variable "subnetwork" {
description = "The name of the subnetwork create this instance in."
default = ""
}

variable "tags" {
type = list(string)
description = "Network tags, provided as a list"
}

variable "labels" {
type = map(string)
description = "Labels, provided as a map"
}

variable "enable_nested_virtualization" {
type = bool
description = "Defines whether the instance should have nested virtualization enabled."
default = false
}

variable "threads_per_core" {
type = string
description = "The number of threads per physical core. To disable simultaneous multithreading (SMT) set this to 1."
default = null
}
Comment on lines +24 to +55
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets hard code all of these in the example

5 changes: 4 additions & 1 deletion modules/instance_template/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ See the [simple](../../examples/instance_template/simple) for a usage example.
| automatic\_restart | (Optional) Specifies whether the instance should be automatically restarted if it is terminated by Compute Engine (not terminated by a user). | `bool` | `true` | no |
| can\_ip\_forward | Enable IP forwarding, for NAT instances for example | `string` | `"false"` | no |
| confidential\_instance\_type | Defines the confidential computing technology the instance uses. If this is set to "SEV\_SNP", var.min\_cpu\_platform will be automatically set to "AMD Milan". See https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_instance#confidential_instance_type. | `string` | `null` | no |
| create\_new\_service\_account | Create a new service account to attach to the instance. This is alternate to providing the service\_account input variable. | <pre>object({<br> enabled = bool<br> scopes = set(string)<br> })</pre> | <pre>{<br> "enabled": true,<br> "scopes": [<br> "cloud-platform"<br> ]<br>}</pre> | no |
| description | The template's description | `string` | `""` | no |
| disk\_encryption\_key | The id of the encryption key that is stored in Google Cloud KMS to use to encrypt all the disks on this instance | `string` | `null` | no |
| disk\_labels | Labels to be assigned to boot disk, provided as a map | `map(string)` | `{}` | no |
Expand All @@ -47,7 +48,8 @@ See the [simple](../../examples/instance_template/simple) for a usage example.
| project\_id | The GCP project ID | `string` | n/a | yes |
| region | Region where the instance template should be created. | `string` | n/a | yes |
| resource\_policies | A list of self\_links of resource policies to attach to the instance. Modifying this list will cause the instance to recreate. Currently a max of 1 resource policy is supported. | `list(string)` | `[]` | no |
| service\_account | Service account to attach to the instance. See https://www.terraform.io/docs/providers/google/r/compute_instance_template#service_account. | <pre>object({<br> email = string<br> scopes = optional(set(string), ["cloud-platform"])<br> })</pre> | n/a | yes |
| service\_account | Service account to attach to the instance. See https://www.terraform.io/docs/providers/google/r/compute_instance_template#service_account. | <pre>object({<br> email = string<br> scopes = optional(set(string), ["cloud-platform"])<br> })</pre> | `null` | no |
| service\_account\_project\_roles | Roles to grant to the newly created cloud run SA in specified project. Should be used with create\_service\_account set to true and no input for service\_account | `list(string)` | `[]` | no |
| shielded\_instance\_config | Not used unless enable\_shielded\_vm is true. Shielded VM configuration for the instance. | <pre>object({<br> enable_secure_boot = bool<br> enable_vtpm = bool<br> enable_integrity_monitoring = bool<br> })</pre> | <pre>{<br> "enable_integrity_monitoring": true,<br> "enable_secure_boot": true,<br> "enable_vtpm": true<br>}</pre> | no |
| source\_image | Source disk image. If neither source\_image nor source\_image\_family is specified, defaults to the latest public Rocky Linux 9 optimized for GCP image. | `string` | `""` | no |
| source\_image\_family | Source image family. If neither source\_image nor source\_image\_family is specified, defaults to the latest public Rocky Linux 9 optimized for GCP image. | `string` | `"rocky-linux-9-optimized-gcp"` | no |
Expand All @@ -69,6 +71,7 @@ See the [simple](../../examples/instance_template/simple) for a usage example.
| name | Name of instance template |
| self\_link | Self-link of instance template |
| self\_link\_unique | Unique self-link of instance template (recommended output to use instead of self\_link) |
| service\_account\_info | Service account id and email |
| tags | Tags that will be associated with instance(s) |

<!-- END OF PRE-COMMIT-TERRAFORM DOCS HOOK -->
36 changes: 35 additions & 1 deletion modules/instance_template/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,40 @@ locals {
# must be true when preemtible or spot is true
var.preemptible || var.spot ? true : false
)

service_account = (
var.service_account != null
? var.service_account
: (
var.create_new_service_account.enabled
? { email : google_service_account.sa[0].email, scopes : var.create_new_service_account.scopes }
: null
)
)
create_service_account = var.create_service_account.enabled ? var.service_account == null : false

service_account_prefix = substr("${var.name_prefix}-${var.region}", 0, 27)
service_account_output = local.create_service_account ? {
id = google_service_account.sa[0].account_id,
email = google_service_account.sa[0].email,
member = google_service_account.sa[0].member
} : {}
}

# Service account
resource "google_service_account" "sa" {
count = local.create_service_account ? 1 : 0
project = var.project_id
account_id = "${local.service_account_prefix}-sa"
display_name = "Service account for ${var.name_prefix} in ${var.region}"
}

resource "google_project_iam_member" "roles" {
for_each = toset(distinct(var.service_account_project_roles))

project = var.project_id
role = each.value
member = "serviceAccount:${local.service_account.email}"
}

####################
Expand Down Expand Up @@ -111,7 +145,7 @@ resource "google_compute_instance_template" "tpl" {
}

dynamic "service_account" {
for_each = var.service_account == null ? [] : [var.service_account]
for_each = local.service_account == null ? [] : [var.service_account]
content {
email = lookup(service_account.value, "email", null)
scopes = lookup(service_account.value, "scopes", null)
Expand Down
6 changes: 6 additions & 0 deletions modules/instance_template/metadata.display.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,9 @@ spec:
confidential_instance_type:
name: confidential_instance_type
title: Confidential Instance Type
create_new_service_account:
name: create_new_service_account
title: Create New Service Account
description:
name: description
title: Description
Expand Down Expand Up @@ -158,6 +161,9 @@ spec:
service_account:
name: service_account
title: Service Account
service_account_project_roles:
name: service_account_project_roles
title: Service Account Project Roles
shielded_instance_config:
name: shielded_instance_config
title: Shielded Instance Config
Expand Down
20 changes: 19 additions & 1 deletion modules/instance_template/metadata.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ spec:
location: examples/preemptible_and_regular_instance_templates/simple
- name: simple
location: examples/umig/simple
- name: simple_with_sa_creation
location: examples/instance_template/simple_with_sa_creation
- name: static_ips
location: examples/umig/static_ips
- name: tags
Expand Down Expand Up @@ -292,14 +294,28 @@ spec:
email = string
scopes = optional(set(string), ["cloud-platform"])
})
required: true
connections:
- source:
source: github.com/terraform-google-modules/terraform-google-service-accounts//modules/simple-sa
version: ">= 4.4"
spec:
outputExpr: email
inputPath: email
- name: create_new_service_account
description: Create a new service account to attach to the instance. This is alternate to providing the service_account input variable.
varType: |-
object({
enabled = bool
scopes = set(string)
})
defaultValue:
enabled: true
scopes:
- cloud-platform
- name: service_account_project_roles
description: Roles to grant to the newly created cloud run SA in specified project. Should be used with create_service_account set to true and no input for service_account
varType: list(string)
defaultValue: []
- name: enable_shielded_vm
description: Whether to enable the Shielded VM configuration on the instance. Note that the instance image must support Shielded VMs. See https://cloud.google.com/compute/docs/images
varType: bool
Expand Down Expand Up @@ -365,6 +381,8 @@ spec:
- name: self_link_unique
description: Unique self-link of instance template (recommended output to use instead of self_link)
type: string
- name: service_account_info
description: Service account id and email
- name: tags
description: Tags that will be associated with instance(s)
type:
Expand Down
5 changes: 5 additions & 0 deletions modules/instance_template/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,8 @@ output "tags" {
description = "Tags that will be associated with instance(s)"
value = google_compute_instance_template.tpl.tags
}

output "service_account_info" {
description = "Service account id and email"
value = local.service_account_output
}
19 changes: 19 additions & 0 deletions modules/instance_template/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,25 @@ variable "service_account" {
scopes = optional(set(string), ["cloud-platform"])
})
description = "Service account to attach to the instance. See https://www.terraform.io/docs/providers/google/r/compute_instance_template#service_account."
default = null
}

variable "create_new_service_account" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: lets name as create_service_account

type = object({
enabled = bool
scopes = set(string)
})
description = "Create a new service account to attach to the instance. This is alternate to providing the service_account input variable."
default = {
enabled = true
scopes = ["cloud-platform"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's generally not needed to use scope. For this functiality I would recommend changing logic to just use cloud-platform internally if create is true.

}
}

variable "service_account_project_roles" {
type = list(string)
description = "Roles to grant to the newly created cloud run SA in specified project. Should be used with create_service_account set to true and no input for service_account"
default = []
}

###########################
Expand Down
Loading