I am looking at this example from the terraform docs for creating an azure group:
resource "azurerm_resource_group" "test" {
name = "testResourceGroup1"
location = "West US"
tags = {
environment = "Production"
}
}
It does not specify the subscription anywhere.
How can I specify the subscription?
For your issue, you know the Terraform deploy the Azure resources through the Azure CLI. And there are four ways to authenticate.
Authenticating to Azure using the Azure CLI
Authenticating to Azure using Managed Service Identity
Authenticating to Azure using a Service Principal and a Client Certificate
Authenticating to Azure using a Service Principal and a Client Secret
If you do not set the tenant Id and subscription Id in the Terraform code, then you must use the first method in default. And you authenticate via the Azure CLI with the account that you log in the Azure CLI. So which subscription you set in the CLI then you use it for your Terraform.
But as the Terraform recommend:
We recommend using either a Service Principal or Managed Service
Identity when running Terraform non-interactively (such as when
running Terraform in a CI server) - and authenticating using the Azure
CLI when running Terraform locally.
So that you could grant the more appropriate permission for the service principal as you want.
Subscription is set when you configure Terraform to log in to Azure. The recommended way is to use an Azure AD service principal and environment variables.
To configure Terraform to use your Azure AD service principal, set the following environment variables, which are then used by the Azure Terraform modules. You can also set the environment if working with an Azure cloud other than Azure public.
ARM_SUBSCRIPTION_ID
ARM_CLIENT_ID
ARM_CLIENT_SECRET
ARM_TENANT_ID
ARM_ENVIRONMENT
Reference
Related
I have an Azure subscription with ACR and App Configuration services.
I am implementing a pipeline that access Azure through DevOps Service Connection that has Contributor role for both resources. However, using Az Client task pipeline cannot see or access those resources.
If I execute "az resources list" I don't see those resources even though Service Connection has access to them.
I have the same setup working on my personal subscription. What am I missing?
Tried to reproduce same scenario in my personal subscription and it worked with the same level of access for Service Connection.
Also it works in PowerShell console with a user account with the same permissions.
I want my terraform scripts to be able to authenticate on multiple azure subscriptions using multiple service principal.
Here is what I think:
Create a service principal (App registration).
Deploy terraform scripts in azure container instances
Give the "contributor" role to my service principal on the subscription (x)
Configure terraform scripts with environment variables to select the right credentials when I want to create resources in this subscription.
$ export ARM_SUBSCRIPTION_ID=159f2485-xxxx-xxxx-xxxx-xxxxxxxxxxxx # Client subscription
$ export ARM_CLIENT_ID=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx # client_id of the service principal
$ export ARM_CLIENT_SECRET=xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
$ export ARM_TENANT_ID=72f988bf-xxxx-xxxx-xxxx-xxxxxxxxxxxx # the same tenant for all clients
Is this correct?
Do you have a more secure way to authenticate on multiple subscriptions when using terraform cloud? (ideally without client_secret)
If the container instance can run Terraform script, then there is no problem with the steps. You give permission to the service principal and change the environment variable ARM_SUBSCRIPTION_ID for different subscriptions, then Terraform script works for different subscriptions.
A safer way is to use the authentication with Azure CLI. If you set different subscriptions with the CLI command:
az account set --subscription="SUBSCRIPTION_ID"
Then the Terraform script will also work for different subscriptions. In this way you don't need to set the secret as the environment variable.
I'm an owner of an Azure resource group but not have permissions on the subscription or on the management group.
When configuring the "azurerm" provider inside my .tf file, I've added subscription id and tenant id (I'm not the owner of that subscription).
--------------------- UPDATE ---------------------
I'm trying to apply Linux virtual machine using Terraform but having authorization issues while planning the .tf file.
I've listed all my accounts using Azure CLI (want to connect the second subscription in the output below):
I've succeeded authenticating to the subscription using Azure CLI with the command (it worked):
az account set --subscription="SUBSCRIPTION_ID"
It's my default and current subscription:
Also, I was able to create and manage resources inside my resource group in that subscription using Azure CLI.
However, I added the exact tenant ID and the exact subscription ID inside my .tf file and still got the same credentials errors during the "terraform plan".
Using Azure CLI or Azure portal I am able to create and manage resources inside the resource group's scope, although using terraform I'm facing problems.
Thank you :)
According to your story, you just set the tenant id and subscription id in the azure provider, so it seems you authenticate via Azure CLI. No matter you have a user account or a service principal, the owner role of the resource group is enough to create virtual machine in the resource group. In this way, you need to logging into the Azure CLI first. As it shows in the link I have provided.
I have a project that is running on Azure DevOps that requires creating a KeyVault and giving a series of managed AppService identities access to secrets in that vault.
Because of Terraform not being able to give its own service connection access to the key vault(this is a bug of some kind), I am forced to create ResourceGroup and Keyvault with SP access before Terraforming.
When running terraform import on resourcegroup and Keyvault through a PowerShell task:
terraform init
$state = terraform state list
if ($state -like '*azurerm_resource_group.instancerg*' -and '*azurerm_key_vault.instancekeyvault*') {
Write-Host "Resources have already been imported!"
}
else {
terraform import azurerm_resource_group.instancerg /subscriptions/$(subscriptionid)/resourceGroups/rgname
terraform import azurerm_key_vault.instancekeyvault /subscriptions/$(subscriptionid)/resourceGroups/rgname/providers/Microsoft.KeyVault/vaults/keyvaultname
}
Failure happens on terraform import commands:
'Authenticate using a Service Principal' To authenticate to Azure
using a Service Principal, you can use the separate auth method -
instructions for which can be found here:'
My main.tf contains:
provider "azurerm" {
version = "=2.7.0"
subscription_id = var.subscriptionid
client_id = var.devopsserviceconnectionaid
client_secret = var.devopsserviceconnectionpw
tenant_id = var.tennantid
features {}
}
The variables are all linked to the proper credentials.
From what I understand Terraform should pick up on what authentication method that is being used based on the credentials that are in the block above or specific env variables (that are also present...) but somehow Terraform still thinks I'm trying to auth through Azure Cli and not Service principal.
You can use manage identities in keyvault in terraform as shown below.
object_id = azurerm_app_service.app.identity.0.principal_id
Web app is as below creating managed identity
KV as below
The order should be create web app with managed identity, then the KV then the KV access policy.
For authenticate with Azure pipelines service connection below works fine but you need to pass the arguments via the pipeline.
for further information check this blog here
Full PowerShell based implementation calling terraform with Azure DevOps pipelines is explained here. This implementation prevents any azure resources as prerequisite before terraforming. Only prerequisite is creating the SPN to enable authentication and authorization.
My pipe in bitbucket:
- pipe: microsoft/azure-cli-run:1.0.2
variables:
AZURE_APP_ID: $AZURE_APP_ID
AZURE_PASSWORD: $AZURE_PASSWORD
AZURE_TENANT_ID: $AZURE_TENANT_ID
Where is AZURE_APP_ID? On Azure -> App Services I can see a table with my apps but no application id. And what password is it? I haven't set a password anywhere. And tenant id?
First you need to create an Azure service principal in your azure subscription to enable connecting bitbucket to azure services.
When you create the service principal you will get a set of information after successful creation from which you can extract the app ID and tenant ID. This is via azure CLI.
az ad sp list --show-mine --query '[].{"id":"appId", "tenant":"appOwnerTenantId"}'
This information along with your azure password is what you need to supply to the bitbucket pipeline to enable deployment from your repo to azure.