Loading README.md +192 −0 Original line number Diff line number Diff line Loading @@ -888,3 +888,195 @@ include: # specific OIDC role ARN for prod aws-prod-oidc-role-arn: "arn:aws:iam::222222222222:role/cicd-role" ``` ## Azure authentication with OIDC The Terraform template supports authenticating to Azure using OpenID Connect (OIDC) without requiring a dedicated variant. This approach leverages [GitLab's ID tokens](https://docs.gitlab.com/ci/secrets/id_token_authentication/) and the [Azure Provider's OIDC support](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_oidc). ### Prerequisites Before using OIDC authentication with Azure, you must: 1. Configure [Workload Identity Federation between GitLab and Azure](https://docs.gitlab.com/ci/cloud_services/azure/) (following the GitLab guide) 2. Create a Service Principal in Azure with appropriate permissions 3. Configure the federated credential on your Service Principal to trust your GitLab instance ### Configuration #### Step 1: Configure GitLab to generate the ID token Add the following to your `.gitlab-ci.yml` to generate an ID token for Azure authentication: ```yaml .tf-base: id_tokens: ARM_OIDC_TOKEN: aud: api://AzureADTokenExchange # Prefered over GitLab instance URL[2] ``` The `.tf-base` job is the base job that all Terraform jobs inherit from, so this configuration will apply to all Terraform operations. :bulb: Audience `api://AzureADTokenExchange` is the [recommended value][2] that tells the Microsoft API to accept the aud claim in the incoming token. [2]: https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azcli#:~:text=600%20characters.%20The-,recommended%20value,-is%20%22api%3A//AzureADTokenExchange #### Step 2: Configure the Azure Provider in your Terraform code In your Terraform configuration files, configure the `azurerm` provider to use OIDC authentication: ```terraform provider "azurerm" { features {} # OIDC authentication settings - use_oidc MUST be set to true use_oidc = true # Required for OIDC authentication client_id = var.client_id # Your Service Principal's Application (client) ID tenant_id = var.tenant_id # Your Azure AD tenant ID subscription_id = var.subscription_id # Your Azure subscription ID # Optional: only required when your Service Principal lacks permissions to register Resource Providers resource_provider_registrations = "none" } ``` :warning: **Important**: The `use_oidc = true` parameter is **required** for OIDC authentication to work. Without it, the provider will not attempt to authenticate using the OIDC token. See the [Azure Provider OIDC documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_oidc) for more details. #### Step 3: Set the required Terraform variables Define the required variables as GitLab CI/CD variables: * `TF_VAR_client_id`: Your Azure Service Principal's Application (client) ID * `TF_VAR_tenant_id`: Your Azure AD tenant ID * `TF_VAR_subscription_id`: Your Azure subscription ID :bulb: **Tip**: Use [GitLab CI/CD variables](https://docs.gitlab.com/ci/variables/#for-a-project) to manage these values. Mark them as **masked** to prevent them from appearing in logs. ### Multiple environments with different credentials If you need to use different Service Principals for different environments (e.g., separate credentials for production), use environment-specific `.tfvars` files. The template will automatically apply the appropriate `.tfvars` file based on the deployment environment. In your `.gitlab-ci.yml`, you only need to configure the ID token (see example in the next section). ### Complete example Here's a complete example combining all the pieces: **`.gitlab-ci.yml`:** ```yaml include: - component: $CI_SERVER_FQDN/to-be-continuous/terraform/gitlab-ci-terraform@8.1.2 inputs: image: docker.io/hashicorp/terraform:latest staging-enabled: true prod-enabled: true .tf-base: id_tokens: ARM_OIDC_TOKEN: aud: api://AzureADTokenExchange ``` **`production.env.tfvars`:** ```hcl client_id = "44444444-4444-4444-4444-444444444444" tenant_id = "55555555-5555-5555-5555-555555555555" subscription_id = "66666666-6666-6666-6666-666666666666" ``` **`staging.env.tfvars`:** ```hcl client_id = "11111111-1111-1111-1111-111111111111" tenant_id = "22222222-2222-2222-2222-222222222222" subscription_id = "33333333-3333-3333-3333-333333333333" ``` **`main.tf`:** ```terraform terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 3.0" } } } provider "azurerm" { features {} use_oidc = true # Required for OIDC authentication client_id = var.client_id tenant_id = var.tenant_id subscription_id = var.subscription_id # Only set this if your Service Principal cannot register Resource Providers resource_provider_registrations = "none" } ``` **`variables.tf`:** ```terraform variable "client_id" { description = "Azure Service Principal client ID" type = string } variable "tenant_id" { description = "Azure AD tenant ID" type = string } variable "subscription_id" { description = "Azure subscription ID" type = string } ``` ### Troubleshooting #### Authentication fails with `AADSTS700016: Application not found` This indicate that de Service Principal for the registered Application is not properly configured. Verify that: - Your Service Principal's Application ID (`client_id`) is correct - The federated credential is properly configured on the Service Principal - The `aud` claim in your ID token configuration matches what's configured in Azure #### Error `The client '...' with object id '...' does not have authorization to perform action` Ensure your Service Principal has been granted the appropriate Azure RBAC roles on the target subscription or resource groups. #### Authentication fails with `AADSTS7002131: No matching federated identity record found` This error indicates that the federated identity credential configured in Azure doesn't match the JWT token claims that GitLab is presenting. Verify that: - The federated credential's **Subject** field matches your GitLab project path pattern (e.g., `project_path:mygroup/myproject:ref_type:branch:ref:main` for the main branch, or use a wildcard like `project_path:mygroup/myproject:ref_type:branch:ref:*` to match all branches) - The **Audience** configured in Azure matches the `aud` value in your `.gitlab-ci.yml` ID token configuration #### Provider initialization is slow or fails with resource provider errors Try adding `resource_provider_registrations = "none"` to your provider configuration if your Service Principal doesn't have permissions to register Resource Providers. No newline at end of file Loading
README.md +192 −0 Original line number Diff line number Diff line Loading @@ -888,3 +888,195 @@ include: # specific OIDC role ARN for prod aws-prod-oidc-role-arn: "arn:aws:iam::222222222222:role/cicd-role" ``` ## Azure authentication with OIDC The Terraform template supports authenticating to Azure using OpenID Connect (OIDC) without requiring a dedicated variant. This approach leverages [GitLab's ID tokens](https://docs.gitlab.com/ci/secrets/id_token_authentication/) and the [Azure Provider's OIDC support](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_oidc). ### Prerequisites Before using OIDC authentication with Azure, you must: 1. Configure [Workload Identity Federation between GitLab and Azure](https://docs.gitlab.com/ci/cloud_services/azure/) (following the GitLab guide) 2. Create a Service Principal in Azure with appropriate permissions 3. Configure the federated credential on your Service Principal to trust your GitLab instance ### Configuration #### Step 1: Configure GitLab to generate the ID token Add the following to your `.gitlab-ci.yml` to generate an ID token for Azure authentication: ```yaml .tf-base: id_tokens: ARM_OIDC_TOKEN: aud: api://AzureADTokenExchange # Prefered over GitLab instance URL[2] ``` The `.tf-base` job is the base job that all Terraform jobs inherit from, so this configuration will apply to all Terraform operations. :bulb: Audience `api://AzureADTokenExchange` is the [recommended value][2] that tells the Microsoft API to accept the aud claim in the incoming token. [2]: https://learn.microsoft.com/en-us/entra/workload-id/workload-identity-federation-create-trust?pivots=identity-wif-apps-methods-azcli#:~:text=600%20characters.%20The-,recommended%20value,-is%20%22api%3A//AzureADTokenExchange #### Step 2: Configure the Azure Provider in your Terraform code In your Terraform configuration files, configure the `azurerm` provider to use OIDC authentication: ```terraform provider "azurerm" { features {} # OIDC authentication settings - use_oidc MUST be set to true use_oidc = true # Required for OIDC authentication client_id = var.client_id # Your Service Principal's Application (client) ID tenant_id = var.tenant_id # Your Azure AD tenant ID subscription_id = var.subscription_id # Your Azure subscription ID # Optional: only required when your Service Principal lacks permissions to register Resource Providers resource_provider_registrations = "none" } ``` :warning: **Important**: The `use_oidc = true` parameter is **required** for OIDC authentication to work. Without it, the provider will not attempt to authenticate using the OIDC token. See the [Azure Provider OIDC documentation](https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_oidc) for more details. #### Step 3: Set the required Terraform variables Define the required variables as GitLab CI/CD variables: * `TF_VAR_client_id`: Your Azure Service Principal's Application (client) ID * `TF_VAR_tenant_id`: Your Azure AD tenant ID * `TF_VAR_subscription_id`: Your Azure subscription ID :bulb: **Tip**: Use [GitLab CI/CD variables](https://docs.gitlab.com/ci/variables/#for-a-project) to manage these values. Mark them as **masked** to prevent them from appearing in logs. ### Multiple environments with different credentials If you need to use different Service Principals for different environments (e.g., separate credentials for production), use environment-specific `.tfvars` files. The template will automatically apply the appropriate `.tfvars` file based on the deployment environment. In your `.gitlab-ci.yml`, you only need to configure the ID token (see example in the next section). ### Complete example Here's a complete example combining all the pieces: **`.gitlab-ci.yml`:** ```yaml include: - component: $CI_SERVER_FQDN/to-be-continuous/terraform/gitlab-ci-terraform@8.1.2 inputs: image: docker.io/hashicorp/terraform:latest staging-enabled: true prod-enabled: true .tf-base: id_tokens: ARM_OIDC_TOKEN: aud: api://AzureADTokenExchange ``` **`production.env.tfvars`:** ```hcl client_id = "44444444-4444-4444-4444-444444444444" tenant_id = "55555555-5555-5555-5555-555555555555" subscription_id = "66666666-6666-6666-6666-666666666666" ``` **`staging.env.tfvars`:** ```hcl client_id = "11111111-1111-1111-1111-111111111111" tenant_id = "22222222-2222-2222-2222-222222222222" subscription_id = "33333333-3333-3333-3333-333333333333" ``` **`main.tf`:** ```terraform terraform { required_providers { azurerm = { source = "hashicorp/azurerm" version = "~> 3.0" } } } provider "azurerm" { features {} use_oidc = true # Required for OIDC authentication client_id = var.client_id tenant_id = var.tenant_id subscription_id = var.subscription_id # Only set this if your Service Principal cannot register Resource Providers resource_provider_registrations = "none" } ``` **`variables.tf`:** ```terraform variable "client_id" { description = "Azure Service Principal client ID" type = string } variable "tenant_id" { description = "Azure AD tenant ID" type = string } variable "subscription_id" { description = "Azure subscription ID" type = string } ``` ### Troubleshooting #### Authentication fails with `AADSTS700016: Application not found` This indicate that de Service Principal for the registered Application is not properly configured. Verify that: - Your Service Principal's Application ID (`client_id`) is correct - The federated credential is properly configured on the Service Principal - The `aud` claim in your ID token configuration matches what's configured in Azure #### Error `The client '...' with object id '...' does not have authorization to perform action` Ensure your Service Principal has been granted the appropriate Azure RBAC roles on the target subscription or resource groups. #### Authentication fails with `AADSTS7002131: No matching federated identity record found` This error indicates that the federated identity credential configured in Azure doesn't match the JWT token claims that GitLab is presenting. Verify that: - The federated credential's **Subject** field matches your GitLab project path pattern (e.g., `project_path:mygroup/myproject:ref_type:branch:ref:main` for the main branch, or use a wildcard like `project_path:mygroup/myproject:ref_type:branch:ref:*` to match all branches) - The **Audience** configured in Azure matches the `aud` value in your `.gitlab-ci.yml` ID token configuration #### Provider initialization is slow or fails with resource provider errors Try adding `resource_provider_registrations = "none"` to your provider configuration if your Service Principal doesn't have permissions to register Resource Providers. No newline at end of file