From 7a3a1204b45f64e4f4b9da3e6735d6377418f9a7 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Mon, 22 Jun 2026 21:10:55 +0200 Subject: [PATCH 1/2] Support service connection Signed-off-by: Jorge Turrado --- stackit/provider.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/stackit/provider.go b/stackit/provider.go index 7c653f474..2cd82ac6d 100644 --- a/stackit/provider.go +++ b/stackit/provider.go @@ -213,6 +213,7 @@ type providerModel struct { TokenCustomEndpoint types.String `tfsdk:"token_custom_endpoint"` VpnCustomEndpoint types.String `tfsdk:"vpn_custom_endpoint"` OIDCTokenRequestURL types.String `tfsdk:"oidc_request_url"` + ServiceConnectionID types.String `tfsdk:"service_connection_id"` OIDCTokenRequestToken types.String `tfsdk:"oidc_request_token"` EnableBetaResources types.Bool `tfsdk:"enable_beta_resources"` @@ -232,6 +233,7 @@ func (p *Provider) Schema(_ context.Context, _ provider.SchemaRequest, resp *pro "service_account_federated_token_path": "Path for workload identity assertion. It can also be set using the environment variable STACKIT_FEDERATED_TOKEN_FILE.", "service_account_federated_token": "The OIDC ID token for use when authenticating as a Service Account using OpenID Connect.", "use_oidc": "Enables OIDC for Authentication. This can also be sourced from the `STACKIT_USE_OIDC` Environment Variable. Defaults to `false`.", + "service_connection_id": "The ID of the Azure DevOps pipeline service connection. For use when authenticating as a Service Account using OpenID Connect.", "oidc_request_url": "The URL for the OIDC provider from which to request an ID token. For use when authenticating as a Service Account using OpenID Connect.", "oidc_request_token": "The bearer token for the request to the OIDC provider. For use when authenticating as a Service Account using OpenID Connect.", "region": "Region will be used as the default location for regional services. Not all services require a region, some are global", @@ -322,6 +324,10 @@ func (p *Provider) Schema(_ context.Context, _ provider.SchemaRequest, resp *pro Optional: true, Description: descriptions["use_oidc"], }, + "service_connection_id": schema.StringAttribute{ + Optional: true, + Description: descriptions["service_connection_id"], + }, "oidc_request_token": schema.StringAttribute{ Optional: true, Description: descriptions["oidc_request_token"], @@ -634,7 +640,7 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, oidcReqToken = utils.GetEnvStringOrDefault(providerConfig.OIDCTokenRequestToken, "SYSTEM_ACCESSTOKEN", "") // This can be set to the ID of the service connection to restrict the token exchange to that connection, not supported by default to avoid additional configuration // for users that don't need it, can be added as an additional provider config parameter in the future if there is demand - serviceConnectionID := "" + serviceConnectionID := utils.GetEnvStringOrDefault(providerConfig.ServiceConnectionID, "STACKIT_SERVICE_CONNECTION_ID", "") if oidcReqURL != "" && oidcReqToken != "" { sdkConfig.ServiceAccountFederatedTokenFunc = oidcadapters.RequestAzureDevOpsOIDCToken(oidcReqURL, oidcReqToken, serviceConnectionID) } From c6a8de3aa22644efaaf7907540af79af6e1830a5 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 25 Jun 2026 19:48:56 +0200 Subject: [PATCH 2/2] include new examples Signed-off-by: Jorge Turrado --- docs/guides/workload_identity_federation.md | 23 +++++++++---------- docs/index.md | 1 + .../workload_identity_federation.md.tmpl | 23 +++++++++---------- 3 files changed, 23 insertions(+), 24 deletions(-) diff --git a/docs/guides/workload_identity_federation.md b/docs/guides/workload_identity_federation.md index da53eef95..d7667c1cd 100644 --- a/docs/guides/workload_identity_federation.md +++ b/docs/guides/workload_identity_federation.md @@ -40,8 +40,7 @@ execute terraform on the main branch, we will configure the service account "Fed Azure DevOps supports OIDC authentication using the public issuer "https://vstoken.azure.com" (for Azure DevOps Server you should check your issuer URL) and setting information like organization, project, and pipeline as part of the OIDC token claims. -Using a hypothetical pipeline named `terraform-ado-oidc` inside the project 'https://myorg.azure.com/project-abc` as example and assuming that we want to -execute terraform on the main branch, we will configure the service account "Federated identity Provider" with the following configuration: +Using a hypothetical pipeline named `terraform-ado-oidc` inside the project 'https://myorg.azure.com/project-abc` as example, we will configure the service account "Federated identity Provider" with the following configuration: - **Provider Name**: AzureDevOps # This is just an example, you can choose any name you want - **Issuer URL**: https://vstoken.dev.azure.com/{ORGANIZATION_ID} # This is the public issuer for Azure DevOps OIDC tokens - For most organizations, the URL uses `vstoken.dev.azure.com`, but some legacy organizations might use 'vstoken.azure.com'. To be 100% sure, you can inspect the `iss` claim in a decoded OIDC token from your pipeline. @@ -50,8 +49,7 @@ execute terraform on the main branch, we will configure the service account "Fed - Via Pipeline: Add a script step echo $(System.CollectionId) to print it during a run. - **Assertions**: - **aud**->equals->api://AzureADTokenExchange # Mandatory value - - **sub**->equals->p://myorg/project-abc/terraform-ado-oidc # This is the pipeline where the process is running - - **rpo_ref**->equals->refs/heads/main # This is the branch where the pipeline will run + - **sub**->equals->sc://myorg/project-abc/stackit-service-connection # This is the service connection that is being used to authenticate with STACKIT. > Note: This is just an example, you can use more or less fine-grained assertions. @@ -150,6 +148,9 @@ jobs: ### Azure Pipeline +For Azure DevOps, use the STACKIT Azure DevOps extension and authenticate with the [`StackitAuthenticate`](https://marketplace.visualstudio.com/items?itemName=SchwarzDigits.stackit-service-connection) task. +Create a STACKIT Service Connection using Workload Identity Federation (WIF) in your project and reference it in the task input. + ```yaml trigger: branches: @@ -160,8 +161,6 @@ pool: vmImage: "ubuntu-latest" variables: - STACKIT_USE_OIDC: "1" - STACKIT_SERVICE_ACCOUNT_EMAIL: "terraform-example@sa.stackit.cloud" jobs: - job: demo-job @@ -169,6 +168,11 @@ jobs: steps: - checkout: self + - task: StackitAuthenticate@1 + inputs: + serviceConnection: "My STACKIT Connection (WIF)" + displayName: "Authenticate with STACKIT (WIF)" + - task: TerraformInstaller@1 inputs: terraformVersion: "latest" @@ -186,6 +190,7 @@ jobs: provider "stackit" { default_region = "eu01" + use_oidc = true } resource "stackit_service_account" "sa" { @@ -199,23 +204,17 @@ jobs: terraform init displayName: "Terraform Init" env: - STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) - STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) SYSTEM_ACCESSTOKEN: $(System.AccessToken) - script: | terraform plan -out=tfplan displayName: "Terraform Plan" env: - STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) - STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) SYSTEM_ACCESSTOKEN: $(System.AccessToken) - script: | terraform apply -auto-approve tfplan displayName: "Terraform Apply" env: - STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) - STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) SYSTEM_ACCESSTOKEN: $(System.AccessToken) ``` diff --git a/docs/index.md b/docs/index.md index 368beb47e..f0756dd70 100644 --- a/docs/index.md +++ b/docs/index.md @@ -207,6 +207,7 @@ Note: AWS specific checks must be skipped as they do not work on STACKIT. For de - `service_account_key` (String) Service account key used for authentication. If set, the key flow will be used to authenticate all operations. - `service_account_key_path` (String) Path for the service account key used for authentication. If set, the key flow will be used to authenticate all operations. - `service_account_token` (String, Deprecated) Token used for authentication. If set, the token flow will be used to authenticate all operations. +- `service_connection_id` (String) The ID of the Azure DevOps pipeline service connection. For use when authenticating as a Service Account using OpenID Connect. - `service_enablement_custom_endpoint` (String) Custom endpoint for the Service Enablement API - `sfs_custom_endpoint` (String) Custom endpoint for the Stackit Filestorage API - `ske_custom_endpoint` (String) Custom endpoint for the Kubernetes Engine (SKE) service diff --git a/templates/guides/workload_identity_federation.md.tmpl b/templates/guides/workload_identity_federation.md.tmpl index da53eef95..d7667c1cd 100644 --- a/templates/guides/workload_identity_federation.md.tmpl +++ b/templates/guides/workload_identity_federation.md.tmpl @@ -40,8 +40,7 @@ execute terraform on the main branch, we will configure the service account "Fed Azure DevOps supports OIDC authentication using the public issuer "https://vstoken.azure.com" (for Azure DevOps Server you should check your issuer URL) and setting information like organization, project, and pipeline as part of the OIDC token claims. -Using a hypothetical pipeline named `terraform-ado-oidc` inside the project 'https://myorg.azure.com/project-abc` as example and assuming that we want to -execute terraform on the main branch, we will configure the service account "Federated identity Provider" with the following configuration: +Using a hypothetical pipeline named `terraform-ado-oidc` inside the project 'https://myorg.azure.com/project-abc` as example, we will configure the service account "Federated identity Provider" with the following configuration: - **Provider Name**: AzureDevOps # This is just an example, you can choose any name you want - **Issuer URL**: https://vstoken.dev.azure.com/{ORGANIZATION_ID} # This is the public issuer for Azure DevOps OIDC tokens - For most organizations, the URL uses `vstoken.dev.azure.com`, but some legacy organizations might use 'vstoken.azure.com'. To be 100% sure, you can inspect the `iss` claim in a decoded OIDC token from your pipeline. @@ -50,8 +49,7 @@ execute terraform on the main branch, we will configure the service account "Fed - Via Pipeline: Add a script step echo $(System.CollectionId) to print it during a run. - **Assertions**: - **aud**->equals->api://AzureADTokenExchange # Mandatory value - - **sub**->equals->p://myorg/project-abc/terraform-ado-oidc # This is the pipeline where the process is running - - **rpo_ref**->equals->refs/heads/main # This is the branch where the pipeline will run + - **sub**->equals->sc://myorg/project-abc/stackit-service-connection # This is the service connection that is being used to authenticate with STACKIT. > Note: This is just an example, you can use more or less fine-grained assertions. @@ -150,6 +148,9 @@ jobs: ### Azure Pipeline +For Azure DevOps, use the STACKIT Azure DevOps extension and authenticate with the [`StackitAuthenticate`](https://marketplace.visualstudio.com/items?itemName=SchwarzDigits.stackit-service-connection) task. +Create a STACKIT Service Connection using Workload Identity Federation (WIF) in your project and reference it in the task input. + ```yaml trigger: branches: @@ -160,8 +161,6 @@ pool: vmImage: "ubuntu-latest" variables: - STACKIT_USE_OIDC: "1" - STACKIT_SERVICE_ACCOUNT_EMAIL: "terraform-example@sa.stackit.cloud" jobs: - job: demo-job @@ -169,6 +168,11 @@ jobs: steps: - checkout: self + - task: StackitAuthenticate@1 + inputs: + serviceConnection: "My STACKIT Connection (WIF)" + displayName: "Authenticate with STACKIT (WIF)" + - task: TerraformInstaller@1 inputs: terraformVersion: "latest" @@ -186,6 +190,7 @@ jobs: provider "stackit" { default_region = "eu01" + use_oidc = true } resource "stackit_service_account" "sa" { @@ -199,23 +204,17 @@ jobs: terraform init displayName: "Terraform Init" env: - STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) - STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) SYSTEM_ACCESSTOKEN: $(System.AccessToken) - script: | terraform plan -out=tfplan displayName: "Terraform Plan" env: - STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) - STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) SYSTEM_ACCESSTOKEN: $(System.AccessToken) - script: | terraform apply -auto-approve tfplan displayName: "Terraform Apply" env: - STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) - STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) SYSTEM_ACCESSTOKEN: $(System.AccessToken) ```