Terraform操作Openstack

公孙宇
2023-12-01

Terraform

Terraform 常用命令:

terraform init  #initialize a folder which contains *.tf files
terraform plan  #check what actions will be performed
terraform apply #perform actions
terraform destroy   #delete the resources defined in *.tf files
terraform destroy -target=xxx   #delete a single resource
terraform state list    #show what have been done
terraform state show <list-id>    #show details of what have been done

Provider

Username/Password

provider "openstack" {
  user_name   = "admin"
  tenant_name = "admin"
  user_domain_name = "default"
  project_domain_name = "default"
  region      = "RegionOne"
  auth_url    = "http://10.192.22.6:5000/v3"
  password= "xxxxxxxxxxxxxx"
}

Vault Role and Secret

variable "vault_role_id" {
  default    = "d2a8215f-04bd-c714-c0ee-9c23ecd56d14-xxx"   #delete '-xxx'
}
 
variable "vault_secret_id" {
  default    = "9ece2a12-f153-73eb-a448-51f88235c3a8-xxx"   #delete '-xxx'
}
 
provider "null" {
}
 
provider "vault" {
  address = "http://10.198.15.247:8200"
  auth_login {
    path = "auth/approle/login"
    parameters = {
      role_id = "d2a8215f-04bd-c714-c0ee-9c23ecd56d14"
      secret_id = "9ece2a12-f153-73eb-a448-51f88235c3a8"
    }
  }
}
 
data "vault_generic_secret" "cvim_creds" {
  path = "everest/neteng/cvim_creds"
}
 
data "vault_generic_secret" "cvim_oracle_creds" {
  path = "everest/neteng/cvim_configs/cvim_oracle_creds"
}
 
data "vault_generic_secret" "certs" {
  path = "everest/neteng/certs"
}
 
provider "openstack" {
  user_name   = "${data.vault_generic_secret.cvim_creds.data["os_username"]}"
  tenant_name = "${data.vault_generic_secret.cvim_creds.data["os_tenant_name"]}"
  user_domain_name = "${data.vault_generic_secret.cvim_creds.data["os_user_domain_name"]}"
  project_domain_name = "${data.vault_generic_secret.cvim_creds.data["os_project_domain_name"]}"
  region      = "${data.vault_generic_secret.cvim_creds.data["os_region_name"]}"
  auth_url    = "${data.vault_generic_secret.cvim_creds.data["os_auth_url"]}"
}

Identity

Create User

resource "openstack_identity_user_v3" "alexju_terraform" {
  default_project_id = "e75f662a7a7a457e8742f6bd4cc2e31c"
  for_each={
    user1 = "terraform_user1"
    user2 = "terraform_user2"
  }
  name               = each.value
  description        = "A user created by terraform"
  password = "ju000000"
  ignore_change_password_upon_first_use = true
  multi_factor_auth_enabled = true
  multi_factor_auth_rule {
    rule = ["password", "totp"]
  }
  multi_factor_auth_rule {
    rule = ["password"]
  }
  extra = {
    email = "alexju@foobar.com"
  }
}

Instance

Create Flavor

resource "openstack_compute_flavor_v2" "test-flavor" {
  name  = "terraform-test"
  ram   = "8096"
  vcpus = "2"
  disk  = "20"
  is_public = true
  extra_specs = {
    "capabilities:hypervisor_type" = "s!= ironic"
  }
}

Create Instance without volume

resource "openstack_compute_instance_v2" "terraform-test01" {
  name  = "terraform-test01"
  image_name        = "CirrOS 0.5.0 test"
  flavor_name       = "generic-tiny"
  availability_zone = "Normal-IO"
  key_pair        = "alexju-new"
  security_groups = ["Allow_All_Igress"]
  metadata = {
    this = "that"
  }
  network {
    name = "PROVIDER-NETWORK"
  }
}

Create Instance, Create Volume, and Attach Volume as a Block Device

resource "openstack_compute_instance_v2" "terraform-test02" {
  name  = "terraform-test02"
  image_name        = "CirrOS 0.5.0 test"
  flavor_name       = "generic-tiny"
  availability_zone = "Normal-IO"
  key_pair        = "alexju-new"
  security_groups = ["Allow_All_Igress"]
  metadata = {
    this = "that"
  }
  network {
    name = "PROVIDER-NETWORK"
  }
  block_device {
    uuid                  = "76ad48fa-9431-4ef6-9163-9479d515f3e9"
    source_type           = "image"
    destination_type      = "local"
    boot_index            = 0
    delete_on_termination = true
  }
 
  block_device {
    source_type           = "blank"
    destination_type      = "volume"
    volume_size           = 20
    boot_index            = 1
    delete_on_termination = true
  }
}

Provisioner

resource "openstack_compute_instance_v2" "terraform-test03" {
  name  = "terraform-test03"
  image_name        = "CirrOS 0.5.0 test"
  flavor_name       = "generic-tiny"
  availability_zone = "Normal-IO"
  key_pair        = "alexju-new"
  security_groups = ["Allow_All_Igress"]
  metadata = {
    this = "that"
  }
  network {
    name = "PROVIDER-NETWORK"
  }
  block_device {
    uuid                  = "76ad48fa-9431-4ef6-9163-9479d515f3e9"
    source_type           = "image"
    destination_type      = "local"
    boot_index            = 0
    delete_on_termination = true
  }
 
  block_device {
    source_type           = "blank"
    destination_type      = "volume"
    volume_size           = 20
    boot_index            = 1
    delete_on_termination = true
  }
 
  provisioner "file" {
      connection {
          type        = "ssh"
          user        = "cirros"
          password = "gocubsgo"
          host = "${openstack_compute_instance_v2.terraform-test03.access_ip_v4}"
      }
 
      source      = "test.txt"
      destination = "/home/cirros/ha.txt"
  }
 
  provisioner "local-exec" {
    command = "echo ${openstack_compute_instance_v2.terraform-test03.access_ip_v4} >> access_ip_v4.txt"
  }
 
  provisioner "remote-exec" {
      connection {
          type        = "ssh"
          user        = "cirros"
          password = "gocubsgo"
          host = "${openstack_compute_instance_v2.terraform-test03.access_ip_v4}"
      }
      inline = [
      "chmod a+x /tmp/*.sh",
      "cat /home/cirros/ha.txt"
      ]
  }
}

Unexpected:

Error: Failed to upload script: Error chmodding script file to 0777 in remote machine error executing “chmod 0777 /tmp/terraform_1780501774.sh”: Process exited with status 129 from signal HUP:

Network

Create Security Group, Rules

resource "openstack_networking_secgroup_v2" "terraform_test01" {
  name        = "terraform_test01"
  description = "My neutron security group"
}
 
resource "openstack_networking_secgroup_rule_v2" "secgroup_rule_22" {
  direction         = "ingress"
  ethertype         = "IPv4"
  protocol          = "tcp"
  port_range_min    = 22
  port_range_max    = 22
  remote_ip_prefix  = "0.0.0.0/0"
  security_group_id = "${openstack_networking_secgroup_v2.terraform_test01.id}"
}

Create Load Balancer, Listener, Pool, Member, Health monitor

data "openstack_networking_subnet_v2" "provider_network_subnet" {
  name = "provider-network-subnet"
}
 
#Add loadbalancer
resource "openstack_lb_loadbalancer_v2" "terraform_lb" {
  name = "terraform_lb"
  vip_subnet_id = "${data.openstack_networking_subnet_v2.provider_network_subnet.id}"
}
 
#Add listener
resource "openstack_lb_listener_v2" "terraform_listener" {
  name = "terraform_listener"
  protocol        = "HTTP"
  protocol_port   = 8080
  loadbalancer_id = "${openstack_lb_loadbalancer_v2.terraform_lb.id}"
 
  insert_headers = {
    X-Forwarded-For = "true"
  }
}
 
#Add Pool
resource "openstack_lb_pool_v2" "terraform_pool" {
  name = "terraform_pool"
  protocol    = "HTTP"
  lb_method   = "ROUND_ROBIN"
  listener_id = "${openstack_lb_listener_v2.terraform_listener.id}"
 
  persistence {
    type        = "APP_COOKIE"
    cookie_name = "testCookie"
  }
}
 
#Add member
resource "openstack_lb_member_v2" "terraform_member1" {
  name = "member1"
  pool_id     = "${openstack_lb_pool_v2.terraform_pool.id}"
  subnet_id = "${data.openstack_networking_subnet_v2.provider_network_subnet.id}"
  address       = "10.192.26.61"
  protocol_port = 8080
}
resource "openstack_lb_member_v2" "terraform_member2" {
  name = "member2"
  pool_id     = "${openstack_lb_pool_v2.terraform_pool.id}"
  subnet_id = "${data.openstack_networking_subnet_v2.provider_network_subnet.id}"
  address       = "10.192.26.57"
  protocol_port = 8080
}
 
#Add health monitor
resource "openstack_lb_monitor_v2" "terraform_monitor" {
  name = "terraform_monitor"
  pool_id     = "${openstack_lb_pool_v2.terraform_pool.id}"
  type        = "TCP"
  delay       = 20
  timeout     = 10
  max_retries = 5
}

Unexpected: member name is still not a human-readable name.

Storage

Create a Volume and attach to Instance

resource "openstack_blockstorage_volume_v2" "test" {
  region      = "RegionOne"
  name        = "tf-test"
  description = "first test volume"
  size        = 3
}
 
resource "openstack_compute_volume_attach_v2" "va_1" {
  instance_id = "18d32680-6fc0-42d1-bd06-ec56e8f6deee"
  volume_id   = "${openstack_blockstorage_volume_v2.test.id}"
}

Image

Create a Image

resource "openstack_images_image_v2" "CirrOS_0_5_1" {
  name             = "CirrOS 0.5.1"
  image_source_url = "http://download.cirros-cloud.net/0.5.1/cirros-0.5.1-x86_64-disk.img"
  container_format = "bare"
  disk_format      = "qcow2"
  visibility       = "public"
 
  properties = {
    description = "CirrOS is a Tiny OS that specializes in running on a cloud"
    original_source_url = "http://download.cirros-cloud.net/0.5.1/cirros-0.5.1-x86_64-disk.img"
    username = "cirros"
    password = "gocubsgo"
  }
}
 类似资料: