User Assigned Identity & Storage Account in Azure with Terraform
I had come across a situation where I got a mysql running in a Azure Vm & I have to upload database backup files to storage. So, for that purpose I have done this.
The goal is to create storage account container and access from VM using User Assigned Identity.
If User Assigned Identity is attached to VM, accessing storage account won't be much hard.
Most of the terraform code related to infra already shown in previous blog.
Let's start.
Storage Account
resource "azurerm_storage_account" "sa" {
name = "anilsdemo1"
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
account_tier = "Standard"
access_tier = "Hot"
account_replication_type = "ZRS"
network_rules {
default_action = "Deny"
ip_rules = ["GIVE_YOUR_IP"]
virtual_network_subnet_ids = [azurerm_subnet.subnet.id]
}
tags = {
environment = "Test"
}
}
replace "GIVE_YOUR_IP" with your public IP When I was creating container with terraform, it gave errors like
│ Error: containers.Client#GetProperties: 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:b1cbacae-901e-00f1-5233-d0f95c000000\nTime:2022-09-24T16:33:36.0925892Z"
So, I have tried giving my IP.
Create container in storage account
resource "azurerm_storage_container" "sa_container1" {
name = "democontainer"
storage_account_name = azurerm_storage_account.sa.name
container_access_type = "private"
}
Create User Assigned Identity
resource "azurerm_user_assigned_identity" "id1" {
resource_group_name = azurerm_resource_group.rg.name
location = azurerm_resource_group.rg.location
name = "anilsuser1"
}
Assign a role for user id with storage account
resource "azurerm_role_assignment" "role1" {
scope = azurerm_storage_account.sa.id
principal_id = azurerm_user_assigned_identity.id1.principal_id
role_definition_name = "Contributor"
}
You can give other roles in role_definition_name, check documentation for suitable one based on your use case.
Run terraform commands
$ terraform init
$ terraform plan
-> Plan: 9 to add, 0 to change, 0 to destroy.
$ terraform apply
-> Apply complete! Resources: 9 added, 0 changed, 0 destroyed.
Check Az login
Now, connect to VM using public key generated and VM Public
ssh -i ./tls/private.pem anil@VM_IP
Install Azure CLI with below command
$ curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
Copy values of user-id, storage_account_name, container_name from the terraform Outputs. They are required to login using az cli.
$ az login --identity -u /subscriptions/<subscription_id>/resourceGroups/tf-anils-demo/providers/Microsoft.ManagedIdentity/userAssignedIdentities/anilsuser1
$ az storage blob list --account-name anilsdemo1 -c democontainer --output table
$ echo $HOSTNAME > test.txt
$ az storage blob upload \
--account-name anilsdemo1 \
--container-name democontainer \
--file test.txt
$ az storage blob list --account-name anilsdemo1 -c democontainer --output table
-> Name Blob Type Blob Tier Length Content Type Last Modified Snapshot
-------- ----------- ----------- -------- -------------- ------------------------- ----------
test.txt BlockBlob Hot 13 text/plain 2022-09-24T17:02:18+00:00
$ rm -rf test.txt
$ az storage blob download \
--account-name anilsdemo1 \
--container-name democontainer \
--name test.txt \
--file ./dowmload.txt
$ ls
dowmload.txt
Destroy resources
$ terraform destroy --auto-approve
-> Destroy complete! Resources: 16 destroyed.
Terraform Code available at Github
Check my articles at this blog.