Mission LZ also deploys the Hub and Spoke network architecture using Terraform.
To get started with Terraform on Azure check out their useful tutorial: https://learn.hashicorp.com/collections/terraform/azure-get-started/
Once you're comfortable with Terraform, ensure you have the Prerequisites below and follow the instructions to deploy and clean-up Mission LZ.
From a birds-eye view, we're going to deploy the core Mission LZ deployment of the Hub, Tier 0 (Identity), Tier 1 (Operations), and Tier 2 (Shared Services) networks and supporting resources, followed by a new spoke network/Tier 3. The commands we'll execute along the way will look something like this:
cd src/terraform/mlz
terraform init
terraform apply # supply some parameters, approve, copy the output values
cd src/terraform/tier3
terraform init
terraform apply # supply some parameters, approve
Read on to understand the prerequisites, how to get started, and how to optionally configure your deployment for use in other clouds or deploy with a Service Principal.
- Current version of the Azure CLI
- The version of the Terraform CLI described in the .devcontainer Dockerfile
- An Azure Subscription(s) where you or an identity you manage has
Owner
RBAC permissions
Deploying to a Cloud other than Azure Commercial? This requires updating the azurerm
provider block environment
and metadata_host
values. Checkout the Deploying to Other Clouds documentation.
-
Log in using the Azure CLI
az login
(Optional) If you needed to deploy into another cloud such as Azure Government, set the cloud name before logging in:
az cloud set -n AzureUSGovernment az login
-
(OPTIONAL) Deploying with a Service Principal? This requires updating the
azurerm
provider block. Check out the Deploying with a Service Principal documentation.
Before provisioning any Azure resources with Terraform you must initialize a working directory.
Here's the docs on terraform init
: https://www.terraform.io/docs/cli/commands/init.html/
-
Navigate to the directory in the repository that contains the MissionLZ Terraform module:
cd src/terraform/mlz
-
Execute
terraform init
terraform init
After intializing the directory, use terraform apply
to provision the resources described in mlz/main.tf
and its referenced modules at mlz/modules/*
.
Looking to deploy this new spoke in a cloud other than
AzureCloud
, sayAzureUsGovernment
? Follow the guidance at Deploying to Other Clouds to set the correct variables for the deployment.
Here's the docs on terraform apply
: https://www.terraform.io/docs/cli/commands/apply.html
When you run terraform apply
, by default, Terraform will inspect the state of your environment to determine what resource creation, modification, or deletion needs to occur as if you invoked a terraform plan
and then prompt you for your approval before taking action.
Here's the docs on terraform plan
: https://www.terraform.io/docs/cli/commands/plan.html
-
From the directory in which you executed
terraform init
executeterraform apply
:terraform apply
-
You'll be prompted for a subscription ID. Supply the subscription ID you want to use for the Hub network:
> terraform apply var.hub_subid Subscription ID for the deployment Enter a value:
-
Terraform will then inspect the state of your Azure environment and compare it with what is described in the Mission LZ Terraform module. Eventually, you'll be prompted for your approval to create, modify, or destroy resources. Supply
yes
:Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes
-
The deployment will begin. These commands will deploy all of the resources that make up Mission LZ. Deployment could take up to 45 minutes.
If you'd like to deploy from Terraform over-and-over again with the same resource names and environment values, follow the docs on using Terraform Destroy to clean-up your environment.
When it's complete, you'll see some output values that will be necessary if you want to stand up new spoke, or Tier 3, networks:
Apply complete! Resources: 99 added, 0 changed, 0 destroyed.
Outputs:
firewall_private_ip = "10.0.100.4"
hub_rgname = "hub-rg"
hub_subid = "{the Hub subscription ID}"
hub_vnetname = "hub-vnet"
laws_name = "{the name of the Log Analytics Workspace}"
laws_rgname = "operations-rg"
tier1_subid = "{the Tier 1 subscription ID}"
Interested in standing up new spoke networks, or Tier 3 environments, after a deployment? See Deploying New Spoke Networks
Once you're happy with the deployment output and want to modify Mission LZ or just want to tear it down to save on costs, you can use terraform destroy
.
Here's the docs on terraform destroy
: https://www.terraform.io/docs/cli/commands/destroy.html
-
From the directory in which you executed
terraform init
andterraform apply
executeterraform destroy
:terraform destroy
-
You'll be prompted for a subscription ID. Supply the subscription ID you want to used previously:
> terraform destroy var.hub_subid Subscription ID for the deployment Enter a value:
-
Terraform will then inspect the state of your Azure environment and compare it with what is described in Terraform state. Eventually, you'll be prompted for your approval to destroy resources. Supply
yes
:Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes
This command will attempt to remove all the resources that were created by terraform apply
and could take up to 45 minutes.
Once you've deployed Mission LZ, you can use the Tier 3 module to deploy and peer new Spoke Networks and workloads to the Hub and Firewall.
Looking to deploy this new spoke in a cloud other than
AzureCloud
, sayAzureUsGovernment
? Follow the guidance at Deploying to Other Clouds to set the correct variables for the deployment.
-
Navigate to the directory in the repository that contains the MissionLZ Tier 3 Terraform module:
cd src/terraform/tier3
-
Execute
terraform init
terraform init
-
Execute
terraform apply
:terraform apply
-
You'll be prompted for environment values for resources deployed by the core Mission LZ deployment for: 1) the Hub Firewall, 2) the Log Analytics Workspace resources and 3) the desired subscription ID for the new spoke network/Tier 3:
> terraform apply var.firewall_private_ip Firewall IP to bind network to Enter a value: 10.0.100.4 var.hub_rgname Resource Group for the Hub deployment Enter a value: hub-rg var.hub_subid Subscription ID for the Hub deployment Enter a value: {the Hub subscription ID} var.hub_vnetname Virtual Network Name for the Hub deployment Enter a value: hub-vnet var.laws_name Log Analytics Workspace Name for the deployment Enter a value: {the name of the Log Analytics Workspace} var.laws_rgname The resource group that Log Analytics Workspace was deployed to Enter a value: operations-rg var.tier1_subid Subscription ID for the Tier 1 deployment Enter a value: {the Tier 1 subscription ID} var.tier3_subid Subscription ID for this Tier 3 deployment Enter a value: {the Tier 3 subscription ID}
You get these values when
terraform apply
is complete for the core Mission LZ deployment. See the Apply Complete section for what these values look like. You can also source the values after a successful core Mission LZ deployment by inspecting theoutputs
object in the Terraform state file. By default that state file is atsrc/terraform/mlz/terraform.tfstate
. -
Terraform will then inspect the state of your Azure environment and compare it with what is described in the Tier 3 Terraform module. Eventually, you'll be prompted for your approval to create, modify, or destroy resources. Supply
yes
:Do you want to perform these actions? Terraform will perform the actions described above. Only 'yes' will be accepted to approve. Enter a value: yes
When this Tier 3 network has served its purpose, you can follow the same steps in Terraform destroy to remove the provisioned resources.
This is not required, in fact, the current Terraform modules are written as if you're executing them as a user.
But, if you're using a Service Principal to deploy Azure resources with Terraform check out this doc: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret/
Using a Service Principal will require updating the resource providers for mlz/main.tf
, also described in that doc: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/guides/service_principal_client_secret#configuring-the-service-principal-in-terraform/:
variable "client_secret" {
}
terraform {
required_providers {
azurerm = {
...
}
}
}
provider "azurerm" {
features {}
subscription_id = "00000000-0000-0000-0000-000000000000"
client_id = "00000000-0000-0000-0000-000000000000"
client_secret = var.client_secret
tenant_id = "00000000-0000-0000-0000-000000000000"
}
The development container definition downloads the required Terraform plugin providers during the container build so that the container can be transported to an air-gapped network for use. The container also sets the TF_PLUGIN_CACHE_DIR
environment variable, which Terraform uses as the search location for locally installed providers. If you are not using the container to deploy or if the TF_PLUGIN_CACHE_DIR
environment variable is not set, Terraform will automatically attempt to download the provider from the internet when you execute the terraform init
command.
See the development container README for more details on building and running the container.
The default templates write a state file directly to disk locally to where you are executing terraform from. If you wish to change the output directory you can set the path directly in the terraform backend block located in the main.tf file via the path variable in the backend configuration block.
terraform {
backend "local" {
path = "relative/path/to/terraform.tfstate"
}
required_version = ">= 1.0.3"
required_providers {
azurerm = {
source = "hashicorp/azurerm"
version = "= 2.71.0"
}
random = {
source = "hashicorp/random"
version = "= 3.1.0"
}
time = {
source = "hashicorp/time"
version = "0.7.2"
}
}
}
To find more information about setting the backend see Local Backend, if you wish to AzureRM backend please see AzureRM Backend
The azurerm
Terraform provider provides a mechanism for changing the Azure cloud in which to deploy Terraform modules.
If you want to deploy to another cloud, pass in the correct value for environment
, metadata_host
, and location
for the cloud you're targeting to the relevant module's variables file mlz/variables.tf or tier3/variables.tf:
variable "environment" {
description = "The Terraform backend environment e.g. public or usgovernment"
type = string
default = "usgovernment"
}
variable "metadata_host" {
description = "The metadata host for the Azure Cloud e.g. management.azure.com"
type = string
default = "management.usgovcloudapi.net"
}
variable "location" {
description = "The Azure region for most Mission LZ resources"
type = string
default = "usgovvirginia"
}
provider "azurerm" {
features {}
environment = var.environment # e.g. 'public' or 'usgovernment'
metadata_host = var.metadata_host # e.g. 'management.azure.com' or 'management.usgovcloudapi.net'
}
For the supported environment
values, see this doc: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#environment/
For the supported metadata_host
values, see this doc: https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs#metadata_host/
For more endpoint mappings between AzureCloud and AzureUsGovernment: https://docs.microsoft.com/en-us/azure/azure-government/compare-azure-government-global-azure#guidance-for-developers/