如何使用Terraform管理云基础架构

在本文中,我们将研究Terraform的组成,并逐步通过VMware在云中启动我们自己的基础架构-我们将准备用于不同目的的三个VM:代理,文件存储和CMS。

一切都分为三个阶段:

1. Terraform — ,

Terraform —   IaC (Infrastructure-as-Code) .

:

  • ( ). , , "" . Terraform (, ) .

  • . , , .

  • . Amazon Google Cloud, VMware vCloud Director, IaaS, SaaS PaaS .

  • , , .

  • - . , , ,

"" Terraform

,

Providers (). 

Terraform   . API providers , , , Azure VMware vCloud Director.

.

Resources ( ).

, . 

VMware vCloud Director -, vCloud Director.  -

Provisioners.

. , , provisioners SSH, , . 

Input Output.

Input —  . 

Output , , Provisioners.

States ().

States- . Terraform .

, , .

  terraform.tfstate, .

, , Terraform.  

2.

, Terraform . - nginx, Nextcloud CMS Bitrix.

VMware vCloud Director. Organization Administrator, VMware, . !

, .

mkdir project01

. Terraform . , , network.tf - .

, :

.

main.tf - - , ;

network.tf - NAT, Firewall;

variables.tf - , ;

vcd.tfvars - VMware vCloud Director.

Terraform , provisioner, .. .

.

<BLOCK TYPE> "<BLOCK LABEL>" "<BLOCK LABEL>" {

# Block body

<IDENTIFIER> = <EXPRESSION> # Argument

}

HCL (HashiCorp Configuration Language), JSON. .

, variables.tf vcd.tfvars

,   VMware vCloud Director. variables.tf.

C variables.tf.

variable "vcd_org_user" {

  description = "vCD Tenant User"

}

variable "vcd_org_password" {

  description = "vCD Tenant Password"

}

variable "vcd_org" {

  description = "vCD Tenant Org"

}

variable "vcd_org_vdc" {

  description = "vCD Tenant VDC"

}

variable "vcd_org_url" {

  description = "vCD Tenant URL"

}

variable "vcd_org_max_retry_timeout" {

  default = "60"

}

variable "vcd_org_allow_unverified_ssl" {

  default = "true"

}

variable "vcd_org_edge_name" {

  description = "vCD edge name"

}

variable "vcd_org_catalog" {

  description = "vCD public catalog"

}

variable "vcd_template_os_centos7" {

  description = "OS CentOS 7"

  default = "CentOS7"

}

variable "vcd_org_ssd_sp" {

  description = "Storage Policies"

  default = "Gold Storage Policy"

}

variable "vcd_org_hdd_sp" {

  description = "Storage Policies"

  default = "Bronze Storage Policy"

}

variable "vcd_edge_local_subnet" {

  description = "Organization Network Subnet"

}

variable "vcd_edge_external_ip" {

  description = "External public IP"

}

variable "vcd_edge_local_ip_nginx" {}

variable "vcd_edge_local_ip_bitrix" {}

variable "vcd_edge_local_ip_nextcloud" {}

variable "vcd_edge_external_network" {}

, .
  • vcd_org_user - Organization Administrator,

  • vcd_org_password - ,

  • vcd_org - ,

  • vcd_org_vdc - -,

  • vcd_org_url - API URL,

  • vcd_org_edge_name - ,

  • vcd_org_catalog - ,

  • vcd_edge_external_ip - IP-,

  • vcd_edge_external_network - ,

  • vcd_org_hdd_sp - HDD,

  • vcd_org_ssd_sp - SSD.

:

  • vcd_edge_local_ip_nginx - IP- NGINX,

  • vcd_edge_local_ip_bitrix - IP- 1: ,

  • vcd_edge_local_ip_nextcloud - IP- Nextcloud.

VMware vCloud Director vcd.tfvars: , mClouds, . 

vcd.tfvars.

vcd_org_url = "https://vcloud.mclouds.ru/api"

vcd_org_user = "orgadmin"

vcd_org_password = "*"

vcd = "org"

vcd_org_vdc = "orgvdc"

vcd_org_maxretry_timeout = 60

vcd_org_allow_unverified_ssl = true

vcd_org_catalog = "Templates"

vcd_templateos_centos7 = "CentOS7"

vcd_org_ssd_sp = "Gold Storage Policy"

vcd_org_hdd_sp = "Bronze Storage Policy"

vcd_org_edge_name = "MCLOUDS-EDGE"

vcd_edge_external_ip = "185.17.66.1"

vcd_edge_local_subnet = "192.168.110.0/24"

vcd_edge_local_ip_nginx = "192.168.110.1"

vcd_edge_local_ip_bitrix = "192.168.110.10"

vcd_edge_local_ip_nextcloud = "192.168.110.11"

vcd_edge_external_network = "NET-185-17-66-0"

, network.tf.

, —  IP- Destination NAT "" . IP-.

Terraform正在创建的平台的网络图
Terraform

net_lan01, : 192.168.110.254,   : 192.168.110.0/24.

.

resource "vcd_network_routed" "net" {

  name = "net_lan01"

  edge_gateway = var.vcd_org_edge_name

  gateway = "192.168.110.254"

  dns1 = "1.1.1.1"

  dns2 = "8.8.8.8"

 static_ip_pool {

start_address = "192.168.110.1"

end_address = "192.168.110.253"

  }

}

, . :

VM .

resource "vcd_nsxv_firewall_rule" "fw_internet_access" {

  edge_gateway   = var.vcdorgedgename

  name = "Internet Access"

  source {

gateway_interfaces = ["internal"]

  }

  destination {

gateway_interfaces = ["external"]

  }

  service {

protocol = "any"

  }

  depends_on = [vcdnetworkrouted.net]

}

, vcdnetworkrouted.net vcdnsxvfirewallrule, dependson. , .

IP- SSH . 80 443 - IP- 90.1.15.1 SSH .

.

resource "vcd_nsxv_firewall_rule" "fwnatports" {

  edge_gateway   = var.vcd_org_edge_name

  name = "HTTPs Access"

  source {

gateway_interfaces = ["external"]

  }

  destination {

  gateway_interfaces = ["internal"]

  }

  service {

protocol = "tcp"

port = "80"

  }

  service {

protocol = "tcp"

port = "443"

  }

  depends_on = [vcd_network_routed.net]

}

resource "vcd_nsxv_firewall_rule" "fw_nat_admin_ports" {

  edge_gateway   = var.vcd_org_edge_name

  name = "Admin Access"

  source {

  ip_addresses = [ "90.1.15.1" ]

  }

  destination {

  gateway_interfaces = ["internal"]

  }

  service {

protocol = "tcp"

port = "58301"

  }

  service {

protocol = "tcp"

port = "58302"

  }

  service {

protocol = "tcp"

port = "58303"

  }

  depends_on = [vcd_network_routed.net]

}

Source NAT :

Source NAT.

resource "vcd_nsxv_snat" "snat_local" {

edge_gateway = var.vcd_org_edge_name

  network_type = "ext"

  network_name = var.vcdedgeexternalnetwork

  original_address   = var.vcd_edge_local_subnet

translated_address = var.vcd_edge_external_ip

  depends_on = [vcd_network_routed.net]

}

Destination NAT :

Destination NAT.

resource "vcd_nsxv_dnat" "dnat_tcp_nginx_https" { edge_gateway = var.vcd_org_edge_name network_name = var.vcd_edge_external_network network_type = "ext"

  description = "NGINX HTTPs"

original_address = var.vcd_edge_external_ip original_port = 443

translated_address = var.vcd_edge_local_ip_nginx translated_port = 443 protocol = "tcp"

depends_on = [vcd_network_routed.net] } resource "vcd_nsxv_dnat" "dnat_tcp_nginx_http" { edge_gateway = var.vcd_org_edge_name network_name = var.vcd_edge_external_network network_type = "ext"

description = "NGINX HTTP"

original_address = var.vcd_edge_external_ip original_port = 80

translated_address = var.vcd_edge_local_ip_nginx translated_port = 80 protocol = "tcp"

depends_on = [vcd_network_routed.net]

}

NAT SSH- Nginx.

resource "vcd_nsxv_dnat" "dnat_tcp-nginx_ssh" { edge_gateway = var.vcd_org_edge_name network_name = var.vcd_edge_external_network network_type = "ext"

description = "SSH NGINX"

original_address = var.vcd_edge_external_ip original_port = 58301

translated_address = var.vcd_edge_local_ip_nginx translated_port = 22 protocol = "tcp"

depends_on = [vcd_network_routed.net]

}

NAT SSH- 1-.

resource "vcd_nsxv_dnat" "dnat_tcp_bitrix_ssh" { edge_gateway = var.vcd_org_edge_name network_name = var.vcd_edge_external_network network_type = "ext"

description = "SSH Bitrix"

original_address = var.vcd_edge_external_ip original_port = 58302

translated_address = var.vcd_edge_local_ip_bitrix translated_port = 22 protocol = "tcp"

depends_on = [vcd_network_routed.net]

}

NAT SSH- Nextcloud.

resource "vcd_nsxv_dnat" "dnat_tcp_nextcloud_ssh" { edge_gateway = var.vcd_org_edge_name network_name = var.vcd_edge_external_network network_type = "ext"

description = "SSH Nextcloud"

original_address = var.vcd_edge_external_ip original_port = 58303 translated_address = var.vcd_edge_local_ip_nextcloud translated_port = 22 protocol = "tcp"

depends_on = [vcd_network_routed.net]

}

main.tf

, . "Guest Customization". , .

vApp .

虚拟机配置

vApp. vApp depends_on:

resource "vcd_vapp" "vapp" { name = "web" power_on = "true" depends_on = [vcd_network_routed.net]

}

resource "vcd_vapp_vm" "nginx" {

vapp_name = vcd_vapp.vapp.name

name = "nginx"

catalog_name = var.vcd_org_catalog

template_name = var.vcd_template_os_centos7

storage_profile = var.vcd_org_ssd_sp

memory = 8192

cpus = 1

cpu_cores = 1

network {

type = "org"

name = vcd_network_routed.net.name

is_primary = true

adapter_type = "VMXNET3"

ip_allocation_mode = "MANUAL"

ip = var.vcd_edge_local_ip_nginx

}

override_template_disk {

bus_type = "paravirtual"

size_in_mb = "32768"

bus_number = 0

unit_number = 0

storage_profile = var.vcd_org_ssd_sp

}

}

VM:

  • name - ,

  • vappname - vApp ,

  • catalogname / templatename - ,

  • storageprofile - .

network:

  • type - ,

  • name - ,

  • isprimary - ,

  • ipallocation_mode - MANUAL / DHCP / POOL,

  • ip - IP- , .

override_template_disk:

  • sizeinmb - boot-

  • storage_profile -

VM Nextcloud

resource "vcd_vapp_vm" "nextcloud" {

vapp_name = vcd_vapp.vapp.name

name = "nextcloud"

catalog_name = var.vcd_org_catalog

template_name = var.vcd_template_os_centos7

storage_profile = var.vcd_org_ssd_sp

memory = 8192

cpus = 1

cpu_cores = 1

network {

type = "org"

name = vcd_network_routed.net.name

is_primary = true

adapter_type = "VMXNET3"

ip_allocation_mode = "MANUAL"

ip = var.vcd_edge_local_ip_nextcloud

}

override_template_disk {

bus_type = "paravirtual"

size_in_mb = "32768"

bus_number = 0

unit_number = 0

storage_profile = var.vcd_org_ssd_sp

}

}

resource "vcd_vm_internal_disk" "disk1" {

vapp_name = vcd_vapp.vapp.name

vm_name = "nextcloud"

bus_type = "paravirtual"

size_in_mb = "102400"

bus_number = 0

unit_number = 1

storage_profile = var.vcd_org_hdd_sp

allow_vm_reboot = true

depends_on = [ vcd_vapp_vm.nextcloud ]

}

vcdvminternal_disk , .

vcdvminternaldisk:

  • bustype -

  • sizeinmb -

  • busnumber / unitnumber -

  • storage_profile -

VM

resource "vcd_vapp_vm" "bitrix" {

vapp_name = vcd_vapp.vapp.name

name = "bitrix"

catalog_name = var.vcd_org_catalog

template_name = var.vcd_template_os_centos7

storage_profile = var.vcd_org_ssd_sp

memory = 8192

cpus = 1

cpu_cores = 1

network {

type = "org"

name = vcd_network_routed.net.name

is_primary = true

adapter_type = "VMXNET3"

ip_allocation_mode = "MANUAL"

ip = var.vcd_edge_local_ip_bitrix

}

override_template_disk {

bus_type = "paravirtual"

size_in_mb = "81920"

bus_number = 0

unit_number = 0

storage_profile = var.vcd_org_ssd_sp

}

}

, . provisioners Ansible.

CMS Bitrix provisioner .

CentOS.

resource "null_resource" "nginx_update_install" {

provisioner "remote-exec" {

connection {

type = "ssh"

user = "root"

password = vcd_vapp_vm.nginx.customization[0].admin_password

host = var.vcd_edge_external_ip

port = "58301"

timeout = "30s"

}

inline = [

"yum -y update && yum -y upgrade",

"yum -y install wget nano epel-release net-tools unzip zip" ]

}

}

}

:

  • provisioner "remote-exec" - ""

  • connection :

  • type - , SSH;

  • user - ;

  • password - . vcdvappvm.nginx.customization[0].admin_password, .

  • host - IP- ;

  • port - , DNAT;

  • inline - , . , .

, 1-. . , :

1-.

provisioner "file" {

source = "prepare.sh"

destination = "/tmp/prepare.sh"

connection {

type = "ssh"

user = "root"

password = vcd_vapp_vm.nginx.customization[0].admin_password

host = var.vcd_edge_external_ip

port = "58301"

timeout = "30s"

}

}

provisioner "remote-exec" {

inline = [

"chmod +x /tmp/prepare.sh", "./tmp/prepare.sh"

]

}

.

1-.

resource "null_resource" "install_update_bitrix" {

provisioner "remote-exec" {

connection {

type = "ssh"

user = "root"

password = vcd_vapp_vm.bitrix.customization[0].admin_password

host = var.vcd_edge_external_ip

port = "58302"

timeout = "60s"

}

inline = [

"yum -y update && yum -y upgrade",

"yum -y install wget nano epel-release net-tools unzip zip",

"wget http://repos.1c-bitrix.ru/yum/bitrix-env.sh -O /tmp/bitrix-env.sh",

"chmod +x /tmp/bitrix-env.sh",

"/tmp/bitrix-env.sh"

]

}

}

! , SELinux! CMS 1- bitrix-env.sh, .

3.

模块和插件的初始化

“ ”: Windows 10 terraform.io. : terraform.exe init

, , , .

  1. - terraform plan -var-file=vcd.tfvars.

  2. - Plan: 16 to add, 0 to change, 0 to destroy. 16 .

  3. - terraform.exe apply -var-file=vcd.tfvars.

, provisioner — CMS Bitrix.

, output :

output "nginxpassword" {

 value = vcdvappvm.nginx.customization[0].adminpassword

}

:

Outputs: nginx_password = F#4u8!!N

. !

?

3.1. Terraform

, vApp import.

vAPP .

resource "vcd_vapp" "Monitoring" {

name = "Monitoring"

org = "mClouds"

vdc = "mClouds"

}

resource "vcd_vapp_vm" "Zabbix" {

name = "Zabbix"

org = "mClouds"

vdc = "mClouds"

vapp = "Monitoring"

}

, vApp vcdvapp.<vApp> <org>.<orgvdc>.<vApp>, :

  • vApp - vApp;

  • org - ;

  • org_vdc - -.

导入vAPP资源属性
vAPP

VM : vcdvappvm.<VM> <org>.<orgvdc>.<vApp>.<VM>, :

  • VM - VM;

  • vApp - vApp;

  • org - ;

  • orgvdc - -.

C:\Users\Mikhail\Desktop\terraform>terraform import vcd_vapp_vm.Zabbix mClouds.mClouds.Monitoring.Zabbix

vcd_vapp_vm.Zabbix: Importing from ID "mClouds.mClouds.Monitoring.Zabbix"...

vcd_vapp_vm.Zabbix: Import prepared!

Prepared vcd_vapp_vm for import

vcd_vapp_vm.Zabbix: Refreshing state... [id=urn:vcloud:vm:778f4a89-1c8d-45b9-9d94-0472a71c4d1f]

Import successful!

The resources that were imported are shown above. These resources are now in your Terraform state and will henceforth be managed by Terraform.

:

> terraform show

...

# vcd_vapp.Monitoring:

resource "vcd_vapp" "Monitoring" {

guest_properties = {}

href = "https://vcloud.mclouds.ru/api/vApp/vapp-fe5db285-a4af-47c4-93e8-55df92f006ec"

id = "urn:vcloud:vapp:fe5db285-a4af-47c4-93e8-55df92f006ec"

ip = "allocated"

metadata = {}

name = "Monitoring"

org = "mClouds"

status = 4

status_text = "POWERED_ON"

vdc = "mClouds"

}

# vcd_vapp_vm.Zabbix:

resource "vcd_vapp_vm" "Zabbix" {

computer_name = "Zabbix"

cpu_cores = 1

cpus = 2

expose_hardware_virtualization = false

guest_properties = {}

hardware_version = "vmx-14"

href = "https://vcloud.mclouds.ru/api/vApp/vm-778f4a89-1c8d-45b9-9d94-0472a71c4d1f"

id = "urn:vcloud:vm:778f4a89-1c8d-45b9-9d94-0472a71c4d1f"

internal_disk = [

{

bus_number = 0

bus_type = "paravirtual"

disk_id = "2000"

iops = 0

size_in_mb = 122880

storage_profile = "Gold Storage Policy"

thin_provisioned = true

unit_number = 0

},

]

memory = 8192

metadata = {}

name = "Zabbix"

org = "mClouds"

os_type = "centos8_64Guest"

storage_profile = "Gold Storage Policy"

vapp_name = "Monitoring"

vdc = "mClouds"

customization {

allow_local_admin_password = true

auto_generate_password = true

change_sid = false

enabled = false

force = false

join_domain = false

join_org_domain = false

must_change_password_on_first_login = false

number_of_auto_logons = 0

}

network {

adapter_type = "VMXNET3"

ip_allocation_mode = "DHCP"

is_primary = true

mac = "00:50:56:07:01:b1"

name = "MCLOUDS-LAN01"

type = "org"

}

}

- ( )   Terraform. 

, .

, , , . , .




All Articles