Terraform - Azure as a provider and limited access account - azure

I want to deploy some resources on Azure with Terraform.
On Azure, I have an account with "Owner rights" on one Resource Group only(RGName). Not at the subscription level.
From my linux server, I installed "az cli" and I did "az login". At this step, everything is OK.
The problem appears when I want to execute terraform to create one resource.
Content of provider.tf (the only one .tf file for now) :
provider "azurerm" {
}
If I do a "terraform plan", it works.
If I add the following line, it fails. Please see the error at the end :
resource "azurerm_virtual_network" "myterraformnetwork" {
name = "myVnet"
address_space = ["10.0.0.0/16"]
location = "eastus"
resource_group_name = "RGName"
tags = {
environment = "Terraform Demo"
}
}
I do not have right on subscription level but I do not need to.
With the Azure WebUI I can create resource on this Resource Group without problem.
The error :
Error: Error ensuring Resource Providers are registered: Cannot register provider Microsoft.DevSpaces with Azure Resource Manager: resources.ProvidersClient#Register: Failure responding to request: StatusCode=403 -- Original Error: autor
est/azure: Service returned an error. Status=403 Code="AuthorizationFailed" Message="The client 'accountName' with object id 'IDaccountName' does not have authorization to perform action 'Microsoft.DevSpaces/r
egister/action' over scope '/subscriptions/subscriptionID' or the scope is invalid. If access was recently granted, please refresh your credentials.".
on provider.tf line 1, in provider "azurerm":
1: provider "azurerm" {
Thank you all !

If anyone else has this issue in a corporate (restricted) Azure environment, and doesn't have the patience to register the provider (which may not be necessary if you don't use the specified terraform resource) - have a look at https://github.com/terraform-providers/terraform-provider-azurerm/issues/4440
Specifically, this may help:
provider "azurerm" {
skip_provider_registration = "true"
It obviously won't help if you actually need the resource that fails to get registered (in our case it was Cannot register provider Microsoft.DevSpaces with Azure Resource Manager, but the resource will be variable depending on your environment and what Terraform decides to support)

For your issue, when you have the Owner role of the resource group, you can create new resources or manage the existing resources as you want. So permission is no problem. With the test on my side, it works well using a user has the Owner role of the resource group.
As the error shows, I think the possible reason is that you have multiple subscriptions in the tenant and the current subscription is not the right one which the user has the right permission. You can try to take a check and set the right subscription via the command:
az account set --subscription subscription_id

Thank you for your answer.
I got this when I execute "az account list" :
"cloudName": "AzureCloud",
"id": "***********0d43",
"isDefault": true,
"name": "BU*******",
"state": "Enabled",
"tenantId": "TENANTID",
"user": {
"name": "LOGINNAME",
"type": "user"
I do not have rights on this subscription but it is the only one that I know.
On Azure WebUI I can see that the RGName is on the same subscription.
This is a capture from Azure WebUI on the RGName :
Azure WebUI
Thank you

You may need to register the Resource provider by clicking on register as shown in below screenshot under subscription id.

Related

Azure : ResourceNotFound from az cli but resource exist in Portal

Facing this "ResourceNotFound" issue (JPG-1), but I can see the logicapp resource in Azure portal(JPG-2)
(ResourceNotFound) The Resource 'Microsoft.Web/sites/us-analytics-dev-dsvm-auto-deletion-logicapp-eastus2' under resource group 'us-analytics-dev-dsvm-auto-deletion-eastus2' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix
Code: ResourceNotFound
Message: The Resource 'Microsoft.Web/sites/us-analytics-dev-dsvm-auto-deletion-logicapp-eastus2' under resource group 'us-analytics-dev-dsvm-auto-deletion-eastus2' was not found. For more details please go to https://aka.ms/ARMResourceNotFoundFix
Note :
Already configured (us-analytics-dev) as default subscription in
cli.
Logicapp resource created through Terraform (Code below : code-1)
Code-1 :(edited)
resource "azurerm_resource_group" "dsvm_auto_deletion_resource_group" {
name = "us-analytics-dev-dsvm-auto-deletion-logicapp-eastus2"
location = "East US 2"
}
resource "azurerm_logic_app_workflow" "dsvm_auto_deletion_logicapp" {
name = "us-analytics-dev-dsvm-auto-deletion-logicapp-eastus2"
location = "East US 2"
resource_group_name = "us-analytics-dev-dsvm-auto-deletion-eastus2"
}
First note I noticed your azurerm_resource_group resource name is the same as your azurerm_logic_app_workflow resource name but I think it is just a typo :)
I tried the same command as you and it didn't work for me, it kept returning empty list, I think something is wrong with the az logicapp command.
After some research I found that there is a package in preview that can be used instead which is logic workflow.
Just past in the following command and install the package and it should work, so for your case it would be something like :
az logic workflow show -g us-analytics-dev-dsvm-auto-deletion-eastus2 --name us-analytics-dev-dsvm-auto-deletion-logicapp-eastus2

Error: Failed to get existing workspaces: containers.Client#ListBlobs:

Error: Failed to get existing workspaces: containers.Client#ListBlobs: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailure" Message="This request is not authorized to perform this operation.\nRequestId:XXX"
I am using azure storage as Terraform backend. It was working fine. I removed a private endpoint for the storage from configuration and did terraform apply. It starts giving me this error. Is there need of Private endpoint for storing Terraform state in Azure storage? Also not sure why got above error. I am unable to do terraform init with this error.
I tried in my environment and got below results:
Main
provider "azurerm" {
features{
resource_group {
prevent_deletion_if_contains_resources = false
}
}
}
provider "azuread" {
}
data "azurerm_resource_group" "example" {
name = "< Resource group name >"
}
data "azurerm_storage_account" "example" {
name = "venkat123"
resource_group_name = data.azurerm_resource_group.example.name
}
terraform {
backend "azurerm" {
resource_group_name = "< Resource group name >"
storage_account_name = "venkat123"
container_name = "test"
key = "terraform.tfstate"
}
}
Before running the code make sure you have make sure you were logged in with your credentials:
az login --tenant <tenant ID>
az account set --subscription <subscription ID>
Console:
Yes, you can access the storage account without private endpoints.
Portal:
containers.Client#ListBlobs: Failure responding to request:
StatusCode=403 -- Original Error: autorest/azure: Service returned an
error. Status=403 Code="AuthorizationFailure" Message="This request is
not authorized to perform this operation.\nRequestId:XXX"
The above error shows that doesn't has proper permission to authorize the azure blob storage.
Check the firewall settings whether, In networking
If you are access in public enable the select all network
If you enabled selected networks add the virtual networks. and add your add your client iP address and also enable "Allow trusted Microsoft services to access this storage account" allows you to access storage account.
Make sure that you have the necessary permission, such as the Contributor and User Access Administrator roles and the Storage Blob Data Owner role.
Reference:
Creating Azure Storage Containers in a storage account with network rules, with Terraform by Ansuman Bal

Terraform vm deployment using shared galery issue

I'm implementing a Terraform template, that deploys an Azure VM, based on a custom image that resides on another tenant. I've provided permissions to an AppRegistration, and validated that using Az CLI I can deploy a VMSS referring to that same shared image.
However, if I use Terraform to deploy the VM, I get this error:
Error: compute.VirtualMachinesClient#CreateOrUpdate: Failure sending request: StatusCode=403 -- Original Error: Code="LinkedAuthorizationFailed" Message="The client has permission to perform action 'Microsoft.Compute/galleries/images/versions/read' on scope '/subscriptions//resourceGroups/RG-Images/providers/Microsoft.Compute/virtualMachines/VM1', however the current tenant '' is not authorized to access linked subscription '***'."
Terraform is using the AppRegistration that was created. however, it fails with that error
I've followed this how-to, successfully, that usees Az cli.
https://learn.microsoft.com/en-us/azure/virtual-machine-scale-sets/share-images-across-tenants
I understand by the error message, that the user has the permissions, but the issue is between the 2 tenants, is that it? What else can I do to fix this?
Initially please check with the RBAC permissions on the two tenants like Virtual machine contributor or Network Contributor role .
This issue with cross tenant may be even fixed in terraform azurerm
provider version 1.34.0 or later
provider "azurerm" {
version = "~> 1.34.0"
}
And you can make use of auxiliary_tenant_ids = ["<tenant2 Id>"] to mention both the tenants while using shared image gallery .See shared image gallery /terraform/github.com by #rajaie-algorithmia
provider "azurerm" {
subscription_id = "${var.subscription_id}"
client_id = "${var.client_id}"
client_secret = "${var.client_secret}"
tenant_id = "${var.tenant_id}"
auxiliary_tenant_ids = ["${var.sig_tenant_id}"] #give the other tenant Id here
}
References:
share-images-across-tenants | microsoft docs
azure portal : how-to-share-gallery-vm-images-across-azure-tenants |Ajay varma| axiom

terraform plan not working with azurerm provider

I want to create a resource group in the azure cloud using terraform, for which I have to configure azurerm provider.
I created SPN using cli.
# az ad sp create-for-rbac --name spn_devops_terraform --role="Contributor" --scopes="/subscriptions/XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX"
The output includes credentials that you must protect. Be sure that you do not include these credentials in your code or check the credentials into your source control. For more information, see https://aka.ms/azadsp-cli
{
"appId": "YYYYYY-YYYY-YYYY-YYYY-YYYYYYYYY",
"displayName": "spn_devops_terraform",
"password": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
"tenant": "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX"
}
To test my SPN spn_devops_terraform, I logged in via cli
az login --service-principal -u YYYYYY-YYYY-YYYY-YYYY-YYYYYYYYY -p XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX --tenant XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX
then executed
az vm list --output table
And i can see the list of all the VMS.
Now here is my main.tf file
terraform {
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "3.0.2"
}
}
}
provider "azurerm" {
features {}
subscription_id = "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX" # copy pasted this from portal.
client_id = "YYYYYY-YYYY-YYYY-YYYY-YYYYYYYYY" # this is app_id
client_secret = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" # password
tenant_id = "XXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXX" # tenant
}
I initialized the terraform with "terraform init" command which goes fine.
But when i execute terraform plan it just hung for 10 mins and i have to press CTRL + C to stop it.
Please wait for Terraform to exit or data loss may occur.
Gracefully shutting down...
Stopping operation...
╷
│ Error: Unable to list provider registration status, it is possible that this is due to invalid credentials or the service principal does not have permission to use the Resource Manager API, Azure error: resources.ProvidersClient#List: Failure sending request: StatusCode=0 -- Original Error: context canceled
│
│ with provider["registry.terraform.io/hashicorp/azurerm"],
│ on main.tf line 10, in provider "azurerm":
│ 10: provider "azurerm" {
│
╵
What i am going wrong? what is fix and if there is any command in CLI or GUI in portal where i can see what is happening?
Tested in my enviromemt getting the same kind of error.It looks like the Service Principal doesn't have the Contributor role assigned to it/Doesn't have access to the subscription.
You can define the scope of service principle while creating it.
$ az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/SUBSCRIPTION_ID"
OR
Just go to the Subscription in the portal, select Access Control (IAM) and Add the Role assignment, Contributor to your Service Principal
You can refer this Terraform Document to Authenticating using a Service Principal with a Client Secret
Reference : Terraform unable to list provider registration status

Having the Terraform azure state file under different subscription

I have two subscriptions in Azure. Let's call them sub-dev and sub-prod. Under sub-dev I have resources for development (in a resource group rg-dev) and under sub-prod resources for production (in a resource group rg-prod).
Now, I would like to have only one state-file for both dev and prod. I can do this as I am using Terraform workspaces (dev and prod). There is a Storage Account under sub-dev (rg-dev) named tfsate. It has a container etc. The Azure backend is configured like this:
terraform {
backend "azurerm" {
resource_group_name = "rg-dev"
storage_account_name = "tfstate"
container_name = "tfcontainer"
key = "terraform.tfstate"
}
}
If I want to apply to the dev environment I have to switch Az Cli to the sub-dev. Similarly, for production, I would have to use sub-prod. I switch the default subscription with az cli:
az account set -s sub-prod
Problem is that the state's storage account is under sub-dev and not sub-prod. I will get access errors when trying to terraform init (or apply) when the default subscription is set to sub-prod.
Error: Failed to get existing workspaces: Error retrieving keys for Storage Account "tfstate": storage.AccountsClient#ListKeys: Failure responding to request: StatusCode=403 -- Original Error: autorest/azure: Service returned an error. Status=403 Code="AuthorizationFailed" Message="The client 'user#example.com' with object id '<redacted>' does not have authorization to perform action 'Microsoft.Storage/storageAccounts/listKeys/action' over scope '/subscriptions/sub-prod/resourceGroups/rg-dev/providers/Microsoft.Storage/storageAccounts/tfstate' or the scope is invalid. If access was recently granted, please refresh your credentials."
I have tried couple of things:
I added subscription_id = "sub-dev"
I generated a SAS token for the tfstate storage account and added the sas_token config value (removed resource_group_name)
but in vain and getting the same error.
I tried to az logout but terraform requires me to login first. Do I have to tune the permissions in the Azure end somehow (this is hard as the Azure environment is configured by a 3rd party) or does Terraform support this kind of having your state file under different subscription setup at all?
For better or worse (I haven't experimented much with other methods of organising terraform) we use terraform in the exact way you are describing. A state file, in a remote backend, in a different subscription to my resources. Workspaces are created to handle environments for the deployment.
Our state files are specified like this:
terraform {
required_version = ">= 0.12.6"
backend "azurerm" {
subscription_id = "<subscription GUID storage account is in>"
resource_group_name = "terraform-rg"
storage_account_name = "myterraform"
container_name = "tfstate"
key = "root.terraform.tfstate"
}
}
We keep our terraform storage account in a completely different subscription to our deployments but this isn't necessary.
When configuring your state file like so, it authenticates to the remote backend via az CLI, using the context of the person interacting with the CLI. This person needs to have the "Reader & Data Access" role to the storage account in order to dynamically retrieve the storage account keys at runtime.
With the above state file configured, executing Terraform would be
az login
az account set -s "<name of subscription where you want to create resources>"
terraform init
terraform plan
terraform apply
There's another way to do that. You can use the Access Key associated with the Storage Account on the other subscription(the one you want to have the state files on) and export it as an environment variable.
Bash:
export ARM_ACCESS_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
Powershell:
$env:ARM_ACCESS_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query '[0].value' -o tsv)
Then switch to the subscription you want to deploy to and deploy.

Resources