Azure Website Setup with Terraform
Table of Contents
Setting up our Environment
Initial Setup
Create main.tf
and add Azure Provider
# "../resource/terraform/main.tf" provider "azurerm" { features {} }
Create variables.tf
file
We are going to be using variables, so lets get that setup.
# "../resource/terraform/variables.tf" variable "prefix" { description = "The prefix which should be used for all resources in this example" default = "terraform-test" } variable "location" { description = "The Azure Region in which all resources in this example should be created." default = "eastus2" }
Add Resource Group
Then we create a resource group for our project.
# "../resource/terraform/main.tf" resource "azurerm_resource_group" "rg" { name = "${var.prefix}-rg" location = var.location }
Add variable for the VNET address space
We are going to want to separate our project from the rest of our projects in it's own virtual network. We will want to add a variable because we will want to make sure our address space doesn't conflict with any of our other projects.
# "../resource/terraform/variables.tf" variable "vnet__address_space" { description = "The address space to use for the virtual network." default = ["0.0.16.0/20"] }
Add VNET
Now we can add our virtual network.
# "../resource/terraform/main.tf" resource "azurerm_virtual_network" "vnet" { name = "${var.prefix}-vnet" location = var.location resource_group_name = azurerm_resource_group.rg.name address_space = var.vnet__address_space }
Add Key Vault and Secret for User Password
Get Current Client config for our Tenant Id
# "../resource/terraform/main.tf" data "azurerm_client_config" "current" { }
Create Key Vault
# "../resource/terraform/main.tf" resource "azurerm_key_vault" "kv" { name = "${var.prefix}-key-vault" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location tenant_id = data.azurerm_client_config.current.tenant_id sku_name = "standard" access_policy { tenant_id = data.azurerm_client_config.current.tenant_id object_id = data.azurerm_client_config.current.object_id key_permissions = ["create", "get"] secret_permissions = ["set", "get", "delete", "list"] } }
Add The Random Provider So We can generate a password
# "../resource/terraform/main.tf" provider "random" { version = "2.2.1" }
Generate the Random Password
# "../resource/terraform/main.tf" resource "random_password" "webvm_password" { length = 16 special = true override_special = "_%@`" }
Add the password as a Secret
# "../resource/terraform/main.tf" resource "azurerm_key_vault_secret" "webvm" { name = "${var.prefix}-webvm-password" value = random_password.webvm_password.result key_vault_id = azurerm_key_vault.kv.id }
Add a Virtual Machine for our Web Server
Add a subnet for our web servers
Add a new variable for our web server subnet.
# "../resource/terraform/variables.tf" variable "subnet__web__address_space" { description = "The address space to use for our web servers subnet." default = "0.0.16.0/24" }
Add our subnet to our virtual network.
# "../resource/terraform/main.tf" resource "azurerm_subnet" "web" { name = "web" resource_group_name = azurerm_resource_group.rg.name virtual_network_name = azurerm_virtual_network.vnet.name address_prefix = var.subnet__web__address_space }
Add a Public IP to access our Web Server
# "../resource/terraform/main.tf" resource "azurerm_public_ip" "web" { name = "${var.prefix}-web-pip" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location allocation_method = "Dynamic" }
Add a Network Interface With Private Dynamic IP and our Public IP for our Web Server
# "../resource/terraform/main.tf" resource "azurerm_network_interface" "web" { name = "${var.prefix}-web-nic" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location ip_configuration { name = "web" subnet_id = azurerm_subnet.web.id private_ip_address_allocation = "Dynamic" public_ip_address_id = azurerm_public_ip.web.id } }
Add a Network Security Group (NSG) for our Web Server Subnet
We are also adding a security rule to allow https access.
# "../resource/terraform/main.tf" resource "azurerm_network_security_group" "web" { name = "${var.prefix}-web-nsg" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location security_rule { access = "Allow" direction = "Inbound" name = "tls" priority = 100 protocol = "Tcp" source_port_range = "*" source_address_prefix = "*" destination_port_range = "443" destination_address_prefix = azurerm_network_interface.web.private_ip_address } }
Associate NSG with Subnet via our Network Interface
# "../resource/terraform/main.tf" resource "azurerm_subnet_network_security_group_association" "web" { subnet_id = azurerm_subnet.web.id network_security_group_id = azurerm_network_security_group.web.id }
Add the Virtual Machine
Currently getting errors when adding the VM… not sure why yet…
# "../resource/terraform/main.tf" resource "azurerm_linux_virtual_machine" "web" { name = "${var.prefix}-vm" resource_group_name = azurerm_resource_group.rg.name location = azurerm_resource_group.rg.location size = "Standard_B1ms" admin_username = "adminuser" admin_password = random_password.webvm_password.result disable_password_authentication = false network_interface_ids = [ azurerm_network_interface.web.id ] source_image_reference { publisher = "Canonical" offer = "UbuntuServer" sku = "18.04-LTS" version = "latest" } os_disk { storage_account_type = "StandardSSD_LRS" caching = "ReadWrite" } }
Terraform CLI Cheat Sheet
Init project first
terraform init
see the plan
terraform plan
apply the plan
terraform apply
show state
terraform show
save plan to file
terraform plan -out=newplan
terraform apply "newplan"
destroy resources
terraform destroy