Small knowledge, big challenge! This article is participating in the creation activity of “Essential Tips for Programmers”. This article also participated in the “Digitalstar Project” to win a creative gift package and creative incentive money.
In the previous three practical deployment exercises, we learned about application deployment, resource group, and virtual network creation deployment. In this article we deploy a relatively complex infrastructure, cloud computing instance, in combination with the modules that are important to Terraform.
First, build reuse module
Terraform module is an important means to write high-quality Terraform code and improve the reuse of code. It can be said that a mature production environment should be assembled by several credible mature modules.
The basic documents of Terraform module shall be provided as follows:
- Main.tf, for resource definition, interdependence
- Variable. tf, used to declare variables, so that the calling module side can use its own values
- Elsiders.tf, to carry on the content that the caller cares about after the resource is created, such as the resource Id, etc
So we first create a folder, azure_machine_module, to hold our module, with the directory structure shown below.
README.mdDocumentation is used to describe the module for your convenience.
1.1 the resource group
Resource groups are containers for holding Azure solution-related resources. A resource group can contain all the resources of a solution, or it can contain only the resources you want to manage as a group.
#main.tf
# resource group
resource "azurerm_resource_group" "myterraformgroup" {
name = "myResourceGroup"
location = var.location
tags = {
environment = "Terraform Demo"}}Copy the code
1.2 Network
It is well known that for Azure home products, when creating compute instances (virtual machines), you need to create a virtual network for them or use the current virtual network. As a best practice, each group of virtual machines will be assigned to a separate subnet of the virtual network, as shown in the figure below.
So what we have to say aboutNetwork communicationIn this part, we need to provide network interface, virtual network interface, subnet.
#main.tf
# random string
resource "random_string" "nic_prefix" {
length = 4
special = false
}
# Virtual network interface
resource "azurerm_virtual_network" "myterraformnetwork" {
name = "myVnet"
address_space = ["10.0.0.0/16"]
location = var.location
resource_group_name = azurerm_resource_group.myterraformgroup.name
tags = {
environment = "Terraform Demo"}}# subnet
resource "azurerm_subnet" "myterraformsubnet" {
name = "mySubnet"
resource_group_name = azurerm_resource_group.myterraformgroup.name
virtual_network_name = azurerm_virtual_network.myterraformnetwork.name
address_prefixes = ["10.0.1.0/24"]}# Network interface
resource "azurerm_network_interface" "vm_nic" {
name = "${var.vm_name}-nic1"
location = var.location
resource_group_name = azurerm_resource_group.myterraformgroup.name
ip_configuration {
name = "${var.vm_name}_nic_${random_string.nic_prefix.result}"
subnet_id = azurerm_subnet.myterraformsubnet.id
private_ip_address_allocation = "Static"
private_ip_address = var.static_ip_address
}
tags = var.tags
}
Copy the code
Due to the time, part of the dynamic variables are not taken out, and the optimization will be carried out when there is time.
1.3 the virtual machine
To deploy virtual machines, we need to use resource groups, networks, and instance security groups to ensure access security.
#main.tf
# security group
resource "azurerm_network_interface_security_group_association" "vm_nic_sg" {
network_interface_id = azurerm_network_interface.vm_nic.id
network_security_group_id = var.network_security_group_id
count = var.network_security_group_id = = "" ? Zero: 1
}
# example
resource "azurerm_virtual_machine" "windows_vm" {
name = var.vm_name
vm_size = var.vm_size
location = var.location
resource_group_name = azurerm_resource_group.myterraformgroup.name
tags = merge(var.tags, { activityName = "${var.activity_tag} " })
network_interface_ids = [
"${azurerm_network_interface.vm_nic.id}",]storage_image_reference {
publisher = var.publisher
offer = var.offer
sku = var.sku
version = "latest"
}
identity {
type = "SystemAssigned"
}
storage_os_disk {
name = "${var.vm_name}-os-disk"
caching = "ReadWrite"
create_option = "FromImage"
managed_disk_type = "Standard_LRS"
}
os_profile {
admin_password = var.admin_password
admin_username = "azureuser"
computer_name = var.vm_name
}
os_profile_windows_config {
provision_vm_agent = true
}
delete_os_disk_on_termination = var.vm_os_disk_delete_flag
delete_data_disks_on_termination = var.vm_data_disk_delete_flag
}
Copy the code
1.4 other
You also need to define input and output variables.
The # exmission.tf file outputs anything we want to pass back to the root user for reuse
output "vm_id" {
value = "${azurerm_virtual_machine.windows_vm.id}"
}
output "vm_name" {
value = "${azurerm_virtual_machine.windows_vm.name}"
}
output "vm_location" {
value = "${azurerm_virtual_machine.windows_vm.location}"
}
output "vm_resource_group_name" {
value = "${azurerm_virtual_machine.windows_vm.resource_group_name}"
}
Copy the code
The # variables.tf file defines all variables that the module expects to define from the root module call
# variable "resource_group_name" {
#}
variable "location"{}variable "sloc"{}variable "vm_size" {
default = "Standard_B1s"
}
# variable "vm_subnet_id" {
#}
variable "vm_name"{}variable "vm_os_disk_delete_flag" {
default = true
}
variable "vm_data_disk_delete_flag" {
default = true
}
variable "network_security_group_id" {
default = ""
}
variable "static_ip_address"{}variable "publisher"{}variable "offer"{}variable "sku"{}variable "tags" {
type = map
description = "All mandatory tags to use on all assets"
default = {
activityName = "AzureVMWindowsDemo"
automation = "Terraform"
costCenter1 = "A00000"
dataClassification = "Demo"
managedBy = "[email protected]"
solutionOwner = "[email protected]"}}variable "activity_tag"{}variable "admin_password"{}Copy the code
That’s it, module definition is complete!
Second, use modules to build business
The entire project structure directory is shown in the figure below.
Main.tf file, using submodules, providing detailed parameters, authentication information
module windows_desktop_vm_using_local_module {
source = "./azure_machine_module"
# resource_group_name = azurerm_resource_group.myterraformgroup.name
location = "eastus"
sloc = "uks"
# vm_subnet_id = module.azurerm_network_interface.vnet_subnets[0]
vm_name = "testCompute"
vm_size = var.desktop_vm_size
publisher = var.desktop_vm_image_publisher
offer = var.desktop_vm_image_offer
sku = var.desktop_vm_image_sku
static_ip_address = "10.0.1.15"
activity_tag = "Windows Desktop"
admin_password = ! "" @#qwe123"
}
provider "azurerm" {
features {}
subscription_id = "<yours>"
tenant_id = "<yours>"
client_id = "<yours>"
client_secret = "<yours>"
}
Copy the code
Variable. tf, define variables
# read in from the terraform.auto.tfvars file
variable "global_settings"{}variable "desktop_vm_image_publisher"{}variable "desktop_vm_image_offer"{}variable "desktop_vm_image_sku"{}variable "desktop_vm_image_version"{}variable "desktop_vm_size"{}Copy the code
Terraform.auto. Tfvars, the actual parameter
global_settings = {
#Set of tags
tags = {
applicationName = "Windows VM Demo"
businessUnit = "Technical Solutions"
costCenter = "MPN Sponsorship"
DR = "NON-DR-ENABLED"
deploymentType = "Terraform"
environment = "Dev"
owner = "Jack Roper"
version = "0.1"}}# Desktop VM variables
desktop_vm_image_publisher = "MicrosoftWindowsDesktop"
desktop_vm_image_offer = "Windows-10"
desktop_vm_image_sku = "20h1-pro"
desktop_vm_image_version = "latest"
desktop_vm_size = "Standard_B1s"
Copy the code
3. Perform deployment
Terraform init Initializes the environment
terraform planPreviewing deployment Plans
terraform applyPerform the deployment
It took about six minutes to create the execution deployment process, which was a long wait.
Check the Azure Portal Control panel to ensure that the resource was successfully created.