【Terraform】基于模块部署Azure计算实例

1,152 阅读3分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
本文同时参与 「掘力星计划」 ,赢取创作大礼包,挑战创作激励金。

在前面三篇实践部署操作中,我们熟悉了应用部署,资源组和虚拟网络创建部署。这一篇文章我们结合对Terraform相当重要的模块,部署一个相对而言比较复杂的基础设施,云计算实例。

一、构建复用模块

Terraform模块是编写高质量Terraform代码,提升代码复用性的重要手段,可以说,一个成熟的生产环境应该是由数个可信成熟的模块组装而成的。

Terraform模块最基础文件需提供:

  • main.tf,用于资源定义,相互依赖
  • variables.tf,用于申明变量,方便调用模块方使用自己的值
  • outputs.tf,用于承接资源创建后,调用方关心的创建完成的内容,比如资源Id等

所以我们首先创建一个文件夹azure_machine_module,用于存放我们的模块,其目录结构如下图所示。

图片.png README.md文档用于描述该模块,方便使用者。

1.1资源组

资源组是用于保存 Azure 解决方案相关资源的容器。 资源组可以包含解决方案的所有资源,也可以只包含想要作为组来管理的资源。

#main.tf
#资源组
resource "azurerm_resource_group" "myterraformgroup" {
    name     = "myResourceGroup"
    location = var.location
    tags = {
        environment = "Terraform Demo"
    }
}

1.2网络部分

众所周知,对于Azure家的产品,创建计算实例(虚拟机)时,需要为其创建虚拟网络或者使用当前的虚拟网络。最佳实践上,每一组虚拟机都将会分配到虚拟网络的单独子网中,如下图所示。

图片.png 所以我们对于网络通信这一部分,我们要提供网络接口、虚拟网络接口、子网。

#main.tf
#随机字符串
resource "random_string" "nic_prefix" {
  length  = 4
  special = false
}

#虚拟网络接口
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"
    }
}

# 子网
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"]
}

#网络接口
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
}

由于时间关系,部分动态变量并没有抽出来,有时间再进行优化。

1.3虚拟机

为了部署虚拟机,我们需要用到资源组,网络,另外为了保障出入安全,还需要设置实例安全组。

#main.tf
#安全组
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 == "" ? 0 : 1
}

#计算实例
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
}

1.4其它

还需要定义输入输出变量。

#outputs.tf文件输出任何我们想要传递回根用户以供重用的内容
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}"
}
# variables.tf文件定义了模块期望从根模块调用中定义的所有变量
# 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          = "bt@bt.com"
    solutionOwner      = "bt@bt.com"
  }
}

variable "activity_tag" {
}

variable "admin_password" {
}

到此为止,模块定义完成!

二、使用模块,构建业务

整个项目结构目录如下图所示。

图片.png main.tf文件,使用子模块,提供详细参数,认证信息

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>"
}

variables.tf,定义变量

# 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" {
}

terraform.auto.tfvars,实际参数

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"

三、执行部署

terraform init 初始化环境

图片.png terraform plan 预览部署计划

图片.png

图片.png terraform apply 执行部署

图片.png

图片.png 创建执行部署过程花费了六分钟左右的时间,等待时间确实有些久了。

图片.png 检查Azure门户控制面板,确定资源创建成功。

图片.png