From d20df2a00e4f087312dcc14b5c332bff059fe162 Mon Sep 17 00:00:00 2001 From: Florian Heuer Date: Fri, 8 Aug 2025 18:00:08 +0200 Subject: [PATCH 1/3] feature(iac): add service-account module --- service-account/README.md | 26 +++++++++++++++ service-account/outputs.tf | 20 ++++++++++++ service-account/providers.tf | 8 +++++ service-account/service-account.tf | 22 +++++++++++++ service-account/variables.tf | 52 ++++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+) create mode 100644 service-account/README.md create mode 100644 service-account/outputs.tf create mode 100644 service-account/providers.tf create mode 100644 service-account/service-account.tf create mode 100644 service-account/variables.tf diff --git a/service-account/README.md b/service-account/README.md new file mode 100644 index 0000000..d26d450 --- /dev/null +++ b/service-account/README.md @@ -0,0 +1,26 @@ +# Terraform module to create STACKIT Service Account + +## Example for main.tf + +# Service Account Terraform Module + +This module creates a STACKIT service account, optionally creates a key, and optionally attaches it to a server. + +## Usage + +```hcl +module "service_account" { + source = "git::https://commerce-platform.git.onstackit.cloud/commerce-platform-public//terraform-modules/service-account" + name = "my-service-account" + project_id = "your-project-id" + + create_key = true + ttl_days = 90 + rotate_when_changed = { + rotated_at = timestamp() + } + + attach_to_server = true + server_id = "your-server-id" +} +``` diff --git a/service-account/outputs.tf b/service-account/outputs.tf new file mode 100644 index 0000000..3587015 --- /dev/null +++ b/service-account/outputs.tf @@ -0,0 +1,20 @@ +output "service_account_email" { + description = "The email of the service account" + value = stackit_service_account.this.email +} + +output "service_account_id" { + description = "Internal ID of the service account" + value = stackit_service_account.this.id +} + +output "service_account_key_id" { + description = "ID of the created key" + value = try(stackit_service_account_key.this[0].key_id, null) +} + +output "service_account_key_json" { + description = "Sensitive JSON key output" + value = try(stackit_service_account_key.this[0].json, null) + sensitive = true +} diff --git a/service-account/providers.tf b/service-account/providers.tf new file mode 100644 index 0000000..28dfab1 --- /dev/null +++ b/service-account/providers.tf @@ -0,0 +1,8 @@ +terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + version = "~> 0.59.0" + } + } +} diff --git a/service-account/service-account.tf b/service-account/service-account.tf new file mode 100644 index 0000000..c7fdbeb --- /dev/null +++ b/service-account/service-account.tf @@ -0,0 +1,22 @@ +resource "stackit_service_account" "this" { + name = var.service_account_name + project_id = var.stackit_project_id +} + +resource "stackit_service_account_key" "this" { + count = var.service_account_create_key ? 1 : 0 + + project_id = var.stackit_project_id + service_account_email = stackit_service_account.this.email + public_key = var.service_account_public_key + rotate_when_changed = var.service_account_rotate_when_changed + ttl_days = var.service_account_ttl_days +} + +resource "stackit_service_account_attachment" "this" { + count = var.attach_to_server ? 1 : 0 + + project_id = var.stackit_project_id + server_id = var.server_id + service_account_email = stackit_service_account.this.email +} diff --git a/service-account/variables.tf b/service-account/variables.tf new file mode 100644 index 0000000..1ff754c --- /dev/null +++ b/service-account/variables.tf @@ -0,0 +1,52 @@ +variable "stackit_project_id" { + description = "STACKIT project ID" + type = string +} + +# === Service Account variables === + + +variable "service_account_name" { + description = "Name of the service account" + type = string +} + +# === Service Account Key variables === + +variable "service_account_create_key" { + description = "Whether to create a service account key" + type = bool + default = false +} + +variable "service_account_public_key" { + description = "Optional: Specifies the public_key (RSA2048 key-pair). If not provided, a certificate from STACKIT will be used to generate a private_key." + type = string + default = null +} + +variable "service_account_rotate_when_changed" { + description = "Map to force key rotation when changed" + type = map(string) + default = {} +} + +variable "service_account_ttl_days" { + description = "Key validity duration in days. Defaults to 90" + type = number + default = 90 +} + +# === Server Service Account Attach variables === + +variable "attach_to_server" { + description = "Whether to attach the service account to a server" + type = bool + default = false +} + +variable "server_id" { + description = "Server ID for attachment" + type = string + default = "" +} -- 2.45.4 From 5c93a4a668ba008bd50f251e671e859b9e9d6da3 Mon Sep 17 00:00:00 2001 From: Florian Heuer Date: Fri, 22 Aug 2025 22:27:03 +0200 Subject: [PATCH 2/3] feature(iac): fix service-account module --- service-account/outputs.tf | 5 +++++ service-account/service-account.tf | 6 +++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/service-account/outputs.tf b/service-account/outputs.tf index 3587015..753c387 100644 --- a/service-account/outputs.tf +++ b/service-account/outputs.tf @@ -1,3 +1,8 @@ +output "service_account_name" { + description = "The name of the service account" + value = var.service_account_name +} + output "service_account_email" { description = "The email of the service account" value = stackit_service_account.this.email diff --git a/service-account/service-account.tf b/service-account/service-account.tf index c7fdbeb..7bbcc0f 100644 --- a/service-account/service-account.tf +++ b/service-account/service-account.tf @@ -3,6 +3,10 @@ resource "stackit_service_account" "this" { project_id = var.stackit_project_id } +resource "time_rotating" "this" { + rotation_days = 3 +} + resource "stackit_service_account_key" "this" { count = var.service_account_create_key ? 1 : 0 @@ -13,7 +17,7 @@ resource "stackit_service_account_key" "this" { ttl_days = var.service_account_ttl_days } -resource "stackit_service_account_attachment" "this" { +resource "stackit_server_service_account_attach" "this" { count = var.attach_to_server ? 1 : 0 project_id = var.stackit_project_id -- 2.45.4 From 5044dd19ca24ae94ff7ac60e616b80a062ec3131 Mon Sep 17 00:00:00 2001 From: Florian Heuer Date: Fri, 22 Aug 2025 22:27:23 +0200 Subject: [PATCH 3/3] feature(iac): improve readme --- service-account/README.md | 67 +++++++++++++++++++++++++++++---------- 1 file changed, 50 insertions(+), 17 deletions(-) diff --git a/service-account/README.md b/service-account/README.md index d26d450..5e0b070 100644 --- a/service-account/README.md +++ b/service-account/README.md @@ -1,26 +1,59 @@ -# Terraform module to create STACKIT Service Account +# Terraform Module: STACKIT Service Account -## Example for main.tf +This module is designed to create a STACKIT service account, optionally generate a key, and optionally attach it to a server. It is useful for managing service accounts and their associated keys in a secure and repeatable manner. -# Service Account Terraform Module +The purpose of this module is to simplify the creation and management of service accounts in STACKIT, while providing flexibility to generate keys and attach them to servers. It also allows for secure storage of keys using a secrets manager. -This module creates a STACKIT service account, optionally creates a key, and optionally attaches it to a server. +## Example Usage -## Usage +```terraform +module "service-account" { + source = "./service-account" # Or a Git URL "git::https://commerce-platform.git.onstackit.cloud/commerce-platform-public//terraform-modules/service-account" + stackit_project_id = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx" + service_account_name = "my-service-account" + service_account_create_key = true +} -```hcl -module "service_account" { - source = "git::https://commerce-platform.git.onstackit.cloud/commerce-platform-public//terraform-modules/service-account" - name = "my-service-account" - project_id = "your-project-id" +# Save json created to secrets manager +variable "secret_manager_username" { + description = "username of the secrets manger to store credentials" + type = string + sensitive = true +} - create_key = true - ttl_days = 90 - rotate_when_changed = { - rotated_at = timestamp() +variable "secret_manager_password" { + description = "password of the secrets manger to store credentials" + type = string + sensitive = true +} + +module "service_account_key" { + source = "./create-secret" # Or a Git URL "git::https://commerce-platform.git.onstackit.cloud/commerce-platform-public//terraform-modules/create-secret" + secret_manager_instance_id = local.secret_manager_instance_id + secret_manager_username = var.secret_manager_username + secret_manager_password = var.secret_manager_password + secrets_path = "service-accounts/${module.service-account.service_account_name}" + secret_data = { + key_json = module.service-account.service_account_key_json } - - attach_to_server = true - server_id = "your-server-id" } ``` + +## Inputs + +| Key | Description | Type | Required | Default | +| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ------------- | -------- | ------- | +| `service_account_name` | Name of the service account | `string` | yes | +| `service_account_create_key` | Whether to create a service account key | `bool` | no | `false` | +| `service_account_public_key` | Optional: Specifies the public_key (RSA2048 key-pair). If not provided, a certificate from STACKIT will be used to generate a private_key. | `string` | no | `null` | +| `service_account_rotate_when_changed` | Map to force key rotation when changed | `map(string)` | no | `{}` | +| `service_account_ttl_days` | Key validity duration in days. Defaults to 90 | `number` | no | `90` | +| `attach_to_server` | Whether to attach the service account to a server | `bool` | no | `false` | +| `server_id` | Server ID for attachment | `string` | no | `""` | + +## Notes + +- When creating a key, it is recommended to save it securely using a secrets manager. In the example usage we illustrated how to do that using the `create-secret` module. +- The module does not handle key rotation automatically. You can use the service_account_rotate_when_changed input to force key rotation when certain attributes change. +- The module does not handle server attachment automatically. You can use the attach_to_server and server_id inputs to attach the service account to a server. +- The module does not handle deletion of service accounts or keys. It is recommended to manage these resources using appropriate Terraform lifecycle configurations or external tools. -- 2.45.4