Configuring OpenID Connect for Azure
This document outlines the steps required to configure Pulumi to use OpenID Connect to authenticate with Azure. OIDC in Azure uses workload identity federation to access Azure resources via a Microsoft Entra App. Access to the temporary credentials is authorized using federated credentials that validate the contents of the OIDC token issued by the Pulumi Cloud.
Prerequisites
- You must be an admin of your Pulumi organization.
- You must have access in the Azure Portal to create and configure Microsoft Entra App registrations.
Create a Microsoft Entra Application
In the navigation pane of the Microsoft Entra console:
- Select App registrations and then click New registration.
- Provide a name for your application (ex:
pulumi-esc-oidc-app
). - In the Supported account types section, select Accounts in this organizational directory only.
- Click Register.
After the Microsoft Entra App has been created, take note of the following details:
- Subscription ID
- Application (client) ID
- Directory (tenant) ID
These values will be necessary when enabling OIDC for your service.
Add Federated Credentials
Once you have created your new application registration, you will be redirected to the application’s Overview page. In the left navigation menu:
- Navigate to the Certificates & secrets pane.
- Select the Federated credentials tab.
- Click on the Add credential button. This will start the “Add a credential” wizard.
- In the wizard, select Other Issuer as the Federated credential scenario.
- Fill in the remaining form fields as follows:
- Issuer:
https://api.pulumi.com/oidc
- Subject Identifier: must be a valid subject claim (see examples at the end of this section).
- Name: An arbitrary name for the credential, e.g. “pulumi-oidc-credentials”
- Audience: This is different between pulumi deployments and ESC. For Deployments this is only the name of your Pulumi organization. For ESC this is the name of your Pulumi organization prefixed with
azure:
(e.g.azure:{org}
).For environments in the `default` project the audience will use just the Pulumi organization name. This is to prevent regressions for legacy environments.
- Issuer:
Subject claim examples
Depending on the Pulumi service you are configuring OIDC for, the value of the subject claim will be different. You can learn more about configuring OIDC with Pulumi by referring to the relevant documentation.
The below sections show examples that correspond to each OIDC-supported service.
Pulumi Deployments
Because Azure’s federated credentials require that the subject identifier exactly matches an OIDC token’s subject claim, this process must be repeated for each permutation of the subject claim that is possible for a stack. For example, in order to enable all of the valid operations on a stack named dev
of the core
project in the contoso
organization, you would need to create credentials for each of the following subject identifiers:
pulumi:deploy:org:contoso:project:core:stack:dev:operation:preview:scope:write
pulumi:deploy:org:contoso:project:core:stack:dev:operation:update:scope:write
pulumi:deploy:org:contoso:project:core:stack:dev:operation:refresh:scope:write
pulumi:deploy:org:contoso:project:core:stack:dev:operation:destroy:scope:write
Pulumi ESC
The below is an example of a valid subject claim for the project/development
environment of the contoso
organization:
pulumi:environments:org:contoso:env:project/development
The default format of the subject claim when subjectAttributes
are not used is pulumi:environments:org:<organization name>:env:<project name>/<environment name>
default
project, the project will not be present in the subject to preserve backwards compatibility. The format of the subject claim when subjectAttributes
are not set is pulumi:environments:org:<organization name>:env:<environment name>
. If currentEnvironment.name
is used as a custom subject attribute it will resolve to only the environment name (e.g. pulumi:environments:pulumi.organization.login:contoso:currentEnvironment.name:development:pulumi.user.login:personA
). Due to this it is recommended to move your environments out of the default
project for best security practices.If you are integrating Pulumi ESC with Pulumi IaC, the default subject identifier of the ESC environment will not work at this time. There is a known issue with the subject identifier’s value sent to Azure from Pulumi.
Use ‘subjectAttributes’ to customize the subject identifier to work with Pulumi IaC. Alternatively, you can use this syntax: pulumi:environments:org:contoso:env:<yaml>
when configuring the subject claim in your cloud provider account. Make sure to replace contoso
with the name of your Pulumi organization and use the literal value of <yaml>
as shown.
Subject customization
It is possible to customize the OIDC token subject claim by setting configuring the subjectAttributes
setting. It expects an array of keys to include in it:
rootEnvironment.name
: the name of the environment that is opened first. This root environment in turn opens other imported environmentscurrentEnvironment.name
: the full name (including the project) of the environment where the ESC login provider andsubjectAttributes
are definedpulumi.user.login
: the login identifier of the user opening the environmentpulumi.organization.login
: the login identifier of the organization
The subject always contains the following prefix pulumi:environments:pulumi.organization.login:{ORGANIZATION_NAME}
and every key configured will be appended to this prefix. For example, consider the following environment:
values:
azure:
login:
fn::open::azure-login:
...
subjectAttributes:
- currentEnvironment.name
- pulumi.user.login
The subject will be pulumi:environments:pulumi.organization.login:contoso:currentEnvironment.name:project/development:pulumi.user.login:userLogin
. Note how the keys and values are appended along with the prefix.
Create a Service Principal
To provide Pulumi services the ability to deploy, manage, and interact with Azure resources, you need to associate your Microsoft Entra application with your Subscription or Resource Group.
- Navigate to the Subscriptions page of the Azure portal.
- Select the subscription to create the service principal in.
- If you want to limit access to a specific resource group, go to the Resource Groups page instead and select the desired resource group.
- In the left navigation menu, select Access control (IAM).
- Click Add > Add role assignment to be taken to the Add role assignment wizard.
- Under the Job function roles tab, select the desired role from the list, then click Next.
- Select User, group, or service principal, then click Select members
- Enter the name of the application you created in a previous step, select it from the list, then click Select.
- Click Next and then Review + assign.
Configure OIDC in the Pulumi Console
Pulumi Deployments
- Navigate to your stack in the Pulumi Console.
- Open the stack’s “Settings” tab.
- Choose the “Deploy” panel.
- Under the “OpenID Connect” header, toggle “Enable Azure Integration”.
- Enter the client and tenant IDs for the app registration created above in the “Client ID” and “Tenant ID” fields, repsectively.
- Enter the ID of the subscription you want to use in the “Subscription ID” field.
- Click the “Save deployment configuration” button.
With this configuration, each deployment of this stack will attempt to exchange the deployment’s OIDC token for Azure credentials using the specified AAD App prior to running any pre-commands or Pulumi operations. The fetched credentials are published in the ARM_CLIENT_ID
, ARM_TENANT_ID
, and ARM_SUBSCRIPTION_ID
environment variables. The raw OIDC token is also available for advanced scenarios in the PULUMI_OIDC_TOKEN
environment variable and the /mnt/pulumi/pulumi.oidc
file.
Pulumi ESC
To configure OIDC for Pulumi ESC, create a new environment in the Pulumi Console. Make sure that you have the correct organization selected in the left-hand navigation menu. Then:
Click the Environments link.
Click the Create environment button.
Provide a project to create your new environment in and a name for your environment.
- This should be the same as the identifier provided in the subject claim of your federated credentials.
Click the Create environment button.
You will be presented with a split-pane editor view. Delete the default placeholder content in the editor and replace it with the following code:
values: azure: login: fn::open::azure-login: clientId: <your-client-id> tenantId: <your-tenant-id> subscriptionId: /subscriptions/<your-subscription-id> oidc: true environmentVariables: ARM_USE_OIDC: 'true' ARM_CLIENT_ID: ${azure.login.clientId} ARM_TENANT_ID: ${azure.login.tenantId} ARM_OIDC_TOKEN: ${azure.login.oidc.token} ARM_SUBSCRIPTION_ID: ${azure.login.subscriptionId}
Replace
<your-client-id>
,<your-tenant-id>
, and<your-subscription-id>
with the values from the previous steps.Scroll to the bottom of the page and click Save.
You can validate that your configuration is working by running either of the following:
esc open <your-org>/<your-project>/<your-environment>
command of the ESC CLIpulumi env open <your-org>/<your-project>/<your-environment>
command of the Pulumi CLI
Make sure to replace <your-org>
, <your-project>
, and <your-environment>
with the values of your Pulumi organization, project, and environment file respectively. You should see output similar to the following:
{
"azure": {
"login": {
"clientId": "b537....",
"oidc": {
"token": "eyJh...."
},
"subscriptionId": "0282....",
"tenantId": "7061...."
}
},
"environmentVariables": {
"ARM_CLIENT_ID": "b537....",
"ARM_OIDC_TOKEN": "eyJh....",
"ARM_SUBSCRIPTION_ID": "0282....",
"ARM_TENANT_ID": "7061....",
"ARM_USE_OIDC": "true"
}
}
To learn more about how to set up and use the various providers in Pulumi ESC, please refer to the relevant Pulumi documentation
Automate OIDC Configuration
Our Examples repository provides a wide variety of automations using Pulumi Infrastructure as Code (IaC). If you want to automate the configuration and deployment of OIDC between Pulumi and Azure, take a look at the following examples to help you get started:
Thank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.