Rotate Azure Key Vault secrets used by an ASP.NET Core Web API with Terraform on every deployment
Check out my blog post about this topic
- Visual Studio 2022 Preview
- .NET SDK 9.0.100-rc.2
- Azure tenant with a subscription and permissions to create resources and app registrations
- Azure CLI
- Terraform 1.9.8
-
Adjust values in
iac-core\vars\dev.core.tfvars
-
Create resources to host terraform state by executing the following commands
az login -t [AZURE_TENANT_ID] cd [PATH_TO_REPOSITORY]\iac-core terraform init terraform apply --var-file=.\vars\dev.core.tfvars --state=dev.core.tfstate
Important
To generate deployment credentials and to configure the GitHub secrets for the GitHub actions workflow, see here.
There are currently two GitHub environments set up for this repository: dev
and dev-iac
.
For both of them a separate federated credential is set up in the Entra app which got created while generating deployment credentials.
Furthermore the service principal of the Entra app is a member of the Entra group kv-secret-rotation-sample-contributor-iac
and the following Microsoft Graph application permissions got added
Application.ReadWrite.All
Domain.Read.All
Group.ReadWrite.All
Finally, the service principal was assigned the Owner
role for the resource group.
Note
The application resources are created via GitHub actions workflow. The following steps are only required, if you want to create the resources manually.
-
Adjust values in
iac\vars\dev.app.tfvars
-
Adjust values in
iac\backend\dev.backend.tfvars
-
Create application resources using the following commands
az login -t [AZURE_TENANT_ID] cd [PATH_TO_REPOSITORY]\iac terraform init --backend-config=backend\dev.backend.tfvars terraform apply --var-file=.\vars\dev.app.tfvars --state=dev.app.tfstate
-
Clone this GitHub repository
-
Open the solution
src\ArbitraryAspNetCoreWebApi.sln
inVisual Studio 2022 Preview
-
Update the values of the following keys in
appsettings.Development.json
AzureAd:ClientId
(client id of the app registration with infixApplication
created by Terraform)AzureAd:Domain
(domain of the Azure tenant)AzureAd:TenantId
(id of the Azure tenant)
-
Look up the Azure Key Vault secret with name
LocalDevClientSecret
-
Right click on the project
ArbitraryAspNetCoreWebApi
and selectManage User Secrets
-
Add the following content to the
secrets.json
file and replace the value ofClientSecret
with the secret from the Azure Key Vault{ "AzureAd": { "ClientSecret": "VALUE_OF_LOCAL_DEV_CLIENT_SECRET" } }
-
Right click on the project
ArbitraryAspNetCoreWebApi
and selectSet as Startup Project
-
Press
F5
to start the application
To test the application (either a locally running instance or a deployed one), proceed as follows.
Important
- A client secret for app registration
kv-secret-rotation-sample Client dev
has to be created manually via the Azure portal - Admin consent has to be granted for the permissions granted to app registration
kv-secret-rotation-sample Client dev
-
Request an authorization code by opening the following URL in a browser
https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize?client_id={client_app_reg_client_id}&response_type=code&redirect_uri=http://localhost&response_mode=query&scope=api://{web_API_application_client_id}/Forecast.Read
{tenant_id}
: id of the Azure tenant{client_app_reg_client_id}
: client id of the app registration with infixClient
created by Terraform{web_API_application_client_id}
: client id of the app registration with infixApplication
created by Terraform
-
Copy the authorization code from the URL and use it in the following request in windows command prompt
curl -X POST https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/token ^ -d "client_id={client_app_reg_client_id}" ^ -d "api://{web_API_application_client_id}/Forecast.Read" ^ -d "code={authorization_code}&session_state={client_app_reg_client_id}" ^ -d "redirect_uri=http://localhost" ^ -d "grant_type=authorization_code" ^ -d "client_secret={client_secret}"
-
Copy the access token from the response and use it in the following request
curl -X GET https://APPLICATION_BASE_URL:PORT/WeatherForecast ^ -H "Authorization: Bearer {access_token}"
Note
Alternatively, you can use Postman
to send the requests.
- Set up a GitHub Actions workflow manually
- Authenticating using a Service Principal and OpenID Connect
- Tutorial: Register a web API with the Microsoft identity platform
- Tutorial: Create and configure an ASP.NET Core project for authentication
- Tutorial: Implement a protected endpoint to your API
- Call an ASP.NET Core web API with cURL