节前有用户提了两个需求,PostgreSQL和Terraform,趁着过节有大块的时间,把这两个都粗略的过了下。之前已经把PostgreSQL相关测试结果写了篇文档,正好把Terraform的学习经历也记录下来,写个文档。

       Terraform的网站上是这么介绍的“Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions.”。在我看来它是一个可以实现跨云的代码即基础架构工具。目前Terraform支持的公有/私有云平台包括: AWS,Azure(ARM和ASM),阿里云,Google Cloud,Oracle Cloud,OpenStack,CloudStack,VMware等等等等等。嗯,要是还能支持AzureStack就完美了。

       Terraform具体的功能可以在www.terraform.io上学习,它的文档和示例都写得很不错,我在这就简单介绍下怎么用Terraform来管理Azure上的基础架构。

  目前Terraform支持Azure ARM的功能如下

Base Resource

azurerm_resource_group

Creates a new resource group on Azure.

Template

azurerm_template_deployment

Create a template deployment of resources

Web App

azurerm_app_service_plan

Create an App Service Plan component

azurerm_app_service

Manages an App Service (within an App Service Plan)

Virtual Machine

azurerm_virtual_machine

Create a virtual machine.

azurerm_availability_set

Create an availability set for virtual machines.

azurerm_virtual_machine_extension

Creates a new Virtual Machine Extension to provide post deployment configuration and run automated tasks.

azurerm_virtual_machine_scale_set

Create a virtual machine scale set.

Storage

azurerm_storage_account

Create an Azure Storage Account.

azurerm_storage_container

Create an Azure Storage Container.

azurerm_storage_blob

Create an Azure Storage Blob.

azurerm_storage_queue

Create an Azure Storage Queue.

azurerm_storage_share

Create an Azure Storage File Share.

azurerm_storage_table

Create an Azure Storage Table.

Managed Disk

azurerm_managed_disk

Create a managed disk.

azurerm_image

Create a custom virtual machine image that can be used to create virtual machines.

Network

azurerm_express_route_circuit

Creates an ExpressRoute circuit.

azurerm_local_network_gateway

Creates a new local network gateway connection over which specific connections can be configured.

azurerm_network_interface

Manages a Network Interface located in a Virtual Network, usually attached to a Virtual Machine.

azurerm_network_security_group

Create a network security group that contains a list of network security rules.

azurerm_network_security_rule

Create a Network Security Rule.

azurerm_public_ip

Create a Public IP Address.

azurerm_route

Creates a new Route Resource

azurerm_route_table

Creates a new Route Table Resource

azurerm_subnet

Creates a new subnet. Subnets represent network segments within the IP space defined by the virtual network.

azurerm_traffic_manager_endpoint

Creates a Traffic Manager Endpoint.

azurerm_traffic_manager_profile

Creates a Traffic Manager Profile to which multiple endpoints can be attached.

azurerm_virtual_network

Creates a new virtual network including any configured subnets. Each subnet can optionally be configured with a security group to be associated with the subnet.

azurerm_virtual_network_peering

Creates a new virtual network peering which allows resources to access other resources in the linked virtual network.

Load Balance

azurerm_lb

Create a LoadBalancer Resource.

azurerm_lb_backend_address_pool

Create a LoadBalancer Backend Address Pool.

azurerm_lb_rule

Create a LoadBalancer Rule.

azurerm_lb_nat_rule

Create a LoadBalancer NAT Rule.

azurerm_lb_nat_pool

Create a LoadBalancer NAT pool.

azurerm_lb_probe

Create a LoadBalancer Probe Resource.

Automation

azurerm_automation_account

Creates a new Automation Account.

azurerm_automation_credential

Creates a new Automation Credential.

azurerm_automation_runbook

Creates a new Automation Runbook.

azurerm_automation_schedule

Creates a new Automation Schedule.

 

除了这些基础服务,Terraform还支持更多服务,包括Database:MySQL,SQL Server,还有Azure.com支持的PostgreSQL和CosmosDB。DNS 服务,KeyVault服务,消息队列:Event Hub,Service Bus。Redis服务,CDN服务,容器服务(Azure.com支持)。

 

要使用Terraform来部署Azure资源,官方建议是通过Service Principal 来通过Azure认证。我们会在每个部署脚本最前面看到这样一段内容:

provider "azurerm" {

  subscription_id = "..."

  client_id       = "..."

  client_secret   = "..."

  tenant_id       = "..."

}

在这段脚本里指定了登录到哪个Azure环境,使用哪个订阅,以及用户认证。所以接下来我们首先要获得这几个参数。

  首先,我们通过Azure Cli登录Azure。如果要登录Azure.cn,记得先用“az cloud set -n AzureChinaCloud” 设置登录环境。

用 az login 命令登录,按照提示进行网页验证。登录成功后会看到类似以下的返回:

[

  {

    "cloudName": "AzureChinaCloud",

    "id": "XXXXXXXXXXXXXXXXXXXXXXXXXX",

    "isDefault": true,

    "name": "Microsoft Azure Enterprise \u8bd5\u7528\u7248",

    "state": "Enabled",

    "tenantId": "XXXXXXXXXXXXXXXXXXXXXXXXX",

    "user": {

      "name": "XXXXXXXX@smsptsp.partner.onmschina.cn",

      "type": "user"

    }

  }

]

 注意,这其中的id和tenantid就对应了我们需要的subscription_id和tenant_id这两个参数。

接下来用az ad sp create-for-rbac --role="Contributor" --scopes="/subscriptions/<subscription_id>" 这个命令来创建 Service Principal . 顺利的话可以看到以下返回:

Retrying role assignment creation: 1/36

Retrying role assignment creation: 2/36

Retrying role assignment creation: 3/36

{

  "appId": "XXXXXXXXXXXXXXXXXXXXXXXXX",

  "displayName": "azure-cli-2017-09-28-08-01-33",

  "name": "http://azure-cli-2017-09-28-08-01-33",

  "password": "XXXXXXXXXXXXXXXXXXXXXXXXXXX",

  "tenant": "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

}

其中appId和password分别对应了我们需要的参数client_id和client_secret

其实也可以在GUI界面里进行相同的工作,结果大致如下图所示

顺便说一下,按照这个思路,我最后写了4个脚本,可以分别在Azure CLI和Powershell环境下登录Azure.com和Azure.cn。不需要在本机或Azure上保存任何证书都可以使用。还是很方便的。大家如果有兴趣以后再写一个文档说明是怎么做的。

      

       获得所需要的Azure登录参数,我们就可以正式来写一个Terraform脚本来部署一个虚机了。

       这次我们用到的脚本如下:

 variable "resourcesname" {

  default = "helloterraform"

}

 

# 这段是配置Azure的使用环境

# 注意,因为使用的是Azure.cn,所以要加上参数environment = "china",默认是azure.com,参数使用上面所讲的步骤里获得的那几个参数

provider "azurerm" {

  subscription_id = "XXXXXXXXXXXXXXXXXXXXXXXXXXXX"

  client_id       = "XXXXXXXXXXXXXXXXXXXXXXXXXXX"

  client_secret   = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

  tenant_id       = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"

  environment     = "china"

}

 

# 创建一个Resource Group,名字是lyq-testterraform-rg,位置是北京

resource "azurerm_resource_group" "helloterraform" {

    name = "lyq-testterraform-rg"

    location = "China North"

}

 

# 创建一个虚拟网络,给定name,IP,位置和所属资源组

resource "azurerm_virtual_network" "helloterraformnetwork" {

    name = "tfvn"

    address_space = ["10.0.0.0/16"]

    location = "China North"

    resource_group_name = "${azurerm_resource_group.helloterraform.name}"

}

 

# 创建一个虚拟子网

resource "azurerm_subnet" "helloterraformsubnet" {

    name = "tfsub"

    resource_group_name = "${azurerm_resource_group.helloterraform.name}"

    virtual_network_name = "${azurerm_virtual_network.helloterraformnetwork.name}"

    address_prefix = "10.0.2.0/24"

}

 

 

# 创建一个公网地址

resource "azurerm_public_ip" "helloterraformips" {

    name = "terraformtestip"

    location = "China North"

    resource_group_name = "${azurerm_resource_group.helloterraform.name}"

    public_ip_address_allocation = "dynamic"

 

    tags {

        environment = "TerraformDemo"

    }

}

 

# 创建一块虚拟网卡

resource "azurerm_network_interface" "helloterraformnic" {

    name = "tfni"

    location = "China North"

    resource_group_name = "${azurerm_resource_group.helloterraform.name}"

 

    ip_configuration {

        name = "testconfiguration1"

        subnet_id = "${azurerm_subnet.helloterraformsubnet.id}"

        private_ip_address_allocation = "static"

        private_ip_address = "10.0.2.5"

        public_ip_address_id = "${azurerm_public_ip.helloterraformips.id}"

    }

}

 

# 创建一个随机数,我们知道存储账户是要求一个不冲突的独立命名,这个随机数就是用在存储账户里的

resource "random_id" "randomId" {

  byte_length = 4

}

 

# 创建一个存储账户,也可以创建一个managed disk

resource "azurerm_storage_account" "helloterraformstorage" {

    name                = "tfstorage${random_id.randomId.hex}"

    resource_group_name = "${azurerm_resource_group.helloterraform.name}"

    location = "China North"

    account_type = "Standard_LRS"

 

    tags {

        environment = "staging"

    }

}

 

# 创建一个存储容器

resource "azurerm_storage_container" "helloterraformstoragestoragecontainer" {

    name = "vhd"

    resource_group_name = "${azurerm_resource_group.helloterraform.name}"

    storage_account_name = "${azurerm_storage_account.helloterraformstorage.name}"

    container_access_type = "private"

    depends_on = ["azurerm_storage_account.helloterraformstorage"]

}

 

# 创建虚拟机,用Ubuntu系统,将之前创建的虚拟网卡,存储都挂载好,设定用户名和密码,在生产环境里建议disable_password_authentication = true,这样需要指定证书登录。

resource "azurerm_virtual_machine" "helloterraformvm" {

    name = "terraformvm"

    location = "China North"

    resource_group_name = "${azurerm_resource_group.helloterraform.name}"

    network_interface_ids = ["${azurerm_network_interface.helloterraformnic.id}"]

    vm_size = "Standard_A0"

 

    storage_image_reference {

        publisher = "Canonical"

        offer = "UbuntuServer"

        sku = "14.04.2-LTS"

        version = "latest"

    }

 

    storage_os_disk {

        name = "myosdisk"

        vhd_uri = "${azurerm_storage_account.helloterraformstorage.primary_blob_endpoint}${azurerm_storage_container.helloterraformstoragestoragecontainer.name}/myosdisk.vhd"

        caching = "ReadWrite"

        create_option = "FromImage"

    }

 

    os_profile {

        computer_name = "hostname"

        admin_username = "testadmin"

        admin_password = "Password1234!"

    }

 

    os_profile_linux_config {

        disable_password_authentication = false

    }

 

    tags {

        environment = "staging"

    }

}

 

这样就可以创建一个虚拟机了。将以上脚本保存为tf文件,例如:lyqdemo.tf,然后先用terraform plan命令来验证脚本是否正确,还可以用-out参数来输出一个执行脚本,例如:terraform plan -out lyqdemo .

验证没有问题后,用 terraform apply 或 terraform apply lyqdemo 命令来执行变更。等执行完成后,我们可以在Azure.cn界面里查看下创建的是否正确

 

 

创建虚拟机可以说是最简单的一个动作了,接下来我们会做一些更复杂的事情。

posted on 2017-10-06 15:19  johntoo  阅读(674)  评论(0编辑  收藏  举报