Terraform authentication multi-subscription using multiple service principals - terraform

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.

Related

How can I terraform granting access to my Azure Active Directory Tenant

Input: client_id, subscription_id, resource-group-name, .
Manual / command line steps:
Approving at
https://login.microsoftonline.com/<tenant-id>/oauth2/authorize?client_id=<client_id>&response_type=code
Creating a new role (az role definition create --output none --role-definition)
Creating a role assignment (az role assignment create).
Steps 2-3 are pretty easy since I could leverage azurerm TF Provider and, more speficially, its azurerm_role_definition and azurerm_role_assignment resources but I'm kinda confused about step #1.
Update: after googling it seems like step #1 is very similar to Enable Azure Active Directory in your App Service app if that helps.
Before you can even get Terraform to interact with Azure/Azure AD resources you need to get Terraform to authenticate to it.
If you're running your Terraform code locally, the process is generally to authenticate using the Azure CLI - az login and then you provide the code shown by the CLI, to the authentication page.
If you want to do this non-interactively, the best practice is you'd need to get the Terraform code run on a machine that either has Managed Identities enabled. Either a System-Assigned or a User-Assigned identity.
Another possible but less direct approach would be to use a Service Principal with a Client Secret for Terraform to authenticate. this is kinda like the link you provided for the App Service.
Try to follow the steps in those two links above as these are from Terraform and have all required steps to ensure you are able to set it up right.

Terraform "AuthorizationFailed" with Azure provider

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.

How to use multiple azure managed service identity in Terraform provider

I have two subscriptions and a VM in my Azure account. I have assigned two Service Identities to the VM where each MSI is assigned with one subscription. I want my terraform script to use both of them in my providers block. How to proceed with this situation.
I tried to provide client id of the MSI within the provider block but terraform somewhat considers 1 MSI as default and goes along with it.
You can define multiple providers in the terraform script, then use the MSI authenticate. And you can choose which provider to use with the provider property when you create the resources.

Using Azure API without login (using roles)

I'm trying to list virtual machines in azure from inside another virtual machine in azure. I mean, what I want to do is list backend members from the frontent. BUT I don't want to use credentials in my front end and I want to use roles.
For example, in AWS you can assign roles (EC2::DescribeInstance) to instances and use this command:
aws ec2 describe-instances --query 'Reservations[].Instances[].[PrivateIpAddress]' --output text --filters Name=instance-state-name,Values=running Name=tag:myapp-member,Values=myapp-backend
I can run that command without expose my credentials in any place.
If I run something like this on Azure
az vm list
It says I need to login first.
And I can't find how to assign roles to the instance.
Thanks a lot
Cheers
For your purpose, you can use the VM Managed Identity to log in for the Azure CLI, this way will not store any credential in the VM. But first, you need to assign the roles to your VM. And to assign the roles, you can use the Azure CLI command az role assignment create and the steps in Assign a managed identity access to a resource using Azure CLI. Or just in the Azure Portal, you can follow the steps in Assign a managed identity access to a resource by using the Azure portal. The PowerShell command is also available.
When the role is created, you can use the Azure CLI command az login --identity to log in without credential.
Note: You need to install the Azure CLI in the VM first.

create an azure resource group under a subscription with terraform

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

Resources