anthos-bm-openstack-terraform/main.tf (189 lines of code) (raw):

/** * Copyright 2021 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ locals { abm_name_template = "abm-%s" subnet_cidr_prefix = "10.200.0.%s" dns_servers = ["8.8.8.8", "8.8.4.4"] vm_name_template = "${local.abm_name_template}%d" cloud_config_path = "${path.module}/resources/cloud-config.yaml" subnet_cidr = format(local.subnet_cidr_prefix, "0/24") // 10.200.0.0/24 subnet_start_ip = format(local.subnet_cidr_prefix, "3") // 10.200.0.3 subnet_end_ip = format(local.subnet_cidr_prefix, "100") // 10.200.0.100 controlplane_lb_vip = format(local.subnet_cidr_prefix, "101") // 10.200.0.101 router_name = format(local.abm_name_template, "router") network_name = format(local.abm_name_template, "network") subnetwork_name = format(local.abm_name_template, "subnetwork") controlplane_lb_name = format(local.abm_name_template, "cp-lb") admin_vm_names = [format(local.vm_name_template, "ws", 0)] controlplane_vm_names = [for i in range(var.instance_count.controlplane) : format(local.vm_name_template, "cp", i + 1)] worker_vm_names = [for i in range(var.instance_count.worker) : format(local.vm_name_template, "w", i + 1)] admin_ip_start = 10 controlplane_ip_start = local.admin_ip_start + length(local.admin_vm_names) worker_ip_start = local.controlplane_ip_start + length(local.controlplane_vm_names) admin_vm_info = [ for idx, vmName in local.admin_vm_names : { name : vmName, ip : format(local.subnet_cidr_prefix, local.admin_ip_start + idx) } ] controlplane_vm_info = [ for idx, vmName in local.controlplane_vm_names : { name : vmName, ip : format(local.subnet_cidr_prefix, local.controlplane_ip_start + idx) } ] worker_vm_info = [ for idx, vmName in local.worker_vm_names : { name : vmName, ip : format(local.subnet_cidr_prefix, local.worker_ip_start + idx) } ] } ############################################################################### # Create the OpenStack network setup for Anthos on bare metal hosts # - OpenStack router # - OpenStack network # - OpenStack subnet # - Roter interface on the subnet ############################################################################### resource "openstack_networking_router_v2" "abm_network_router" { name = local.router_name external_network_id = var.external_network_id admin_state_up = true } resource "openstack_networking_network_v2" "abm_network" { name = local.network_name mtu = var.network_mtu admin_state_up = "true" } resource "openstack_networking_subnet_v2" "abm_subnetwork" { name = local.subnetwork_name cidr = local.subnet_cidr network_id = openstack_networking_network_v2.abm_network.id dns_nameservers = local.dns_servers allocation_pool { start = local.subnet_start_ip end = local.subnet_end_ip } ip_version = 4 } resource "openstack_networking_router_interface_v2" "abm_interface_1" { router_id = openstack_networking_router_v2.abm_network_router.id subnet_id = openstack_networking_subnet_v2.abm_subnetwork.id } ############################################################################### # Create the control plane loadbalancer for the Anthos on bare metal setup # - LoadBalancer (based on LBaaS v2, i.e: Octavia) # - LoadBalancer Listener # - LoadBalancer Pool # - LoadBalancer Monitor # - LoadBalancer Members (one each for controlplane nodes) ############################################################################### resource "openstack_lb_loadbalancer_v2" "abm_cp_lb" { name = local.controlplane_lb_name vip_address = local.controlplane_lb_vip vip_subnet_id = openstack_networking_subnet_v2.abm_subnetwork.id } resource "openstack_lb_listener_v2" "abm_cp_lb_listener" { protocol = "HTTPS" protocol_port = 443 loadbalancer_id = openstack_lb_loadbalancer_v2.abm_cp_lb.id } resource "openstack_lb_pool_v2" "abm_cp_lb_pool" { protocol = "HTTPS" lb_method = var.lb_method listener_id = openstack_lb_listener_v2.abm_cp_lb_listener.id } resource "openstack_lb_monitor_v2" "abm_cp_lb_monitor" { pool_id = openstack_lb_pool_v2.abm_cp_lb_pool.id type = "HTTPS" delay = 5 timeout = 5 max_retries = 5 url_path = "/readyz" } resource "openstack_lb_member_v2" "lb_membership_cp_nodes" { for_each = { for index, vm in local.controlplane_vm_info : index => vm } pool_id = openstack_lb_pool_v2.abm_cp_lb_pool.id address = each.value.ip protocol_port = 6444 } ############################################################################### # Create security groups for configuring access for the Anthos BareMeal hosts # - Allow TCP port 443 for HTTPS traffic # - Allow TCP port 22 for SSH traffic # - Allow all ICMP traffic ############################################################################### resource "openstack_compute_secgroup_v2" "basic_access" { name = "basic_access" description = "Allow HTTPS(443), SSH(22) and ICMP" rule { from_port = 22 to_port = 22 ip_protocol = "tcp" cidr = "0.0.0.0/0" } rule { from_port = 443 to_port = 443 ip_protocol = "tcp" cidr = "0.0.0.0/0" } rule { from_port = -1 to_port = -1 ip_protocol = "icmp" cidr = "0.0.0.0/0" } } ############################################################################### # Create public-private key pair for use by the Anthos on bare metal hosts ############################################################################### resource "tls_private_key" "abm_key" { algorithm = "RSA" rsa_bits = 4096 } ############################################################################### # Generate the cloud-init configuration by filling in the templated details # in the cloud-config file ############################################################################### data "template_file" "cloud_config" { template = file(local.cloud_config_path) vars = { private_key = tls_private_key.abm_key.private_key_pem, public_key = tls_private_key.abm_key.public_key_openssh } } ############################################################################### # Create the VMs for the Anthos on bare metal setup # - 1 VM for the Admin workstation # - VMs for the Controlplane based on the input variable 'instance_count' # - VMs for the worker nodes based on the input variable 'instance_count' ############################################################################### module "admin_vm_hosts" { source = "./modules/vm" vm_info = local.admin_vm_info image = var.image flavor = var.machine_type key = var.ssh_key_name network = openstack_networking_network_v2.abm_network.id user_data = data.template_file.cloud_config.rendered security_groups = ["default", openstack_compute_secgroup_v2.basic_access.name] } module "cp_vm_hosts" { source = "./modules/vm" vm_info = local.controlplane_vm_info image = var.image flavor = var.machine_type key = var.ssh_key_name network = openstack_networking_network_v2.abm_network.id user_data = data.template_file.cloud_config.rendered security_groups = ["default", openstack_compute_secgroup_v2.basic_access.name] } module "worker_vm_hosts" { source = "./modules/vm" vm_info = local.worker_vm_info image = var.image flavor = var.machine_type key = var.ssh_key_name network = openstack_networking_network_v2.abm_network.id user_data = data.template_file.cloud_config.rendered security_groups = ["default", openstack_compute_secgroup_v2.basic_access.name] } ############################################################################### # Associate floating virtual IPs for the control plane and admin workstation ############################################################################### resource "openstack_networking_floatingip_v2" "abm_ws_floatingip" { pool = "public" tags = ["abm_ws_floatingip"] description = "abm_ws_floatingip" } resource "openstack_networking_floatingip_v2" "abm_cp_floatingip" { pool = "public" tags = ["abm_cp_floatingip"] description = "abm_cp_floatingip" } resource "openstack_networking_floatingip_associate_v2" "abm_cp_ip_lb_association" { floating_ip = openstack_networking_floatingip_v2.abm_cp_floatingip.address port_id = openstack_lb_loadbalancer_v2.abm_cp_lb.vip_port_id } resource "openstack_compute_floatingip_associate_v2" "abm_ws_ip_lb_association" { floating_ip = openstack_networking_floatingip_v2.abm_ws_floatingip.address instance_id = module.admin_vm_hosts.vm_ids[0] }