使用Terraform在Azure上建立虚拟机(2个vm+α)

以前的文章在这里。

执行的内容

-建立虚拟机和相关资源。
-尝试使用变量。
-由于某些原因需要更改terraform版本(0.12.9),因此通过tfenv进行管理。
-将terraform.tfstate保存到Azure存储账户中进行更改。

tfenv是什么

这是一个用于管理Terraform版本的软件。
详细信息请参考下文。

使用tfenv进行管理(从卸载terraform到安装tfenv和安装terraform)。

% brew uninstall terraform
Uninstalling /usr/local/Cellar/terraform/0.12.18... (6 files, 50.9MB)

% brew install tfenv

==> Downloading https://github.com/tfutils/tfenv/archive/v1.0.2.tar.gz
==> Downloading from https://codeload.github.com/tfutils/tfenv/tar.gz/v1.0.2
#=#=#
?  /usr/local/Cellar/tfenv/1.0.2: 20 files, 29.2KB, built in 4 seconds

% tfenv install 0.12.9
[INFO] Installing Terraform v0.12.9
[INFO] Downloading release tarball from https://releases.hashicorp.com/terraform/0.12.9/terraform_0.12.9_darwin_amd64.zip
######################################################################################################################################################################################################################################################### 100.0%
[INFO] Downloading SHA hash file from https://releases.hashicorp.com/terraform/0.12.9/terraform_0.12.9_SHA256SUMS
tfenv: tfenv-install: [WARN] No keybase install found, skipping OpenPGP signature verification
Archive:  tfenv_download.aQegFa/terraform_0.12.9_darwin_amd64.zip
  inflating: /usr/local/Cellar/tfenv/1.0.2/versions/0.12.9/terraform
[INFO] Installation of terraform v0.12.9 successful
[INFO] Switching to v0.12.9
[INFO] Switching completed
masaakihamada@masaakinoMacBook-Pro tf-test %
masaakihamada@masaakinoMacBook-Pro tf-test %
masaakihamada@masaakinoMacBook-Pro tf-test %
masaakihamada@masaakinoMacBook-Pro tf-test % terraform --version
Terraform v0.12.9
+ provider.azurerm v1.39.0

tfstate是什么?

该文件描述了实际资源的状态。
默认情况下,它存储在本地,并且可以选择保存在远程。
基本上,我们认为应该在团队中协作,因此决定将其保存在远程(Azure Storage Account)。

这个状态默认存储在名为”terraform.tfstate”的本地文件中,但也可以远程存储,对于团队环境更有效。

Terraform使用本地状态来创建计划并对基础架构进行更改。在任何操作之前,Terraform都会进行刷新,以更新状态与真实的基础架构。

事前准备远程管理tfstate。

需要以下内容:
– 创建Azure存储帐户。
– 将访问密钥设置为环境变量。

创建Azure存储帐户

#!/bin/bash

RESOURCE_GROUP_NAME=tstate
STORAGE_ACCOUNT_NAME=tstate$RANDOM
CONTAINER_NAME=tstate

# Create resource group
az group create --name $RESOURCE_GROUP_NAME --location japaneast

# Create storage account
az storage account create --resource-group $RESOURCE_GROUP_NAME --name $STORAGE_ACCOUNT_NAME --sku Standard_LRS --encryption-services blob

# Get storage account key
ACCOUNT_KEY=$(az storage account keys list --resource-group $RESOURCE_GROUP_NAME --account-name $STORAGE_ACCOUNT_NAME --query [0].value -o tsv)

# Create blob container
az storage container create --name $CONTAINER_NAME --account-name $STORAGE_ACCOUNT_NAME --account-key $ACCOUNT_KEY

echo "storage_account_name: $STORAGE_ACCOUNT_NAME"
echo "container_name: $CONTAINER_NAME"
echo "access_key: $ACCOUNT_KEY"

执行结果

~~~~省略~~~~~~
storage_account_name: tstate12763
container_name: tstate
access_key: **********************************

将访问密钥设置为环境变量。

% export ARM_ACCESS_KEY="**********************************"
% env | grep ARM_ACCESS_KEY
ARM_ACCESS_KEY=**********************************

如果需要每次加载,请将其设置在.bashrc或其他地方。

定义文件(backend.tf)

这是一个用于远程管理tfstate的配置。

terraform {
  backend "azurerm" {
    resource_group_name  = "tstate"
    storage_account_name = "tstate12763"
    container_name       = "tstate"
    key                  = "terraform.tfstate"
  }
}

定义文件(vars.tf)

可以声明一个名为config的变量。
通常会使用默认值,但也可以在terraform plan或terraform apply时通过选项指定。

variable "resource_prefix" {
  default = "testprefix"
}

variable "location" {
  default = "japaneast"
}

主要.tf文件的定义文件

要创建的文件如下所示

– 资源组
– 虚拟网络
– 子网
– 网络安全组
– 网络接口
– 虚拟机

provider "azurerm" {
    version = "=1.39.0"
}

# Create a resource group
resource "azurerm_resource_group" "rg" {
    name     = "myTFResourceGroup"
    location = "japaneast"
}

# Create a virtual network
resource "azurerm_virtual_network" "vnet" {
    name                = "myTFVnet"
    address_space       = ["10.0.0.0/16"]
    location            = var.location
    resource_group_name = azurerm_resource_group.rg.name
}

# Create subnet
resource "azurerm_subnet" "subnet" {
  name                 = "myTFSubnet"
  resource_group_name  = azurerm_resource_group.rg.name
  virtual_network_name = azurerm_virtual_network.vnet.name
  address_prefix       = "10.0.1.0/24"
}

# Create public IP
resource "azurerm_public_ip" "publicip" {
  name                = "${var.resource_prefix}TFPublicIP"
  location            = var.location
  resource_group_name = azurerm_resource_group.rg.name
  allocation_method   = "Static"
}

# Create Network Security Group and rule
resource "azurerm_network_security_group" "nsg" {
  name                = "myTFNSG"
  location            = var.location
  resource_group_name = azurerm_resource_group.rg.name

  security_rule {
    name                       = "SSH"
    priority                   = 1001
    direction                  = "Inbound"
    access                     = "Allow"
    protocol                   = "Tcp"
    source_port_range          = "*"
    destination_port_range     = "22"
    source_address_prefix      = "*"
    destination_address_prefix = "*"
  }
}

# Create network interface
resource "azurerm_network_interface" "nic" {
  name                      = "myNIC"
  location                  = var.location
  resource_group_name       = azurerm_resource_group.rg.name
  network_security_group_id = azurerm_network_security_group.nsg.id

  ip_configuration {
    name                          = "myNICConfg"
    subnet_id                     = azurerm_subnet.subnet.id
    private_ip_address_allocation = "dynamic"
    public_ip_address_id          = azurerm_public_ip.publicip.id
  }
}

# Create a Linux virtual machine
resource "azurerm_virtual_machine" "vm" {
  name                  = "myTFVM"
  location              = var.location
  resource_group_name   = azurerm_resource_group.rg.name
  network_interface_ids = [azurerm_network_interface.nic.id]
  vm_size               = "Standard_DS1_v2"

  storage_os_disk {
    name              = "myOsDisk"
    caching           = "ReadWrite"
    create_option     = "FromImage"
    managed_disk_type = "Premium_LRS"
  }

  storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "16.04.0-LTS"
    version   = "latest"
  }

  os_profile {
    computer_name  = "myTFVM"
    admin_username = "plankton"
    admin_password = "Password1234!"
  }

  os_profile_linux_config {
    disable_password_authentication = false
  }
}

确认要创建的资源-创建

% terraform plan
Acquiring state lock. This may take a few moments...
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

~~~省略~~~

Plan: 7 to add, 0 to change, 0 to destroy.

------------------------------------------------------------------------

Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.

%

 % terraform apply
Acquiring state lock. This may take a few moments...

An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create

~~~省略~~~

Plan: 7 to add, 0 to change, 0 to destroy.

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    ※yesを入力しEnter

Apply complete! Resources: 7 added, 0 changed, 0 destroyed.

申请已完成!

登录确认已创建的虚拟机。

获取IP地址

% az vm list-ip-addresses --query "[].virtualMachine[].{Name:name, PublicIp:network.publicIpAddresses[0].ipAddress, PrivateIp:network.privateIpAddresses[0]}" -o table -g myTFResourceGroup
Name    PublicIp        PrivateIp
------  --------------  -----------
myTFVM  52.140.240.152  10.0.1.4

登录到目标主机

% ssh plankton@52.140.240.152
The authenticity of host '52.140.240.152 (52.140.240.152)' can't be established.
ECDSA key fingerprint is SHA256:AmCpQpiGo9TYY65wKZKHcNYMIPKGwxg2UZaxPCXEpsY.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '52.140.240.152' (ECDSA) to the list of known hosts.
plankton@52.140.240.152's password:
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.15.0-1066-azure x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

0 packages can be updated.
0 updates are security updates.



The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.

plankton@myTFVM:~$

整理收拾

% terraform destroy


Plan: 0 to add, 0 to change, 7 to destroy.

Do you really want to destroy all resources?
  Terraform will destroy all your managed infrastructure, as shown above.
  There is no undo. Only 'yes' will be accepted to confirm.

  Enter a value: yes

Destroy complete! Resources: 7 destroyed.

% terraform show

% 


删除完成

请参考

土壤构建官方文件
土壤入门指南
土壤Azure提供者
土壤后端
创建Azure存储帐户
获取虚拟机的IP地址
关于tfstate的说明

广告
将在 10 秒后关闭
bannerAds