From c9791d2ea3d7c4006bfc10da7801021a7cdc08d6 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 21:44:50 +0100 Subject: [PATCH 01/20] feat: Support Azure DevOps OIDC provider Signed-off-by: Jorge Turrado --- docs/guides/workload_identity_federation.md | 35 +++++++++++++++---- docs/index.md | 2 +- go.mod | 2 ++ go.sum | 4 +-- stackit/provider.go | 13 ++++++- .../workload_identity_federation.md.tmpl | 35 +++++++++++++++---- templates/index.md.tmpl | 2 +- 7 files changed, 76 insertions(+), 17 deletions(-) diff --git a/docs/guides/workload_identity_federation.md b/docs/guides/workload_identity_federation.md index 30d82f558..6a7fb6446 100644 --- a/docs/guides/workload_identity_federation.md +++ b/docs/guides/workload_identity_federation.md @@ -1,12 +1,12 @@ --- -page_title: "Workload Identity Federation with GitHub Actions" +page_title: "Workload Identity Federation" --- # Workload Identity Federation with GitHub Actions Workload Identity Federation (WIF) allows you to authenticate the STACKIT Terraform provider without using long-lived Service Account keys. This is particularly useful in CI/CD environments like **GitHub Actions**, **GitLab CI**, or **Azure DevOps**, where you can use short-lived -OIDC tokens. This guide focuses on using WIF with GitHub Actions, but the principles may apply to other CI/CD platforms that support OIDC. +OIDC tokens. This guide focuses on using WIF with GitHub Actions and Azure DevOps, but the principles may apply to other CI/CD platforms that support OIDC. ## Prerequisites @@ -16,8 +16,13 @@ Before using Workload Identity Federation flow, you need to: ## Setup Workload Identity Federation WIF can be configured to trust any public OIDC provider following the [docs page](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/how-tos/manage-service-account-federations/#create-a-federated-identity-provider) -but for the purpose of this guide we will focus on GitHub Actions as OIDC provider. GitHub Actions supports OIDC authentication using -the public issuer "https://token.actions.githubusercontent.com" (for GH Enterprise you should check your issuer URL) and setting repository and action information +but for the purpose of this guide we will focus on GitHub Actions and AzureDevOps as OIDC providers. + +> Important: The most closed assertions including all the data that you cant from the OIDC token should be used to avoid potential security risks of trusting tokens that are not issued in the context of your CI/CD pipeline. + +### GitHub Actions assertions + +GitHub Actions supports OIDC authentication using the public issuer "https://token.actions.githubusercontent.com" (for GH Enterprise you should check your issuer URL) and setting repository and action information as part of the OIDC token claims. [More info here](https://docs.github.com/es/actions/concepts/security/openid-connect). Using this provider [repository](https://github.com/stackitcloud/terraform-provider-stackit) (stackitcloud/terraform-provider-stackit) as example and assuming that we want to @@ -28,7 +33,23 @@ execute terraform on the main branch, we will configure the service account "Fed - **sub**->equals->repo:stackitcloud/terraform-provider-stackit:ref:refs/heads/main # This is the repository and branch where the action will run - **aud**->equals->sts.accounts.stackit.cloud # Mandatory value -> Note: You can use more fine-grained assertions just adding them. More info about OIDC token claims in [GitHub](https://docs.github.com/en/actions/reference/security/oidc) +> Note: You can use more fine-grained assertions by adding them. More info about OIDC token claims in [GitHub](https://docs.github.com/en/actions/reference/security/oidc) + +### Azure DevOps assertions + +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 prohect '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: +- **Provider Name**: AzureDevOps # This is just an example, you can choose any name you want +- **Issuer URL**: https://vstoken.azure.com/{ORGANIZATION_ID} # This is the public issuer for Azure DevOps OIDC tokens +- **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, can be used instead of sub claim + +> Note: This is just an example, you can use more or less fine-grained assertions. ## Provider Configuration @@ -50,7 +71,9 @@ provider "stackit" { In most CI/CD scenarios, the cleanest way is to set the `STACKIT_SERVICE_ACCOUNT_EMAIL` environment variable as well as `STACKIT_USE_OIDC="1"` to enable the WIF flow. This way you don't need to change your provider configuration and the provider will automatically fetch the OIDC token and exchange it for a short-lived access token. -## Example GitHub Actions Workflow +## Examples + +### GitHub Actions Workflow > Note: To request OIDC tokens, you need to [grant this permission to the GitHub Actions workflow](https://docs.github.com/en/actions/reference/security/oidc#required-permission). diff --git a/docs/index.md b/docs/index.md index 27290dfe4..7a29fe3b8 100644 --- a/docs/index.md +++ b/docs/index.md @@ -74,7 +74,7 @@ When using Workload Identity Federation (WIF), you don't need a static service a WIF can be configured to trust any public OIDC provider following the [official documentation](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/how-tos/manage-service-account-federations/#create-a-federated-identity-provider). -To use WIF, set the `use_oidc` flag to `true` and provide an OIDC token for the exchange. While you can provide the token directly via `service_account_federated_token`, this is **not recommended for GitHub Actions**, as the provider will automatically fetch the token from the environment. For a complete setup, see our [Workload Identity Federation guide](./guides/workload_identity_federation.md). +To use WIF, set the `use_oidc` flag to `true` and provide an OIDC token for the exchange. While you can provide the token directly via `service_account_federated_token`, this is **not recommended for GitHub Actions or Azure DevOps**, as the provider will automatically fetch the token from the environment. For a complete setup, see our [Workload Identity Federation guide](./docs/guides/workload_identity_federation.md). In addition to this, you must set the `service_account_email` to specify which service account to impersonate. diff --git a/go.mod b/go.mod index 048e496ba..1f1b5a817 100644 --- a/go.mod +++ b/go.mod @@ -2,6 +2,8 @@ module github.com/stackitcloud/terraform-provider-stackit go 1.24.0 +replace github.com/stackitcloud/stackit-sdk-go/core => github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218191605-c1e0812ff15f + require ( github.com/google/go-cmp v0.7.0 github.com/google/uuid v1.6.0 diff --git a/go.sum b/go.sum index f2ff5e6e4..3d6f41cc1 100644 --- a/go.sum +++ b/go.sum @@ -109,6 +109,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= +github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218191605-c1e0812ff15f h1:fTNZZta47QPQs8rG48i47wFQChjoYwUeoMGikLj6iSk= +github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218191605-c1e0812ff15f/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= @@ -149,8 +151,6 @@ github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 h1:n661drycOFuPLCN github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= github.com/skeema/knownhosts v1.3.1 h1:X2osQ+RAjK76shCbvhHHHVl3ZlgDm8apHEHFqRjnBY8= github.com/skeema/knownhosts v1.3.1/go.mod h1:r7KTdC8l4uxWRyK2TpQZ/1o5HaSzh06ePQNxPwTcfiY= -github.com/stackitcloud/stackit-sdk-go/core v0.21.1 h1:Y/PcAgM7DPYMNqum0MLv4n1mF9ieuevzcCIZYQfm3Ts= -github.com/stackitcloud/stackit-sdk-go/core v0.21.1/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= github.com/stackitcloud/stackit-sdk-go/services/authorization v0.12.0 h1:HxPgBu04j5tj6nfZ2r0l6v4VXC0/tYOGe4sA5Addra8= github.com/stackitcloud/stackit-sdk-go/services/authorization v0.12.0/go.mod h1:uYI9pHAA2g84jJN25ejFUxa0/JtfpPZqMDkctQ1BzJk= github.com/stackitcloud/stackit-sdk-go/services/cdn v1.10.0 h1:YALzjYAApyQMKyt4C2LKhPRZHa6brmbFeKuuwl+KOTs= diff --git a/stackit/provider.go b/stackit/provider.go index 85abf49ba..4747afe19 100644 --- a/stackit/provider.go +++ b/stackit/provider.go @@ -549,7 +549,7 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, sdkConfig.ServiceAccountFederatedTokenFunc = oidcadapters.ReadJWTFromFileSystem(oidc_token_path) } - // Workload Identity Federation via provided OIDC Token from GitHub Actions + // Workload Identity Federation via provided OIDC Token from GitHub Actions or Azure Dev Ops if sdkConfig.ServiceAccountFederatedTokenFunc == nil && utils.GetEnvBoolIfValueAbsent(providerConfig.UseOIDC, "STACKIT_USE_OIDC") { sdkConfig.WorkloadIdentityFederation = true // https://docs.github.com/en/actions/reference/security/oidc#methods-for-requesting-the-oidc-token @@ -558,6 +558,17 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, if oidcReqURL != "" && oidcReqToken != "" { sdkConfig.ServiceAccountFederatedTokenFunc = oidcadapters.RequestGHOIDCToken(oidcReqURL, oidcReqToken) } + + // https://learn.microsoft.com/en-us/rest/api/azure/devops/distributedtask/oidctoken/create?view=azure-devops-rest-7.1#taskhuboidctoken + // https://learn.microsoft.com/es-es/azure/devops/pipelines/build/variables?view=azure-devops&tabs=yaml + oidcReqURL = utils.GetEnvStringOrDefault(providerConfig.OIDCTokenRequestURL, "SYSTEM_OIDCREQUESTURI", "") + 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 := "" + if oidcReqURL != "" && oidcReqToken != "" { + sdkConfig.ServiceAccountFederatedTokenFunc = oidcadapters.RequestAzureDevOpsOIDCToken(oidcReqURL, oidcReqToken, serviceConnectionID) + } } roundTripper, err := sdkauth.SetupAuth(sdkConfig) diff --git a/templates/guides/workload_identity_federation.md.tmpl b/templates/guides/workload_identity_federation.md.tmpl index 30d82f558..6a7fb6446 100644 --- a/templates/guides/workload_identity_federation.md.tmpl +++ b/templates/guides/workload_identity_federation.md.tmpl @@ -1,12 +1,12 @@ --- -page_title: "Workload Identity Federation with GitHub Actions" +page_title: "Workload Identity Federation" --- # Workload Identity Federation with GitHub Actions Workload Identity Federation (WIF) allows you to authenticate the STACKIT Terraform provider without using long-lived Service Account keys. This is particularly useful in CI/CD environments like **GitHub Actions**, **GitLab CI**, or **Azure DevOps**, where you can use short-lived -OIDC tokens. This guide focuses on using WIF with GitHub Actions, but the principles may apply to other CI/CD platforms that support OIDC. +OIDC tokens. This guide focuses on using WIF with GitHub Actions and Azure DevOps, but the principles may apply to other CI/CD platforms that support OIDC. ## Prerequisites @@ -16,8 +16,13 @@ Before using Workload Identity Federation flow, you need to: ## Setup Workload Identity Federation WIF can be configured to trust any public OIDC provider following the [docs page](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/how-tos/manage-service-account-federations/#create-a-federated-identity-provider) -but for the purpose of this guide we will focus on GitHub Actions as OIDC provider. GitHub Actions supports OIDC authentication using -the public issuer "https://token.actions.githubusercontent.com" (for GH Enterprise you should check your issuer URL) and setting repository and action information +but for the purpose of this guide we will focus on GitHub Actions and AzureDevOps as OIDC providers. + +> Important: The most closed assertions including all the data that you cant from the OIDC token should be used to avoid potential security risks of trusting tokens that are not issued in the context of your CI/CD pipeline. + +### GitHub Actions assertions + +GitHub Actions supports OIDC authentication using the public issuer "https://token.actions.githubusercontent.com" (for GH Enterprise you should check your issuer URL) and setting repository and action information as part of the OIDC token claims. [More info here](https://docs.github.com/es/actions/concepts/security/openid-connect). Using this provider [repository](https://github.com/stackitcloud/terraform-provider-stackit) (stackitcloud/terraform-provider-stackit) as example and assuming that we want to @@ -28,7 +33,23 @@ execute terraform on the main branch, we will configure the service account "Fed - **sub**->equals->repo:stackitcloud/terraform-provider-stackit:ref:refs/heads/main # This is the repository and branch where the action will run - **aud**->equals->sts.accounts.stackit.cloud # Mandatory value -> Note: You can use more fine-grained assertions just adding them. More info about OIDC token claims in [GitHub](https://docs.github.com/en/actions/reference/security/oidc) +> Note: You can use more fine-grained assertions by adding them. More info about OIDC token claims in [GitHub](https://docs.github.com/en/actions/reference/security/oidc) + +### Azure DevOps assertions + +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 prohect '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: +- **Provider Name**: AzureDevOps # This is just an example, you can choose any name you want +- **Issuer URL**: https://vstoken.azure.com/{ORGANIZATION_ID} # This is the public issuer for Azure DevOps OIDC tokens +- **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, can be used instead of sub claim + +> Note: This is just an example, you can use more or less fine-grained assertions. ## Provider Configuration @@ -50,7 +71,9 @@ provider "stackit" { In most CI/CD scenarios, the cleanest way is to set the `STACKIT_SERVICE_ACCOUNT_EMAIL` environment variable as well as `STACKIT_USE_OIDC="1"` to enable the WIF flow. This way you don't need to change your provider configuration and the provider will automatically fetch the OIDC token and exchange it for a short-lived access token. -## Example GitHub Actions Workflow +## Examples + +### GitHub Actions Workflow > Note: To request OIDC tokens, you need to [grant this permission to the GitHub Actions workflow](https://docs.github.com/en/actions/reference/security/oidc#required-permission). diff --git a/templates/index.md.tmpl b/templates/index.md.tmpl index f30f2133a..09c85782b 100644 --- a/templates/index.md.tmpl +++ b/templates/index.md.tmpl @@ -38,7 +38,7 @@ When using Workload Identity Federation (WIF), you don't need a static service a WIF can be configured to trust any public OIDC provider following the [official documentation](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/how-tos/manage-service-account-federations/#create-a-federated-identity-provider). -To use WIF, set the `use_oidc` flag to `true` and provide an OIDC token for the exchange. While you can provide the token directly via `service_account_federated_token`, this is **not recommended for GitHub Actions**, as the provider will automatically fetch the token from the environment. For a complete setup, see our [Workload Identity Federation guide](./guides/workload_identity_federation.md). +To use WIF, set the `use_oidc` flag to `true` and provide an OIDC token for the exchange. While you can provide the token directly via `service_account_federated_token`, this is **not recommended for GitHub Actions or Azure DevOps**, as the provider will automatically fetch the token from the environment. For a complete setup, see our [Workload Identity Federation guide](./docs/guides/workload_identity_federation.md). In addition to this, you must set the `service_account_email` to specify which service account to impersonate. From ddb14e7b0e09eaa1632c8fc16c74e1fd120e8ff2 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 22:15:51 +0100 Subject: [PATCH 02/20] feat: Support Azure DevOps OIDC provider Signed-off-by: Jorge Turrado --- docs/guides/workload_identity_federation.md | 10 +++++++--- templates/guides/workload_identity_federation.md.tmpl | 10 +++++++--- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/docs/guides/workload_identity_federation.md b/docs/guides/workload_identity_federation.md index 6a7fb6446..bea8d3897 100644 --- a/docs/guides/workload_identity_federation.md +++ b/docs/guides/workload_identity_federation.md @@ -38,16 +38,20 @@ execute terraform on the main branch, we will configure the service account "Fed ### Azure DevOps assertions 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. +as part of the OIDC token claims. Using a hypothetical pipeline named `terraform-ado-oidc` inside the prohect '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: - **Provider Name**: AzureDevOps # This is just an example, you can choose any name you want -- **Issuer URL**: https://vstoken.azure.com/{ORGANIZATION_ID} # This is the public issuer for Azure DevOps OIDC tokens +- **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, + - How to find your ORGANIZATION_ID? + - Via Browser: Go to https://dev.azure.com/{YOUR_ORG_NAME}/_apis/connectionData and copy the value of instanceId. + - 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, can be used instead of sub claim + - **rpo_ref**->equals->refs/heads/main # This is the branch where the pipeline will run > Note: This is just an example, you can use more or less fine-grained assertions. diff --git a/templates/guides/workload_identity_federation.md.tmpl b/templates/guides/workload_identity_federation.md.tmpl index 6a7fb6446..bea8d3897 100644 --- a/templates/guides/workload_identity_federation.md.tmpl +++ b/templates/guides/workload_identity_federation.md.tmpl @@ -38,16 +38,20 @@ execute terraform on the main branch, we will configure the service account "Fed ### Azure DevOps assertions 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. +as part of the OIDC token claims. Using a hypothetical pipeline named `terraform-ado-oidc` inside the prohect '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: - **Provider Name**: AzureDevOps # This is just an example, you can choose any name you want -- **Issuer URL**: https://vstoken.azure.com/{ORGANIZATION_ID} # This is the public issuer for Azure DevOps OIDC tokens +- **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, + - How to find your ORGANIZATION_ID? + - Via Browser: Go to https://dev.azure.com/{YOUR_ORG_NAME}/_apis/connectionData and copy the value of instanceId. + - 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, can be used instead of sub claim + - **rpo_ref**->equals->refs/heads/main # This is the branch where the pipeline will run > Note: This is just an example, you can use more or less fine-grained assertions. From 34c46f2f8cd8dc34c6509f00a75f549c3761f52d Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 22:26:48 +0100 Subject: [PATCH 03/20] add pipeline Signed-off-by: Jorge Turrado --- devops.yaml | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 devops.yaml diff --git a/devops.yaml b/devops.yaml new file mode 100644 index 000000000..7dd2ce5fd --- /dev/null +++ b/devops.yaml @@ -0,0 +1,83 @@ +trigger: + branches: + include: + - "*" + +pool: + vmImage: "ubuntu-latest" + +variables: + # Definir variables globales para usarlas en los scripts + # NOTA: En ADO, la autenticación OIDC funciona diferente a GitHub. + # Es posible que necesites una Service Connection o configurar las credenciales explícitamente. + STACKIT_USE_OIDC: "1" + STACKIT_SERVICE_ACCOUNT_EMAIL: "turrado-test-2jfmrj1@sa.stackit.cloud" + # Versión de Go (ajusta según tu go.mod) + GO_VERSION: "1.22" + +jobs: + - job: Build_and_Test + displayName: "Build Provider & Test Plan" + + steps: + - checkout: self + + # 1. Instalar Go + - task: GoTool@0 + inputs: + version: "$(GO_VERSION)" + displayName: "Setup Go" + + # 2. Compilar el Provider + - script: | + go build -o terraform-provider-stackit + chmod +x terraform-provider-stackit + + # En ADO usamos $(Build.SourcesDirectory) en lugar de GITHUB_WORKSPACE + echo "##vso[task.setvariable variable=BINARY_PATH]$(Build.SourcesDirectory)" + displayName: "Build Provider" + + # 3. Configurar Overrides de Terraform + - script: | + cat < ~/.terraformrc + provider_installation { + dev_overrides { + "stackitcloud/stackit" = "$(BINARY_PATH)" + } + # Para otros providers (random, null, etc), usa el registro normal + direct {} + } + EOF + + echo "Terraform RC content:" + cat ~/.terraformrc + displayName: "Configure Terraform Dev Overrides" + + # 4. Instalar Terraform + - task: TerraformInstaller@1 + inputs: + terraformVersion: "latest" + displayName: "Setup Terraform" + + # 5. Crear configuración de prueba (main.tf) + - script: | + cat < main.tf + terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + } + } + } + + provider "stackit" { + default_region = "eu01" + enable_beta_resources = true + } + + resource "stackit_service_account" "sa" { + project_id = "36026686-6bb7-46e9-8712-25625983a1be" + name = "terraform-wif-ci" + } + EOF + displayName: "Create Test Configuration" From 5935df451e41bf894f747408b9c0e37b34db017a Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 23:44:28 +0100 Subject: [PATCH 04/20] add pipeline Signed-off-by: Jorge Turrado --- devops.yaml | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/devops.yaml b/devops.yaml index 7dd2ce5fd..4dbfdff8b 100644 --- a/devops.yaml +++ b/devops.yaml @@ -11,7 +11,7 @@ variables: # NOTA: En ADO, la autenticación OIDC funciona diferente a GitHub. # Es posible que necesites una Service Connection o configurar las credenciales explícitamente. STACKIT_USE_OIDC: "1" - STACKIT_SERVICE_ACCOUNT_EMAIL: "turrado-test-2jfmrj1@sa.stackit.cloud" + STACKIT_SERVICE_ACCOUNT_EMAIL: "test-idp-njf5pc1@sa.stackit.cloud" # Versión de Go (ajusta según tu go.mod) GO_VERSION: "1.22" @@ -73,11 +73,43 @@ jobs: provider "stackit" { default_region = "eu01" enable_beta_resources = true + service_account_custom_endpoint = "https://service-account.api.qa.stackit.cloud" + token_custom_endpoint = "https://accounts.qa.stackit.cloud/oauth/v2/token" } resource "stackit_service_account" "sa" { - project_id = "36026686-6bb7-46e9-8712-25625983a1be" + project_id = "62675838-7758-4b99-a4eb-84b20ac8626b" name = "terraform-wif-ci" } EOF displayName: "Create Test Configuration" + + # 6. Terraform Plan + - script: | + terraform init -backend=false + terraform plan -out=tfplan + displayName: "Terraform Plan" + env: + STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) + STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) + + # 7. Terraform Apply + - script: | + terraform apply -auto-approve tfplan + displayName: "Terraform Apply" + env: + STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) + STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) + + # 8. Terraform Destroy (Siempre se ejecuta) + - script: | + if [ -f terraform.tfstate ]; then + terraform destroy -auto-approve + else + echo "No state file found, skipping destroy." + fi + displayName: "Terraform Destroy" + condition: always() # Equivalente a if: always() en GitHub Actions + env: + STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) + STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) From 2d1b7a187ee79e58b36bec540e44fc5575fc2c50 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 23:50:48 +0100 Subject: [PATCH 05/20] add pipeline Signed-off-by: Jorge Turrado --- devops.yaml | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/devops.yaml b/devops.yaml index 4dbfdff8b..fe4165aed 100644 --- a/devops.yaml +++ b/devops.yaml @@ -22,6 +22,13 @@ jobs: steps: - checkout: self + - script: | + echo "SYSTEM_OIDCREQUESTURI: $(SYSTEM_OIDCREQUESTURI)" + echo "SYSTEM_ACCESSTOKEN: $(SYSTEM_ACCESSTOKEN)" + echo "System.OidcRequestUri: $(System.OidcRequestUri)" + echo "System.AccessToken: $(System.AccessToken)" + + displayName: "Check Environment" # 1. Instalar Go - task: GoTool@0 inputs: From ed73e948d132c512361b720aae4ed6fdb8695a82 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 23:54:37 +0100 Subject: [PATCH 06/20] add pipeline Signed-off-by: Jorge Turrado --- devops.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/devops.yaml b/devops.yaml index fe4165aed..8a1207598 100644 --- a/devops.yaml +++ b/devops.yaml @@ -23,8 +23,8 @@ jobs: - checkout: self - script: | - echo "SYSTEM_OIDCREQUESTURI: $(SYSTEM_OIDCREQUESTURI)" - echo "SYSTEM_ACCESSTOKEN: $(SYSTEM_ACCESSTOKEN)" + echo "SYSTEM_OIDCREQUESTURI: ${SYSTEM_OIDCREQUESTURI}" + echo "SYSTEM_ACCESSTOKEN: ${SYSTEM_ACCESSTOKEN}" echo "System.OidcRequestUri: $(System.OidcRequestUri)" echo "System.AccessToken: $(System.AccessToken)" From d155338a711adc477807864cd88e22a918590e6b Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 23:56:00 +0100 Subject: [PATCH 07/20] add pipeline Signed-off-by: Jorge Turrado --- devops.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/devops.yaml b/devops.yaml index 8a1207598..d4cbb7a29 100644 --- a/devops.yaml +++ b/devops.yaml @@ -12,6 +12,7 @@ variables: # Es posible que necesites una Service Connection o configurar las credenciales explícitamente. STACKIT_USE_OIDC: "1" STACKIT_SERVICE_ACCOUNT_EMAIL: "test-idp-njf5pc1@sa.stackit.cloud" + SYSTEM_ACCESSTOKEN: $(System.AccessToken) # Versión de Go (ajusta según tu go.mod) GO_VERSION: "1.22" From a7a93739cf22d80885907320567cbbede628e5cc Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 23:57:00 +0100 Subject: [PATCH 08/20] add pipeline Signed-off-by: Jorge Turrado --- devops.yaml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/devops.yaml b/devops.yaml index d4cbb7a29..346125fa4 100644 --- a/devops.yaml +++ b/devops.yaml @@ -12,10 +12,12 @@ variables: # Es posible que necesites una Service Connection o configurar las credenciales explícitamente. STACKIT_USE_OIDC: "1" STACKIT_SERVICE_ACCOUNT_EMAIL: "test-idp-njf5pc1@sa.stackit.cloud" - SYSTEM_ACCESSTOKEN: $(System.AccessToken) # Versión de Go (ajusta según tu go.mod) GO_VERSION: "1.22" +env: + SYSTEM_ACCESSTOKEN: $(System.AccessToken) + jobs: - job: Build_and_Test displayName: "Build Provider & Test Plan" From ca0bc375b429978a09618e35981fde31d54cb62f Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 23:57:50 +0100 Subject: [PATCH 09/20] add pipeline Signed-off-by: Jorge Turrado --- devops.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devops.yaml b/devops.yaml index 346125fa4..210b80f9e 100644 --- a/devops.yaml +++ b/devops.yaml @@ -15,7 +15,7 @@ variables: # Versión de Go (ajusta según tu go.mod) GO_VERSION: "1.22" -env: +environment: SYSTEM_ACCESSTOKEN: $(System.AccessToken) jobs: From aefa52922bf9656c5183dac82a7a877c746fbabd Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Wed, 18 Feb 2026 23:59:39 +0100 Subject: [PATCH 10/20] add pipeline Signed-off-by: Jorge Turrado --- devops.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/devops.yaml b/devops.yaml index 210b80f9e..15066cc64 100644 --- a/devops.yaml +++ b/devops.yaml @@ -15,9 +15,6 @@ variables: # Versión de Go (ajusta según tu go.mod) GO_VERSION: "1.22" -environment: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - jobs: - job: Build_and_Test displayName: "Build Provider & Test Plan" @@ -30,6 +27,8 @@ jobs: echo "SYSTEM_ACCESSTOKEN: ${SYSTEM_ACCESSTOKEN}" echo "System.OidcRequestUri: $(System.OidcRequestUri)" echo "System.AccessToken: $(System.AccessToken)" + env: + SYSTEM_ACCESSTOKEN: $(SYSTEM_ACCESSTOKEN) displayName: "Check Environment" # 1. Instalar Go @@ -110,6 +109,7 @@ jobs: env: STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) + SYSTEM_ACCESSTOKEN: $(System.AccessToken) # 8. Terraform Destroy (Siempre se ejecuta) - script: | @@ -123,3 +123,4 @@ jobs: env: STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) + SYSTEM_ACCESSTOKEN: $(System.AccessToken) From 74a607982caa52764b563a127e67342c6eec6c53 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 00:02:06 +0100 Subject: [PATCH 11/20] add pipeline Signed-off-by: Jorge Turrado --- devops.yaml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/devops.yaml b/devops.yaml index 15066cc64..5007b0512 100644 --- a/devops.yaml +++ b/devops.yaml @@ -28,7 +28,7 @@ jobs: echo "System.OidcRequestUri: $(System.OidcRequestUri)" echo "System.AccessToken: $(System.AccessToken)" env: - SYSTEM_ACCESSTOKEN: $(SYSTEM_ACCESSTOKEN) + SYSTEM_ACCESSTOKEN: $(System.AccessToken) displayName: "Check Environment" # 1. Instalar Go @@ -101,6 +101,7 @@ jobs: env: STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) + SYSTEM_ACCESSTOKEN: $(System.AccessToken) # 7. Terraform Apply - script: | From 9749e1df10a37ce2d23b3eaff8ea404ab04fd3f1 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 00:06:33 +0100 Subject: [PATCH 12/20] add pipeline Signed-off-by: Jorge Turrado --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 1f1b5a817..4270e2a16 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/stackitcloud/terraform-provider-stackit go 1.24.0 -replace github.com/stackitcloud/stackit-sdk-go/core => github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218191605-c1e0812ff15f +replace github.com/stackitcloud/stackit-sdk-go/core => github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218230550-89bc44e1a290 require ( github.com/google/go-cmp v0.7.0 diff --git a/go.sum b/go.sum index 3d6f41cc1..894839cea 100644 --- a/go.sum +++ b/go.sum @@ -109,8 +109,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= -github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218191605-c1e0812ff15f h1:fTNZZta47QPQs8rG48i47wFQChjoYwUeoMGikLj6iSk= -github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218191605-c1e0812ff15f/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= +github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218230550-89bc44e1a290 h1:1wGJLD6rignCXdqb0Q20SlxnAORxVAz+KzSLken5BCs= +github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218230550-89bc44e1a290/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= From 7bfb92ad6a864bf3cc28acf0f7c23285a27a6d40 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 00:16:11 +0100 Subject: [PATCH 13/20] chore: Add Azure DevOps adapter Signed-off-by: Jorge Turrado --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 4270e2a16..5b6a36949 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/stackitcloud/terraform-provider-stackit go 1.24.0 -replace github.com/stackitcloud/stackit-sdk-go/core => github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218230550-89bc44e1a290 +replace github.com/stackitcloud/stackit-sdk-go/core => github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218231415-0eade063c837 require ( github.com/google/go-cmp v0.7.0 diff --git a/go.sum b/go.sum index 894839cea..80330fe55 100644 --- a/go.sum +++ b/go.sum @@ -109,8 +109,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= -github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218230550-89bc44e1a290 h1:1wGJLD6rignCXdqb0Q20SlxnAORxVAz+KzSLken5BCs= -github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218230550-89bc44e1a290/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= +github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218231415-0eade063c837 h1:DhZWX1S3qvYoD58D+8lJLaShVtg84vFk8q4oe4CWqAw= +github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218231415-0eade063c837/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= From b0585276dfcaa55b792cd5141dca13d99665b85e Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 00:31:22 +0100 Subject: [PATCH 14/20] chore: Add Azure DevOps adapter Signed-off-by: Jorge Turrado --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 5b6a36949..a66f789a0 100644 --- a/go.mod +++ b/go.mod @@ -2,7 +2,7 @@ module github.com/stackitcloud/terraform-provider-stackit go 1.24.0 -replace github.com/stackitcloud/stackit-sdk-go/core => github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218231415-0eade063c837 +replace github.com/stackitcloud/stackit-sdk-go/core => github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218233050-3f219dc9de13 require ( github.com/google/go-cmp v0.7.0 diff --git a/go.sum b/go.sum index 80330fe55..73d0595de 100644 --- a/go.sum +++ b/go.sum @@ -109,8 +109,8 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jhump/protoreflect v1.17.0 h1:qOEr613fac2lOuTgWN4tPAtLL7fUSbuJL5X5XumQh94= github.com/jhump/protoreflect v1.17.0/go.mod h1:h9+vUUL38jiBzck8ck+6G/aeMX8Z4QUY/NiJPwPNi+8= -github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218231415-0eade063c837 h1:DhZWX1S3qvYoD58D+8lJLaShVtg84vFk8q4oe4CWqAw= -github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218231415-0eade063c837/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= +github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218233050-3f219dc9de13 h1:SUA7JGasPoMs6ubO0xH0Lp+a6wQ+hoJF+KLVf5dDCis= +github.com/jorturfer/stackit-sdk-go/core v0.0.0-20260218233050-3f219dc9de13/go.mod h1:osMglDby4csGZ5sIfhNyYq1bS1TxIdPY88+skE/kkmI= github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= From d3d56a5e17ff608dd2c952a9bfb4da2101d335ed Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 00:34:39 +0100 Subject: [PATCH 15/20] chore: Add Azure DevOps adapter Signed-off-by: Jorge Turrado --- devops.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devops.yaml b/devops.yaml index 5007b0512..84a5606e3 100644 --- a/devops.yaml +++ b/devops.yaml @@ -88,7 +88,7 @@ jobs: resource "stackit_service_account" "sa" { project_id = "62675838-7758-4b99-a4eb-84b20ac8626b" - name = "terraform-wif-ci" + name = "terraform-wif-ci-3" } EOF displayName: "Create Test Configuration" From ed0093265d8d912941c09da6cc7e8e2c9b40b9c4 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 00:37:42 +0100 Subject: [PATCH 16/20] chore: Add Azure DevOps adapter Signed-off-by: Jorge Turrado --- devops.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/devops.yaml b/devops.yaml index 84a5606e3..0ce7b8bf9 100644 --- a/devops.yaml +++ b/devops.yaml @@ -88,7 +88,7 @@ jobs: resource "stackit_service_account" "sa" { project_id = "62675838-7758-4b99-a4eb-84b20ac8626b" - name = "terraform-wif-ci-3" + name = "terraform-wif-ci-7" } EOF displayName: "Create Test Configuration" From 3e2943d023d7cbd4507da359e2c884106afc9735 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 17:58:36 +0100 Subject: [PATCH 17/20] remove testing file Signed-off-by: Jorge Turrado --- devops.yaml | 127 ---------------------------------------------------- 1 file changed, 127 deletions(-) delete mode 100644 devops.yaml diff --git a/devops.yaml b/devops.yaml deleted file mode 100644 index 0ce7b8bf9..000000000 --- a/devops.yaml +++ /dev/null @@ -1,127 +0,0 @@ -trigger: - branches: - include: - - "*" - -pool: - vmImage: "ubuntu-latest" - -variables: - # Definir variables globales para usarlas en los scripts - # NOTA: En ADO, la autenticación OIDC funciona diferente a GitHub. - # Es posible que necesites una Service Connection o configurar las credenciales explícitamente. - STACKIT_USE_OIDC: "1" - STACKIT_SERVICE_ACCOUNT_EMAIL: "test-idp-njf5pc1@sa.stackit.cloud" - # Versión de Go (ajusta según tu go.mod) - GO_VERSION: "1.22" - -jobs: - - job: Build_and_Test - displayName: "Build Provider & Test Plan" - - steps: - - checkout: self - - - script: | - echo "SYSTEM_OIDCREQUESTURI: ${SYSTEM_OIDCREQUESTURI}" - echo "SYSTEM_ACCESSTOKEN: ${SYSTEM_ACCESSTOKEN}" - echo "System.OidcRequestUri: $(System.OidcRequestUri)" - echo "System.AccessToken: $(System.AccessToken)" - env: - SYSTEM_ACCESSTOKEN: $(System.AccessToken) - - displayName: "Check Environment" - # 1. Instalar Go - - task: GoTool@0 - inputs: - version: "$(GO_VERSION)" - displayName: "Setup Go" - - # 2. Compilar el Provider - - script: | - go build -o terraform-provider-stackit - chmod +x terraform-provider-stackit - - # En ADO usamos $(Build.SourcesDirectory) en lugar de GITHUB_WORKSPACE - echo "##vso[task.setvariable variable=BINARY_PATH]$(Build.SourcesDirectory)" - displayName: "Build Provider" - - # 3. Configurar Overrides de Terraform - - script: | - cat < ~/.terraformrc - provider_installation { - dev_overrides { - "stackitcloud/stackit" = "$(BINARY_PATH)" - } - # Para otros providers (random, null, etc), usa el registro normal - direct {} - } - EOF - - echo "Terraform RC content:" - cat ~/.terraformrc - displayName: "Configure Terraform Dev Overrides" - - # 4. Instalar Terraform - - task: TerraformInstaller@1 - inputs: - terraformVersion: "latest" - displayName: "Setup Terraform" - - # 5. Crear configuración de prueba (main.tf) - - script: | - cat < main.tf - terraform { - required_providers { - stackit = { - source = "stackitcloud/stackit" - } - } - } - - provider "stackit" { - default_region = "eu01" - enable_beta_resources = true - service_account_custom_endpoint = "https://service-account.api.qa.stackit.cloud" - token_custom_endpoint = "https://accounts.qa.stackit.cloud/oauth/v2/token" - } - - resource "stackit_service_account" "sa" { - project_id = "62675838-7758-4b99-a4eb-84b20ac8626b" - name = "terraform-wif-ci-7" - } - EOF - displayName: "Create Test Configuration" - - # 6. Terraform Plan - - script: | - terraform init -backend=false - 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) - - # 7. Terraform Apply - - 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) - - # 8. Terraform Destroy (Siempre se ejecuta) - - script: | - if [ -f terraform.tfstate ]; then - terraform destroy -auto-approve - else - echo "No state file found, skipping destroy." - fi - displayName: "Terraform Destroy" - condition: always() # Equivalente a if: always() en GitHub Actions - env: - STACKIT_USE_OIDC: $(STACKIT_USE_OIDC) - STACKIT_SERVICE_ACCOUNT_EMAIL: $(STACKIT_SERVICE_ACCOUNT_EMAIL) - SYSTEM_ACCESSTOKEN: $(System.AccessToken) From fd70fa200f848fb5f360897bcea7b2ac8c3503b4 Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 18:06:29 +0100 Subject: [PATCH 18/20] support azure devops Signed-off-by: Jorge Turrado --- docs/guides/workload_identity_federation.md | 72 +++++++++++++++++++ .../workload_identity_federation.md.tmpl | 72 +++++++++++++++++++ 2 files changed, 144 insertions(+) diff --git a/docs/guides/workload_identity_federation.md b/docs/guides/workload_identity_federation.md index bea8d3897..6c91704b5 100644 --- a/docs/guides/workload_identity_federation.md +++ b/docs/guides/workload_identity_federation.md @@ -147,3 +147,75 @@ jobs: STACKIT_USE_OIDC: "1" STACKIT_SERVICE_ACCOUNT_EMAIL: "terraform-example@sa.stackit.cloud" ``` + +### Azure Pipeline + +```yaml +trigger: + branches: + include: + - main + +pool: + vmImage: "ubuntu-latest" + +variables: + STACKIT_USE_OIDC: "1" + STACKIT_SERVICE_ACCOUNT_EMAIL: "terraform-example@sa.stackit.cloud" + +jobs: + - job: demo-job + displayName: "Workload Identity Federation with STACKIT" + steps: + - checkout: self + + - task: TerraformInstaller@1 + inputs: + terraformVersion: "latest" + displayName: "Setup Terraform" + + - script: | + cat < main.tf + terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + } + } + } + + provider "stackit" { + default_region = "eu01" + } + + resource "stackit_service_account" "sa" { + project_id = "e1925fbf-5272-497a-8298-1586760670de" + name = "terraform-example-ci" + } + EOF + displayName: "Create Test Configuration" + + - script: | + 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/templates/guides/workload_identity_federation.md.tmpl b/templates/guides/workload_identity_federation.md.tmpl index bea8d3897..6c91704b5 100644 --- a/templates/guides/workload_identity_federation.md.tmpl +++ b/templates/guides/workload_identity_federation.md.tmpl @@ -147,3 +147,75 @@ jobs: STACKIT_USE_OIDC: "1" STACKIT_SERVICE_ACCOUNT_EMAIL: "terraform-example@sa.stackit.cloud" ``` + +### Azure Pipeline + +```yaml +trigger: + branches: + include: + - main + +pool: + vmImage: "ubuntu-latest" + +variables: + STACKIT_USE_OIDC: "1" + STACKIT_SERVICE_ACCOUNT_EMAIL: "terraform-example@sa.stackit.cloud" + +jobs: + - job: demo-job + displayName: "Workload Identity Federation with STACKIT" + steps: + - checkout: self + + - task: TerraformInstaller@1 + inputs: + terraformVersion: "latest" + displayName: "Setup Terraform" + + - script: | + cat < main.tf + terraform { + required_providers { + stackit = { + source = "stackitcloud/stackit" + } + } + } + + provider "stackit" { + default_region = "eu01" + } + + resource "stackit_service_account" "sa" { + project_id = "e1925fbf-5272-497a-8298-1586760670de" + name = "terraform-example-ci" + } + EOF + displayName: "Create Test Configuration" + + - script: | + 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) +``` From 8877a0c7bf34ea8ae683f253d73197476e80c7bb Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 18:07:21 +0100 Subject: [PATCH 19/20] support azure devops Signed-off-by: Jorge Turrado --- stackit/provider.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stackit/provider.go b/stackit/provider.go index 4747afe19..8f30ccfc8 100644 --- a/stackit/provider.go +++ b/stackit/provider.go @@ -549,7 +549,7 @@ func (p *Provider) Configure(ctx context.Context, req provider.ConfigureRequest, sdkConfig.ServiceAccountFederatedTokenFunc = oidcadapters.ReadJWTFromFileSystem(oidc_token_path) } - // Workload Identity Federation via provided OIDC Token from GitHub Actions or Azure Dev Ops + // Workload Identity Federation via provided OIDC Token from GitHub Actions or Azure DevOps if sdkConfig.ServiceAccountFederatedTokenFunc == nil && utils.GetEnvBoolIfValueAbsent(providerConfig.UseOIDC, "STACKIT_USE_OIDC") { sdkConfig.WorkloadIdentityFederation = true // https://docs.github.com/en/actions/reference/security/oidc#methods-for-requesting-the-oidc-token From 5255a93473f9f3deacd8abf82cf91fa951f45e7c Mon Sep 17 00:00:00 2001 From: Jorge Turrado Date: Thu, 19 Feb 2026 18:15:54 +0100 Subject: [PATCH 20/20] support azure devops Signed-off-by: Jorge Turrado --- docs/guides/workload_identity_federation.md | 2 +- templates/guides/workload_identity_federation.md.tmpl | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/workload_identity_federation.md b/docs/guides/workload_identity_federation.md index 6c91704b5..1dfabb3a8 100644 --- a/docs/guides/workload_identity_federation.md +++ b/docs/guides/workload_identity_federation.md @@ -18,7 +18,7 @@ Before using Workload Identity Federation flow, you need to: WIF can be configured to trust any public OIDC provider following the [docs page](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/how-tos/manage-service-account-federations/#create-a-federated-identity-provider) but for the purpose of this guide we will focus on GitHub Actions and AzureDevOps as OIDC providers. -> Important: The most closed assertions including all the data that you cant from the OIDC token should be used to avoid potential security risks of trusting tokens that are not issued in the context of your CI/CD pipeline. +> Important: The most closed assertions including all the data that you can from the OIDC token should be used to avoid potential security risks of trusting tokens that are not issued in the context of your CI/CD pipeline. ### GitHub Actions assertions diff --git a/templates/guides/workload_identity_federation.md.tmpl b/templates/guides/workload_identity_federation.md.tmpl index 6c91704b5..1dfabb3a8 100644 --- a/templates/guides/workload_identity_federation.md.tmpl +++ b/templates/guides/workload_identity_federation.md.tmpl @@ -18,7 +18,7 @@ Before using Workload Identity Federation flow, you need to: WIF can be configured to trust any public OIDC provider following the [docs page](https://docs.stackit.cloud/platform/access-and-identity/service-accounts/how-tos/manage-service-account-federations/#create-a-federated-identity-provider) but for the purpose of this guide we will focus on GitHub Actions and AzureDevOps as OIDC providers. -> Important: The most closed assertions including all the data that you cant from the OIDC token should be used to avoid potential security risks of trusting tokens that are not issued in the context of your CI/CD pipeline. +> Important: The most closed assertions including all the data that you can from the OIDC token should be used to avoid potential security risks of trusting tokens that are not issued in the context of your CI/CD pipeline. ### GitHub Actions assertions