Terraform 學(xué)習(xí)筆記

Terraform 是一個 IT 基礎(chǔ)架構(gòu)自動化編排工具与学,它的口號是 "Write, Plan, and create Infrastructure as Code", 基礎(chǔ)架構(gòu)即代碼鸯隅。Terraform 幾乎可以支持所有市面上能見到的云服務(wù)邦尊。

Terraform 要解決的就是在云上那些硬件資源分配管理的問題。相比較 Chef, Puppet, Ansible 這些軟件配置工具立由,Terraform 提供的是軟件配置之前后裸,軟硬件(基礎(chǔ))資源構(gòu)建的問題。

當(dāng)我們創(chuàng)建資源時殖蚕,使用 terraform 比 ansible 好在哪里轿衔?

  • 并發(fā)創(chuàng)建,速度快
  • 擴(kuò)容/縮容 很方便睦疫,改一個數(shù)字就行
  • state 文件記錄資源狀態(tài)

就創(chuàng)建資源這個角度來說害驹,terraform 和 ansible 都能完成,terraform能夠并發(fā)蛤育,效率高很多宛官,另外它在資源生產(chǎn)成功之后會在本地以一個state文件的形式記錄整個資源的詳細(xì)信息葫松,而這些信息的記錄使得整個模板所定義的資源可以保證前后端的高度一致性,可以有利于后續(xù)對于整個一套資源的有效的版本控制底洗。同時Terraform擁有一個Data Source功能腋么,利用這個功能可以實現(xiàn)對于已有資源的獲取,比如在生產(chǎn)資源之前想要查看當(dāng)前有哪些可用區(qū)亥揖,有哪些可用鏡像等珊擂,所有的這些都可以通過DataSource實現(xiàn)。

Terraform 和 Ansible 的結(jié)合

  • terraform 調(diào)用 ansible
    • Provisioner(local-exec, remote-exec) (官方推薦)
  • ansible 調(diào)用 terraform
    • Ansible module for terraform(官方推薦)
  • 其它方式
    • terraform output 生成 inventory 給 ansible 使用(手工)
    • Terraform template 渲染后费变,生成 inventory 給 ansible 使用(自動)
    • Terraform創(chuàng)建的時候使用tag摧扇,ansible直接對tag 操作(完全解耦,云平臺挚歧,動態(tài)主機(jī)列表)
    • 第三方工具解析state文件給ansible使用扛稽。 比如 Terraform - Inventory 這個第三方工具能夠?qū)erraform生產(chǎn)出的資源轉(zhuǎn)化為Ansible想要的Inventory文件

安裝軟件

  1. 下載zip 文件 https://www.terraform.io/downloads.html
  2. 解壓后直接就能用。把文件放到合適的路徑滑负,比如 /usr/local/bin

生成配置文件

  1. 新建目錄在张,并生成配置文件,比如 azure.tf

    # Configure the provider
    provider "azurerm" {
        version = "=1.20.0"
    }
    
    # Create a new resource group
    resource "azurerm_resource_group" "rg" {
        name     = "royTR"
        location = "eastasia"
    }
    

    配置有兩部分:provider 和 resource橙困。provider 告知與哪一個云平臺打交道瞧掺,這里是Azure;如果使用AWS凡傅,這里就寫成 provider "aws"辟狈。第二部分是資源,說明要生成哪些資源夏跷,例子中是resource group哼转,還可以繼續(xù)往下寫,比如網(wǎng)卡槽华,存儲壹蔓,虛擬機(jī)等。

格式:resource resource_type resource_name { }

A resource block has two string parameters before opening the block: the resource type (first parameter) and the resource name (second parameter). The combination of the type and name must be unique in the configuration.

我已經(jīng)通過Azure CLI 登陸過猫态,所以上面provider 部分沒有提供用戶驗證信息佣蓉,如果單獨配置,使用如下形式:

# Configure the Microsoft Azure Provider
provider "azurerm" {
  # More information on the authentication methods supported by
  # the AzureRM Provider can be found here:
  # http://terraform.io/docs/providers/azurerm/index.html

  subscription_id = "..."
  client_id       = "..."
  client_secret   = "..."
  tenant_id       = "..."
}

這些信息怎么獲取? 可以用Azure CLI 的命令生成:

az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/${SUBSCRIPTION_ID}"

詳細(xì)信息參考微軟文檔

創(chuàng)建資源

  1. 初始化

    在初始化項目的時候亲雪,Terraform 會解析目錄下的*.tf文件并加載相關(guān)的 provider插件勇凭。

$ terraform init

Initializing provider plugins...
- Checking for available provider plugins on https://releases.hashicorp.com...
- Downloading plugin for provider "azurerm" (1.20.0)...

Terraform has been successfully initialized!

You may now begin working with Terraform. Try running "terraform plan" to see
any changes that are required for your infrastructure. All Terraform commands
should now work.

If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
  1. apply changes

    This output shows the execution plan, describing which actions Terraform will take in order to change real infrastructure to match the configuration.

    $ terraform apply .
    
    An execution plan has been generated and is shown below.
    Resource actions are indicated with the following symbols:
      + create
    
    Terraform will perform the following actions:
    
      + azurerm_resource_group.rg
          id:       <computed>
          location: "eastasia"
          name:     "royTR"
          tags.%:   <computed>
    
    
    Plan: 1 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  # 查看 execution plan 符合期望,輸入 yes 確認(rèn)义辕,之后真正執(zhí)行虾标。
    
    azurerm_resource_group.rg: Creating...
      location: "" => "eastasia"
      name:     "" => "royTR"
      tags.%:   "" => "<computed>"
    azurerm_resource_group.rg: Creation complete after 1s (ID: /subscriptions/7c91db0e-eb7f-491b-997f-32cf55b85dea/resourceGroups/royTR)
    
    Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
    
  1. 查看狀態(tài)
$ terraform state show
id       = /subscriptions/7c91db0e-eb7f-491b-997f-32cf55b85dea/resourceGroups/royTR
location = eastasia
name     = royTR
tags.%   = 0

更多

$ terraform state list
module.roy-azure.azurerm_availability_set.hdp-avset
module.roy-azure.azurerm_network_interface.bastion-nic
...
$ terraform state show module.roy-azure.azurerm_virtual_machine.hdp-slave[1]
...
location                                                         = japaneast
name                                                             = roy-tf0-hdp-slave-02
...
$ terraform state show module.roy-azure.azurerm_network_interface.hdp[0]
...
ip_configuration.0.load_balancer_backend_address_pools_ids.#       = 0
ip_configuration.0.load_balancer_inbound_nat_rules_ids.#           = 0
ip_configuration.0.name                                            = hdp-01-ip-conf
....
private_ip_address                                                 = 10.0.10.8
...

更改資源

  1. 改配置

    修改剛才的文件,添加tag部分灌砖。

   # Configure the provider
   provider "azurerm" {
       version = "=1.20.0"
   }
   
   # Create a new resource group
   resource "azurerm_resource_group" "rg" {
       name     = "royTR"
       location = "eastasia"
       tags {
           environment = "TF sandbox"
       }
   }
  1. apply changes

    An execution plan has been generated and is shown below.
    Resource actions are indicated with the following symbols:
      ~ update in-place
    
    Terraform will perform the following actions:
    
      ~ azurerm_resource_group.rg
          tags.%:           "0" => "1"
          tags.environment: "" => "TF sandbox"
    
    
    Plan: 0 to add, 1 to change, 0 to destroy.
    

銷毀基礎(chǔ)設(shè)施

terraform destroy

$ terraform destroy
azurerm_resource_group.rg: Refreshing state... (ID: /subscriptions/xxxx/resourceGroups/royTR-rg)

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

Terraform will perform the following actions:

  - azurerm_resource_group.rg


Plan: 0 to add, 0 to change, 1 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

azurerm_resource_group.rg: Destroying... (ID: /subscriptions/xxxxx/resourceGroups/royTR-rg)
azurerm_resource_group.rg: Still destroying... (ID: /subscriptions/xxxx/resourceGroups/royTR-rg, 10s elapsed)
azurerm_resource_group.rg: Still destroying... (ID: /subscriptions/xxxxx/resourceGroups/royTR-rg, 20s elapsed)
azurerm_resource_group.rg: Still destroying... (ID: /subscriptions/xxxxx/resourceGroups/royTR-rg, 30s elapsed)
azurerm_resource_group.rg: Still destroying... (ID: /subscriptions/xxxxx/resourceGroups/royTR-rg, 40s elapsed)
azurerm_resource_group.rg: Destruction complete after 48s

Destroy complete! Resources: 1 destroyed.

單獨刪除一個資源:

$ terraform destroy -target=module.roy-azure.azurerm_virtual_machine.hdp[2]
...
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  - destroy

Terraform will perform the following actions:

  - module.roy-azure.azurerm_virtual_machine.hdp[2]


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

Do you really want to destroy all resources?
....
Destroy complete! Resources: 1 destroyed.

資源的依賴關(guān)系

要創(chuàng)建一個VM璧函,需要一些資源已經(jīng)具備傀蚌,這些資源可能包括:

  • Resource group
  • Virtual network and subnet
  • Public IP
  • Network security group
  • Network interface

先來一個簡單的例子,創(chuàng)建網(wǎng)絡(luò):

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

location等部分引入了插值(interpolation)蘸吓,它已經(jīng)在前面的資源定義善炫,之后直接調(diào)用,格式是 TYPE.NAME.ATTRIBUTE.
Azure 網(wǎng)絡(luò)和虛擬機(jī)的基礎(chǔ)架構(gòu)如下圖所示:

azure_vm_structure.png

把上面的圖美澳,變成代碼销部,創(chuàng)建VM需要的整個文件:

# Configure the provider
provider "azurerm" {
    version = "=1.20.0"
}

# Create a new resource group
resource "azurerm_resource_group" "rg" {
    name     = "royTR"
    location = "eastasia"
    tags {
        environment = "TF sandbox"
    }
}

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

# Create subnet
resource "azurerm_subnet" "subnet" {
    name                 = "royTFSubnet"
    resource_group_name  = "${azurerm_resource_group.rg.name}"
    virtual_network_name = "${azurerm_virtual_network.vnet.name}"
    address_prefix       = "10.0.1.0/24"
    #address_prefix       = "${cidrsubnet(var.cluster_cidr, 8, 10)}"
}

# Create public IP
resource "azurerm_public_ip" "publicip" {
    name                         = "myTFPublicIP"
    location                     = "${azurerm_resource_group.rg.location}"
    resource_group_name          = "${azurerm_resource_group.rg.name}"
    public_ip_address_allocation = "dynamic"
    }

# Create Network Security Group and rule
resource "azurerm_network_security_group" "nsg" {
    name                = "myTFNSG"
    location            = "${azurerm_resource_group.rg.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                  = "${azurerm_resource_group.rg.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                  = "royTFVM"
    location              = "${azurerm_resource_group.rg.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  = "royvm"
        admin_username = "royzeng"
    }

    os_profile_linux_config {
        disable_password_authentication = true
        ssh_keys {
            path     = "/home/royzeng/.ssh/authorized_keys"
            key_data = "ssh-rsa AAAAB3Nz{snip}hwhqT9h"
        }
    }

}

使用 Provisioners 進(jìn)行環(huán)境配置

Provisioners 可以在資源創(chuàng)建/銷毀時在本地/遠(yuǎn)程執(zhí)行腳本。

Provisioners 通常用來引導(dǎo)一個資源制跟,在銷毀資源前完成清理工作,進(jìn)行配置管理等酱虎。

Provisioners擁有多種類型可以滿足多種需求雨膨,如:文件傳輸(file),本地執(zhí)行(local-exec)读串,遠(yuǎn)程執(zhí)行(remote-exec)等 Provisioners可以添加在任何的resource當(dāng)中:

# Create a Linux virtual machine
resource "azurerm_virtual_machine" "vm" {

<...snip...>

    provisioner "file" {
        connection {
            type        = "ssh"
            user        = "royzeng"
            private_key = "${file("~/.ssh/id_rsa")}"
        }

        source      = "newfile.txt"
        destination = "newfile.txt"
    }

    provisioner "remote-exec" {
        connection {
            type        = "ssh"
            user        = "royzeng"
            private_key = "${file("~/.ssh/id_rsa")}"
        }

        inline = [
        "ls -a",
        "cat newfile.txt"
        ]
    }

}

上面的方式適合有public ip聊记,能夠直接連接的機(jī)器,對于不能直接連接的vm恢暖,通過跳板來實現(xiàn)排监。

官方的方法,定義 bastion_host

resource "null_resource" "connect_private" {
  connection {
    bastion_host = "${aws_instance.bastion.public_ip}"
    host         = "${aws_instance.private.private_ip}"
    user         = "ubuntu"
    private_key  = "${file("~/.ssh/id_rsa")}"
  }

  provisioner "remote-exec" {
    inline = ["echo 'CONNECTED to PRIVATE!'"]
  }
}

或者

resource "azurerm_virtual_machine" "vm" {

<...snip...>


    provisioner "remote-exec" {
        connection {
            bastion_host= "${azurerm_public_ip.bastion.ip_address}"
            type        = "ssh"
            user        = "${var.admin-username}"
            private_key = "${file("~/.ssh/id_rsa")}"
        }

        inline = [
        "sudo parted /dev/disk/azure/scsi1/lun0 mklabel msdos",
        "sudo parted /dev/disk/azure/scsi1/lun0 mkpart primary 1 100%",
        "sudo partprobe",
        "sleep 5; sudo mkfs.xfs /dev/disk/azure/scsi1/lun0-part1",
        "sudo mkdir /roytest",
        "sudo mount /dev/disk/azure/scsi1/lun0-part1 ${var.mount_path[0]}",
        "echo 'UUID='`sudo blkid -s UUID -o value $(readlink -f /dev/disk/azure/scsi1/lun0-part1)`  ${var.mount_path[0]} 'xfs defaults  0 0' | sudo tee -a /etc/fstab",
        "df -hl | grep /dev/sd"
        ]
    }
}

另一種方法杰捂,用local-exec 來跳轉(zhuǎn)

  provisioner "local-exec" {
    ## 簡化方式
    command = "ssh -o "ProxyCommand ssh -q -W %h:%p -i mykey jump_server” -C 'echo hello'"
    ## 真實環(huán)境用的方式
    command = <<EOF
        sleep 30; ansible-playbook -i '${element(azurerm_network_interface.master_bind.*.private_ip_address, count.index)},' ${local.ansible_ssh_args} ${var.ansible_path}/mount_disk.yml --extra-vars '{
        "root_user": "centos",
        "deviceName": "/dev/disk/azure/scsi1/lun0",
        "mountPath": "${var.mount_path}",
        "bind_zone_name": "${var.bind_zone_name}"
        }'
        EOF
    }

使用 null resource 和 trigger 來解耦

為了讓ansible 腳本單獨運(yùn)行舆床,而不需要創(chuàng)建或銷毀資源,可以用 null_resource 調(diào)用 provisioner 來實現(xiàn)嫁佳。

resource "null_resource" "datanode" {
  count = "${var.count.datanode}"

  triggers {
    instance_ids = "${element(aws_instance.datanode.*.id, count.index)}"
  }

  provisioner "remote-exec" {
    inline = [
      ...
    ]

    connection {
      type = "ssh"
      user = "centos"
      host = "${element(aws_instance.datanode.*.private_ip, count.index)}"
    }
  }
}

輸入變量

新建一個文件定義變量

# file variables.tf
---
variable "prefix" {
  default = "royTF"
}

variable "location" { }

variable "tags" {
  type    = "map"
  default = {
     Environment = "royDemo"
     Dept = "Engineering"
  }
}

文件中 location 部分沒有定義挨队,運(yùn)行terraform的時候,會提示輸入:

$ terraform plan -out royplan
var.location
  Enter a value: eastasia
  
  <...snip...>
  
  This plan was saved to: royplan

To perform exactly these actions, run the following command to apply:
    terraform apply "royplan"

其它輸入變量的方式

命令行輸入

$ terraform apply \
>> -var 'prefix=tf' \
>> -var 'location=eastasia'

文件輸入

$ terraform apply \
  -var-file='secret.tfvars'

默認(rèn)讀取文件 terraform.tfvars蒿往,這個文件不需要單獨指定盛垦。

環(huán)境變量輸入

TF_VAR_name ,比如 TF_VAR_location

變量類型

  • list
  • map

對于 list 變量

# 定義 list 變量
variable "image-RHEL" {
  type = "list"
  default = ["RedHat", "RHEL", "7.5", "latest"]
}

# 調(diào)用 list 變量

    storage_image_reference {
        publisher = "${var.image-RHEL[0]}"
        offer     = "${var.image-RHEL[1]}"
        sku       = "${var.image-RHEL[2]}"
        version   = "${var.image-RHEL[3]}"
    }

map 是一個可以被查詢的表瓤漏。

variable "sku" {
    type = "map"
    default = {
        westus = "16.04-LTS"
        eastus = "18.04-LTS"
    }
}

查詢方式(使用 lookup)

storage_image_reference {
    publisher = "Canonical"
    offer     = "UbuntuServer"
    sku       = "${lookup(var.sku, var.location)}"
    version   = "latest"
}

輸出變量

定義輸出

output "ip" {
    value = "${azurerm_public_ip.publicip.ip_address}"
}

測試

$ terraform apply
...

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

Outputs:

  ip = 52.184.97.1
$ terraform output ip
52.184.97.1

Bug? 第一次運(yùn)行腾夯,ip 輸出是空的,terraform output ip 命令的結(jié)果也是空的蔬充,過一段時間才能看到結(jié)果蝶俱。

$ terraform output -module=roy-azure
bastion-private-ip = 10.0.1.4
bastion-public-ip = 40.115.243.72
cluster_cidr = 10.0.0.0/16
cluster_location = japaneast
cluster_prefix = roy-tf0
cluster_resource_group = roy-tf0-rg
hdp-master-ip = 10.0.10.4,10.0.10.6,10.0.10.7
hdp-master-name = roy-tf0-hdp-master-01,roy-tf0-hdp-master-02,roy-tf0-hdp-master-03
hdp-slave-ip = 10.0.10.5,10.0.10.9,10.0.10.8
hdp-slave-name = roy-tf0-hdp-slave-01,roy-tf0-hdp-slave-02,roy-tf0-hdp-slave-03
k8s-master-ip = 10.0.20.8,10.0.20.5
k8s-master-name = roy-tf0-k8s-master-01,roy-tf0-k8s-master-02
k8s-slave-ip = 10.0.20.6,10.0.20.7,10.0.20.4
k8s-slave-name = roy-tf0-k8s-slave-01,roy-tf0-k8s-slave-02,roy-tf0-k8s-slave-03
virtual_network = roy-tf0-vnet

Data Source

DataSource 的作用可以通過輸入一個資源的變量名,然后獲得這個變量的其他屬性字段娃惯。

用 Azure網(wǎng)絡(luò) 來舉例跷乐,提供一些信息,查詢其它的屬性趾浅。具體必須提供什么愕提,能查到什么馒稍,參考這個鏈接

data "azurerm_virtual_network" "test" {
  name                = "production"
  resource_group_name = "networking"
}

output "virtual_network_id" {
  value = "${data.azurerm_virtual_network.test.id}"
}

output "virtual_network_subnet" {
  value = "${data.azurerm_virtual_network.test.subnets[0]}"
}

生成主機(jī)列表

ansible通過主機(jī)列表來連接目標(biāo)主機(jī)浅侨,我們就要想辦法讓terraform來生成纽谒。(local-exec 也是一種方式,這是另一種思路:用terraform 調(diào)用ansible)

terraform 生成inventory的思路是:從模板到文件如输,需要先用template_file 渲染成一個字符串鼓黔,然后用local_file把這個字符串輸出到一個文件。

模版文件

## file inventory.tpl

[backend]
${bastion_private_ip}

[frontend]
${bastion_pub_ip}

[all:vars]
ansible_ssh_private_key_file = ${key_path}
ansible_ssh_user = dcpuser

渲染和輸出

## file inventory.tf

data "template_file" "inventory" {
    template = "${file("./test/inventory.tpl")}"

    vars {
        bastion_private_ip      = "${element(azurerm_network_interface.bastion-nic.*.private_ip_address, count.index)}"
        bastion_pub_ip          = "${element(azurerm_public_ip.bastion.*.ip_address, count.index)}"
        key_path = "~/.ssh/id_rsa"
    }
}

resource "local_file" "save_inventory" {
  content  = "${data.template_file.inventory.rendered}"
  filename = "./myhost"
}

運(yùn)行后不见,當(dāng)前目錄生成文件myhost

[backend]
13.78.94.242

[frontend]
10.0.1.4

[all:vars]
ansible_ssh_private_key_file = ~/.ssh/id_rsa
ansible_ssh_user = dcpuser

對于多個主機(jī)澳化,使用 join 來把它們合在一起。

File inventory.tf

data  "template_file" "k8s" {
    template = "${file("./templates/k8s.tpl")}"
    vars {
        k8s_master_name = "${join("\n", azurerm_virtual_machine.k8s-master.*.name)}"
    }
}

resource "local_file" "k8s_file" {
  content  = "${data.template_file.k8s.rendered}"
  filename = "./inventory/k8s-host"
}

File k8s.tpl

[kube-master]
${k8s_master_name}

Final result

[kube-master]
k8s-master-01
k8s-master-02
k8s-master-03

使用module進(jìn)行代碼的組織管理

Module 是 Terraform 為了管理單元化資源而設(shè)計的稳吮,是子節(jié)點缎谷,子資源,子架構(gòu)模板的整合和抽象灶似。將多種可以復(fù)用的資源定義為一個module列林,通過對 module 的管理簡化模板的架構(gòu),降低模板管理的復(fù)雜度酪惭,這就是module的作用希痴。

Terraform中的模塊是以組的形式管理不同的Terraform配置。模塊用于在Terraform中創(chuàng)建可重用組件春感,以及用于基本代碼組織砌创。每一個module都可以定義自己的input與output,方便代碼進(jìn)行模塊化組織甥厦。

用模塊纺铭,可以寫更少的代碼。比如用下面的代碼刀疙,調(diào)用已有的module 創(chuàng)建vm舶赔。

調(diào)用官方module

# declare variables and defaults
variable "location" {}
variable "environment" {
    default = "dev"
}
variable "vm_size" {
    default = {
        "dev"   = "Standard_B2s"
        "prod"  = "Standard_D2s_v3"
    }
}

# Use the network module to create a resource group, vnet and subnet
module "network" {
    source              = "Azure/network/azurerm"
    version             = "2.0.0"
    location            = "${var.location}"
    resource_group_name = "roytest-rg"
    address_space       = "10.0.0.0/16"
    subnet_names        = ["mySubnet"]
    subnet_prefixes     = ["10.0.1.0/24"]
}

# Use the compute module to create the VM
module "compute" {
    source            = "Azure/compute/azurerm"
    version           = "1.2.0"
    location          = "${var.location}"
    resource_group_name = "roytest-rg"
    vnet_subnet_id    = "${element(module.network.vnet_subnets, 0)}"
    admin_username    = "royzeng"
    admin_password    = "Password1234!"
    remote_port       = "22"
    vm_os_simple      = "UbuntuServer"
    vm_size           = "${lookup(var.vm_size, var.environment)}"
    public_ip_dns     = ["roydns"]
}

調(diào)用自己寫的module

## file main.cf

module "roy-azure" {
  source = "./test"
}

## file test/resource.tf

variable "cluster_prefix" {
  type        = "string"
}
variable "cluster_location" {
    type        = "string"
}

resource "azurerm_resource_group" "core" {
    name     = "${var.cluster_prefix}-rg"
    location = "${var.cluster_location}"
}

參考文檔

https://docs.microsoft.com/en-us/azure/virtual-machines/linux/terraform-install-configure

https://learn.hashicorp.com/terraform/azure/install_az

Provisioner connections

Terraform example

https://www.terraform.io/docs/providers/azurerm/r/virtual_machine.html

Create a VM cluster with Terraform https://docs.microsoft.com/en-us/azure/terraform/terraform-create-vm-cluster-with-infrastructure

http://aukjan.vanbelkum.nl/2016/02/23/Ansible-inventory-from-Terraform/

Terraform Azure modules https://registry.terraform.io/browse?offset=9&provider=azurerm

How to use Ansible with Terraform https://alex.dzyoba.com/blog/terraform-ansible/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市谦秧,隨后出現(xiàn)的幾起案子竟纳,更是在濱河造成了極大的恐慌,老刑警劉巖疚鲤,帶你破解...
    沈念sama閱讀 206,839評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件锥累,死亡現(xiàn)場離奇詭異,居然都是意外死亡集歇,警方通過查閱死者的電腦和手機(jī)桶略,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人际歼,你說我怎么就攤上這事惶翻。” “怎么了鹅心?”我有些...
    開封第一講書人閱讀 153,116評論 0 344
  • 文/不壞的土叔 我叫張陵吕粗,是天一觀的道長。 經(jīng)常有香客問我旭愧,道長颅筋,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,371評論 1 279
  • 正文 為了忘掉前任输枯,我火速辦了婚禮议泵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘用押。我一直安慰自己肢簿,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,384評論 5 374
  • 文/花漫 我一把揭開白布蜻拨。 她就那樣靜靜地躺著,像睡著了一般桩引。 火紅的嫁衣襯著肌膚如雪缎讼。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評論 1 285
  • 那天坑匠,我揣著相機(jī)與錄音血崭,去河邊找鬼。 笑死厘灼,一個胖子當(dāng)著我的面吹牛夹纫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播设凹,決...
    沈念sama閱讀 38,416評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼舰讹,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了闪朱?” 一聲冷哼從身側(cè)響起月匣,我...
    開封第一講書人閱讀 37,053評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎奋姿,沒想到半個月后锄开,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,558評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡称诗,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,007評論 2 325
  • 正文 我和宋清朗相戀三年萍悴,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,117評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡癣诱,死狀恐怖计维,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情狡刘,我是刑警寧澤享潜,帶...
    沈念sama閱讀 33,756評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站嗅蔬,受9級特大地震影響剑按,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜澜术,卻給世界環(huán)境...
    茶點故事閱讀 39,324評論 3 307
  • 文/蒙蒙 一艺蝴、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸟废,春花似錦猜敢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至添寺,卻和暖如春胯盯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背计露。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評論 1 262
  • 我被黑心中介騙來泰國打工博脑, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人票罐。 一個月前我還...
    沈念sama閱讀 45,578評論 2 355
  • 正文 我出身青樓叉趣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親该押。 傳聞我的和親對象是個殘疾皇子疗杉,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,877評論 2 345

推薦閱讀更多精彩內(nèi)容

  • rljs by sennchi Timeline of History Part One The Cognitiv...
    sennchi閱讀 7,294評論 0 10
  • The Inner Game of Tennis W Timothy Gallwey Jonathan Cape ...
    網(wǎng)事_79a3閱讀 11,734評論 2 19
  • 朋友說,你看一個人手機(jī)里的音樂沈善,就能知道他大概是怎樣的人乡数,看你的音樂就覺得你是那種“文藝青年”。我說闻牡,“文藝青年...
    米糖西西閱讀 378評論 3 2
  • 這一天是寒冷的净赴,十二月中旬也是該讓我們感受下冬天的真正傷害了,清晨六點罩润,被鬧鈴驚醒玖翅,絲絲倦意依然在眼中彌漫,在想到...
    邂逅君閱讀 298評論 2 3