See how HashiCorp Terraform and Packer can leverage of Microsoft Azure’s Managed Identities.
This post is part one of a three-part blog series on Azure managed identities with the HashiCorp stack. In parts two and three, we learn how HashiCorp Vault, Nomad, and Consul can take advantage of managed identities
Managing credentials for infrastructure to authenticate against the cloud has been a problem many cloud engineers have faced over the years. With the introduction of concepts such as infrastructure as code and configuration as code, the problem has spread to code management of infrastructure and its configuration.
There are also applications that run on this infrastructure that need to authenticate against the cloud. Engineers have attempted to solve this issue in many different ways over the years; however, these attempts have often not been without compromise. Cloud providers have been working to solve this issue and Microsoft has played their part by releasing Managed Identities.
Managed Identities (formerly known as Managed Service Identities) is an identity and access management feature of Microsoft’s Azure cloud offering that assigns identities to machines. This comes in two flavors: System-assigned identities, and user-assigned identities.
System-assigned identities are created with the Azure resource and are tied to the lifecycle of that resource. The nice thing about this type is that, when the resource is deleted, the identity is also deleted. This has a one-to-one relationship with the Azure resource, which greatly reduces the risk of identity sprawl.
User-assigned identities are created independent of Azure resources and are scoped to the subscription. In fact, this in itself is an Azure resource. The benefit of this approach is that it allows a one-to-one or one-to-many relationship. This means that you can assign an identity to a group of VMs, for example, all VMs provisioned for the purpose of hosting HashiCorp Vault can have a single identity assigned to them. This eases the burden of access management. The tradeoff with this approach is that you will need to manage the lifecycle of the identities yourself in order to not have identity sprawl.
While we need not worry about the inner workings under the hood, it’s handy to point out a few key details:
The HashiCorp stack works in harmony with Azure and many of our products allow practitioners to make use of Managed Identities. HashiCorp Packer and Terraform fully support Managed Identities as an authentication method (as well as a resource in the case of Terraform).
A common use case for Managed Identities with Terraform is authentication of a worker node responsible for Terraform runs to provision other Azure resources as part of an orchestration piece. This could be a Jenkins worker node for example.
In order for that node to have the ability to provision to Azure resources, it first needs to authenticate against Azure. To achieve this, people historically set some environment variables to tell Terraform what subscription ID, Tenant ID, and Client Secret to use to authenticate with. It’s important to highlight that these environment variables are sensitive data or “secrets” and should be handled accordingly.
In order to reliably ensure these variables are always set correctly, we have the challenge of secure secret introduction. This is the problem of how we can inject secret zero into the machine build. As we typically deploy infrastructure with code, we would need to find a way of putting this information in the code without exposing it. This is a barrier to storing your code in a version control system (VCS).
These authentication details can also be set inside the provider declaration block; however, we have the same challenges as the environment variables as we still are unable to store our code in a VCS while the secrets are present in the code.
Managed Identities solve these problems as we now do not need to configure these authentication details. Instead, these details are securely baked into the VM as metadata which is only readable by Azure. Now we can express ourselves in Terraform and trust that our VM will have the ability to provision our Azure resources without the burden of managing the introduction of secret zero.
The below video is a demonstration of how we can provision Managed Identities using this Terraform resource.
The use case for Packer is almost identical to Terraform. The workflow for a Packer image build follows these steps:
Packer deploys a VM and any other required resources in your cloud environment as per the configuration in your Packer template.
Packer will run your provisioner against the VM provisioned in step 1. This could be a shell script, Ansible playbook, a PowerShell script, or any other type of configuration management. Currently, Packer supports 18 different provisioners. In addition to this, there are community-supported provisioners as Packer allows you to build your own.
Packer will then run any post processors that are specified in the build manifest.
The above steps prepare the VM to be in the state that you would like to image. Packer then takes this VM and creates a VM image.
With the image built, Packer will store it according to your storage definition in your manifest. This could be Azure Shared Image Gallery for example.
For the final step, Packer cleans up all of the resources it created in step
As you can see from the steps above, Packer will need to authenticate with Azure in order to deploy the target machine, access it, and store the image. Even though you can specify service principal details in your manifest, we have the same challenges as discussed with Terraform. When your Packer VM is deployed in Azure, it can use Managed Identity to authenticate with Azure. This will allow Packer to perform the steps above. This is the default authentication method when no credentials are supplied and a managed Identity is present on the Virtual Machine.
In this blog post, we have introduced the concept of Managed Identities, looked at how they work and why we would use them. We have also demonstrated how we can use Terraform to provision a Managed Identity resource as well as authenticate with Azure using them. We have also looked at how Packer can take advantage of Managed Identity.
In part two, we will look at how HashiCorp Vault can take advantage of Managed Identities to ease Vault operations.
Learn how even non-technical operators can use HashiCorp Terraform Cloud to deploy Azure resources based on Microsoft's Cloud Adoption Framework (CAF) templates.
Terraform Sentinel policies are now available in the Terraform Registry so you can publish policies you want to share and search the Registry for policies you need.
Cloud Development Kit for Terraform (CDKTF) has reached its first GA release, adding full support for Go and providing a GitHub action to use with Terraform Cloud.