From 8ade749c4c8dd0358b05cebac36355d8ec8777a8 Mon Sep 17 00:00:00 2001 From: Hendrik Frenzel Date: Tue, 25 Aug 2020 13:18:26 +0200 Subject: [PATCH 1/6] Initial OpenStack Support --- .github/workflows/terraform.yml | 2 +- README.md | 2 +- openstack/README.md | 172 +++++++++ .../files/userdata_quickstart_node.template | 10 + openstack/infra.tf | 331 ++++++++++++++++++ openstack/output.tf | 11 + openstack/provider.tf | 30 ++ openstack/terraform.tfvars.example | 110 ++++++ openstack/variables.tf | 198 +++++++++++ openstack/versions.tf | 20 ++ test/e2e_test.go | 4 + 11 files changed, 888 insertions(+), 2 deletions(-) create mode 100644 openstack/README.md create mode 100644 openstack/files/userdata_quickstart_node.template create mode 100644 openstack/infra.tf create mode 100644 openstack/output.tf create mode 100644 openstack/provider.tf create mode 100644 openstack/terraform.tfvars.example create mode 100644 openstack/variables.tf create mode 100644 openstack/versions.tf diff --git a/.github/workflows/terraform.yml b/.github/workflows/terraform.yml index 0647b0b1..1ca37747 100644 --- a/.github/workflows/terraform.yml +++ b/.github/workflows/terraform.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - provider: ['aws', 'azure', 'azure-windows', 'do', 'gcp'] + provider: ['aws', 'azure', 'azure-windows', 'do', 'gcp', 'openstack'] # Use the Bash shell regardless whether the GitHub Actions runner is ubuntu-latest, macos-latest, or windows-latest defaults: diff --git a/README.md b/README.md index 5a1dc468..b054a943 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ See [/vagrant](./vagrant) for details on usage and settings. ## Cloud quickstart -Quickstarts are provided for [**Amazon Web Services** (`aws`)](./aws), [**Microsoft Azure Cloud** (`azure`)](./azure), [**Microsoft Azure Cloud with Windows nodes** (`azure-windows`)](./azure-windows), [**DigitalOcean** (`do`)](./do), and [**Google Cloud Platform** (`gcp`)](./gcp). +Quickstarts are provided for [**Amazon Web Services** (`aws`)](./aws), [**Microsoft Azure Cloud** (`azure`)](./azure), [**Microsoft Azure Cloud with Windows nodes** (`azure-windows`)](./azure-windows), [**DigitalOcean** (`do`)](./do), [**Google Cloud Platform** (`gcp`)](./gcp) and [**OpenStack** (`openstack`)](./openstack). **You will be responsible for any and all infrastructure costs incurred by these resources.** diff --git a/openstack/README.md b/openstack/README.md new file mode 100644 index 00000000..e3e137b2 --- /dev/null +++ b/openstack/README.md @@ -0,0 +1,172 @@ +# OpenStack Rancher Quickstart + +Two single-node RKE Kubernetes clusters will be created from two linux virtual instances running Ubuntu 18.04 and Docker. +Both instances will have wide-open security groups and will be accessible over SSH using the SSH keys +`id_rsa` and `id_rsa.pub`. + +## Variables + +###### `openstack_floating_ip_pool` +- **Required** +The name of the pool from which to obtain the floating IPs + +###### `openstack_auth_url` +- **Optional**; required if `openstack_cloud` is not specified. +The OpenStack Identity authentication URL. +If omitted, the `OS_AUTH_URL` environment variable is used. + +###### `openstack_cloud` +- **Optional**; required if `openstack_auth_url` is not specified. +An entry in a `clouds.yaml` file. +See the OpenStack openstacksdk documentation for more information about clouds.yaml files. +If omitted, the `OS_CLOUD` environment variable is used. + +###### `openstack_region` +- **Optional** +The region of the OpenStack cloud to use. +If omitted, the `OS_REGION_NAME` environment variable is used. + +###### `openstack_user_name` +- **Optional** +The Username to login with. +f omitted, the `OS_USERNAME` environment variable is used. + +###### `openstack_project_name` +- **Optional** +The Name of the Project. +If omitted, the `OS_TENANT_ID` or `OS_PROJECT_ID` environment variables are used. + +###### `openstack_password` +- **Optional** +The Password to login with. +If omitted, the `OS_PASSWORD` environment variable is used. + +###### `openstack_domain_name` +- **Optional** +The Name of the Domain to scope to. +If omitted, the `OS_DOMAIN_NAME` environment variable is used. + +###### `openstack_user_id` +- **Optional** +The User ID to login with. +If omitted, the `OS_USER_ID` environment variable is checked. + +###### `openstack_application_credential_id` +- **Optional** +The ID of an application credential to authenticate with. +An `openstack_application_credential_secret` has to bet set along with this parameter. + +###### `openstack_application_credential_name` +- **Optional** +The name of an application credential to authenticate with. +Requires `openstack_user_id`, or `openstack_user_name` and `openstack_user_domain_name` (or `openstack_user_domain_id`) to be set. + +###### `openstack_application_credential_secret` +- **Optional** +The secret of an application credential to authenticate with. +Required by `openstack_application_credential_id` or `openstack_application_credential_name`. + +###### `openstack_project_id` +- **Optional** +The ID of the Project to login with. +If omitted, the `OS_TENANT_ID` or `OS_PROJECT_ID` environment variables are used. + +###### `openstack_token` +- **Optional** +The auth token to login with. +A token is an expiring, temporary means of access issued via the Keystone service. +If omitted, the `OS_TOKEN` or `OS_AUTH_TOKEN` environment variables are used. + +###### `openstack_user_domain_name` +- **Optional** +The domain name where the user is located. +If omitted, the `OS_USER_DOMAIN_NAME` environment variable is checked. + +###### `openstack_user_domain_id` +- **Optional** +The domain ID where the user is located. +If omitted, the `OS_USER_DOMAIN_ID` environment variable is checked. + +###### `openstack_project_domain_name` +- **Optional** +The domain name where the project is located. +If omitted, the `OS_PROJECT_DOMAIN_NAME` environment variable is checked. + +###### `openstack_project_domain_id` +- **Optional** +The domain ID where the project is located. +If omitted, the `OS_PROJECT_DOMAIN_ID` environment variable is checked. + +###### `openstack_domain_id` +- **Optional** +The Name of the Domain to scope to. +If omitted, the `OS_DOMAIN_ID` environment variable is checked. + +###### `openstack_insecure` +- **Optional** +Trust self-signed SSL certificates. +If omitted, the `OS_INSECURE` environment variable is used. + +###### `openstack_cacert_file` +- **Optional** +Specify a custom CA certificate when communicating over SSL. +You can specify either a path to the file or the contents of the certificate. +If omitted, the `OS_CACERT` environment variable is used. + +###### `openstack_cert` +- **Optional** +Specify client certificate file for SSL client authentication. +You can specify either a path to the file or the contents of the certificate. +If omitted the `OS_CERT` environment variable is used. + +###### `openstack_key` +- **Optional** +Specify client private key file for SSL client authentication. +You can specify either a path to the file or the contents of the key. +If omitted the `OS_KEY` environment variable is used. + +###### `prefix` +- Default: **`"quickstart"`** +Prefix added to names of all resources + +###### `instance_type` +- Default: **`"m1.large"`** +Instance type used for all linux virtual instances + +###### `docker_version` +- Default: **`"19.03"`** +Docker version to install on nodes + +###### `rke_kubernetes_version` +- Default: **`"v1.18.3-rancher2-2"`** +Kubernetes version to use for Rancher server RKE cluster + +See `rancher-common` module variable `rke_kubernetes_version` for more details. + +###### `workload_kubernetes_version` +- Default: **`"v1.17.6-rancher2-2"`** +Kubernetes version to use for managed workload cluster + +See `rancher-common` module variable `workload_kubernetes_version` for more details. + +###### `cert_manager_version` +- Default: **`"0.12.0"`** +Version of cert-mananger to install alongside Rancher (format: 0.0.0) + +See `rancher-common` module variable `cert_manager_version` for more details. + +###### `rancher_version` +- Default: **`"v2.4.5"`** +Rancher server version (format v0.0.0) + +See `rancher-common` module variable `rancher_version` for more details. + +###### `rancher_server_admin_password` +- **Required** +Admin password to use for Rancher server bootstrap + +See `rancher-common` module variable `admin_password` for more details. + +###### `network_cidr` +- Default: **`"10.0.0.0/16"`** +The Network CIDR for the Rancher nodes diff --git a/openstack/files/userdata_quickstart_node.template b/openstack/files/userdata_quickstart_node.template new file mode 100644 index 00000000..2af9f1f9 --- /dev/null +++ b/openstack/files/userdata_quickstart_node.template @@ -0,0 +1,10 @@ +#!/bin/bash -x + +export DEBIAN_FRONTEND=noninteractive +curl -sL https://releases.rancher.com/install-docker/${docker_version}.sh | sh +sudo usermod -aG docker ${username} + +publicIP=$(curl -H "Metadata: true" http://169.254.169.254/latest/meta-data/public-ipv4) +privateIP=$(curl -H "Metadata: true" http://169.254.169.254/latest/meta-data/local-ipv4) + +${register_command} --address $publicIP --internal-address $privateIP --etcd --controlplane --worker diff --git a/openstack/infra.tf b/openstack/infra.tf new file mode 100644 index 00000000..838161e9 --- /dev/null +++ b/openstack/infra.tf @@ -0,0 +1,331 @@ +# OpenStack Infrastructure Resources + +resource "tls_private_key" "global_key" { + algorithm = "RSA" + rsa_bits = 2048 +} + +resource "local_file" "ssh_private_key_pem" { + filename = "${path.module}/id_rsa" + sensitive_content = tls_private_key.global_key.private_key_pem + file_permission = "0600" +} + +resource "local_file" "ssh_public_key_openssh" { + filename = "${path.module}/id_rsa.pub" + content = tls_private_key.global_key.public_key_openssh +} + +# Upload Ubuntu image +resource "openstack_images_image_v2" "rancher-ubuntu-image" { + name = "${var.prefix}-ubuntu-image" + image_source_url = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img" + container_format = "bare" + disk_format = "qcow2" + min_ram_mb = 4096 + min_disk_gb = 25 + visibility = "private" + + properties = { + os_type = "linux" + os_distro = "ubuntu" + os_version = "18.04-LTS" + } + + tags = ["rancher-quickstart"] +} + +# Upload SSH keypair +resource "openstack_compute_keypair_v2" "rancher-keypair" { + name = "${var.prefix}-rancher-keypair" + public_key = tls_private_key.global_key.public_key_openssh +} + +# OpenStack virtual network for quickstart resources +resource "openstack_networking_network_v2" "rancher-quickstart" { + name = "${var.prefix}-network" + + tags = ["rancher-quickstart"] +} + +# OpenStack internal subnet for quickstart resources +resource "openstack_networking_subnet_v2" "rancher-quickstart-internal" { + name = "rancher-quickstart-internal" + network_id = openstack_networking_network_v2.rancher-quickstart.id + cidr = var.network_cidr + + tags = ["rancher-quickstart"] +} + +# Get floating IP network +data "openstack_networking_network_v2" "rancher-quickstart-external" { + name = var.openstack_floating_ip_pool +} + +# OpenStack router to connect the internal subnet to the floating IP network +resource "openstack_networking_router_v2" "rancher-quickstart-router" { + name = "${var.prefix}-rancher-router" + external_network_id = data.openstack_networking_network_v2.rancher-quickstart-external.id + + tags = ["rancher-quickstart"] +} + +# OpenStack router interface to the internal subnet +resource "openstack_networking_router_interface_v2" "rancher-quickstart-router-interface" { + router_id = openstack_networking_router_v2.rancher-quickstart-router.id + subnet_id = openstack_networking_subnet_v2.rancher-quickstart-internal.id +} + +# Floating IP of Rancher server +resource "openstack_networking_floatingip_v2" "rancher-server-pip" { + pool = var.openstack_floating_ip_pool + + tags = ["rancher-quickstart"] +} + +# OpenStack network interface for quickstart resources +resource "openstack_networking_port_v2" "rancher-server-interface" { + name = "rancher-quickstart-interface" + network_id = openstack_networking_network_v2.rancher-quickstart.id + + fixed_ip { + subnet_id = openstack_networking_subnet_v2.rancher-quickstart-internal.id + } + + tags = ["rancher-quickstart"] +} + +# Associate Rancher server floating IP with the Rancher server port +resource "openstack_networking_floatingip_associate_v2" "rancher-server-pip-associate" { + floating_ip = openstack_networking_floatingip_v2.rancher-server-pip.address + port_id = openstack_networking_port_v2.rancher-server-interface.id +} + +# OpenStack security group +resource "openstack_networking_secgroup_v2" "rancher-quickstart-secgroup" { + name = "${var.prefix}-rancher-secgroup" +} + +# OpenStack security group rules +resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-ssh" { + 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.rancher-quickstart-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-http" { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 80 + port_range_max = 80 + remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-https" { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 443 + port_range_max = 443 + remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-kubeapi" { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 6443 + port_range_max = 6443 + remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-docker" { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 2376 + port_range_max = 2376 + remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-self-v4" { + direction = "ingress" + ethertype = "IPv4" + remote_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id + security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-self-v6" { + direction = "ingress" + ethertype = "IPv6" + remote_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id + security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id +} + +# Associate security group to Rancher server port +resource "openstack_networking_port_secgroup_associate_v2" "rancher-server-interface-secgroup" { + port_id = openstack_networking_port_v2.rancher-server-interface.id + security_group_ids = [openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id] +} + +# Create CloudInit / User-Data for Rancher server +data "cloudinit_config" "rancher-server-cloudinit" { + part { + content_type = "text/x-shellscript" + content = templatefile( + join("/", [path.module, "../cloud-common/files/userdata_rancher_server.template"]), + { + docker_version = var.docker_version + username = local.node_username + } + ) + } +} + +# OpenStack instance for creating a single node RKE cluster and installing the Rancher Server +resource "openstack_compute_instance_v2" "rancher_server" { + name = "${var.prefix}-rancher-server" + flavor_name = var.instance_type + key_pair = openstack_compute_keypair_v2.rancher-keypair.name + user_data = data.cloudinit_config.rancher-server-cloudinit.rendered + + network { + port = openstack_networking_port_v2.rancher-server-interface.id + } + + block_device { + uuid = openstack_images_image_v2.rancher-ubuntu-image.id + source_type = "image" + volume_size = 25 + boot_index = 0 + destination_type = "volume" + delete_on_termination = true + } + + provisioner "remote-exec" { + inline = [ + "echo 'Waiting for cloud-init to complete...'", + "cloud-init status --wait > /dev/null", + "echo 'Completed cloud-init!'", + ] + + connection { + type = "ssh" + host = openstack_networking_floatingip_v2.rancher-server-pip.address + user = local.node_username + private_key = tls_private_key.global_key.private_key_pem + } + } + + tags = ["rancher-quickstart"] + +} + +# Rancher resources +module "rancher_common" { + source = "../rancher-common" + + node_public_ip = openstack_networking_floatingip_v2.rancher-server-pip.address + node_internal_ip = openstack_compute_instance_v2.rancher_server.access_ip_v4 + node_username = local.node_username + ssh_private_key_pem = tls_private_key.global_key.private_key_pem + rke_kubernetes_version = var.rke_kubernetes_version + + cert_manager_version = var.cert_manager_version + rancher_version = var.rancher_version + + rancher_server_dns = join(".", ["rancher", openstack_networking_floatingip_v2.rancher-server-pip.address, "xip.io"]) + + admin_password = var.rancher_server_admin_password + + workload_kubernetes_version = var.workload_kubernetes_version + workload_cluster_name = "quickstart-openstack-custom" +} + +# Floating IP of quickstart node +resource "openstack_networking_floatingip_v2" "quickstart-node-pip" { + pool = var.openstack_floating_ip_pool + + tags = ["rancher-quickstart"] +} + +# OpenStack network interface for quickstart resources +resource "openstack_networking_port_v2" "quickstart-node-interface" { + name = "quickstart-node-interface" + network_id = openstack_networking_network_v2.rancher-quickstart.id + + fixed_ip { + subnet_id = openstack_networking_subnet_v2.rancher-quickstart-internal.id + } + + tags = ["rancher-quickstart"] +} + +# Associate Quickstart node floating IP with the Quickstart node port +resource "openstack_networking_floatingip_associate_v2" "quickstart-node-pip-associate" { + floating_ip = openstack_networking_floatingip_v2.quickstart-node-pip.address + port_id = openstack_networking_port_v2.quickstart-node-interface.id +} + +# Create CloudInit / User-Data for Quickstart node +data "cloudinit_config" "quickstart-node-cloudinit" { + part { + content_type = "text/x-shellscript" + content = templatefile( + join("/", [path.module, "files/userdata_quickstart_node.template"]), + { + docker_version = var.docker_version + username = local.node_username + register_command = module.rancher_common.custom_cluster_command + } + ) + } +} + +# OpenStack instance for creating a single node RKE cluster and installing the Rancher Server +resource "openstack_compute_instance_v2" "quickstart-node" { + name = "${var.prefix}-quickstart-node" + flavor_name = var.instance_type + key_pair = openstack_compute_keypair_v2.rancher-keypair.name + user_data = data.cloudinit_config.quickstart-node-cloudinit.rendered + + network { + port = openstack_networking_port_v2.quickstart-node-interface.id + } + + block_device { + uuid = openstack_images_image_v2.rancher-ubuntu-image.id + source_type = "image" + volume_size = 25 + boot_index = 0 + destination_type = "volume" + delete_on_termination = true + } + + provisioner "remote-exec" { + inline = [ + "echo 'Waiting for cloud-init to complete...'", + "cloud-init status --wait > /dev/null", + "echo 'Completed cloud-init!'", + ] + + connection { + type = "ssh" + host = openstack_networking_floatingip_v2.quickstart-node-pip.address + user = local.node_username + private_key = tls_private_key.global_key.private_key_pem + } + } + + tags = ["rancher-quickstart"] + +} diff --git a/openstack/output.tf b/openstack/output.tf new file mode 100644 index 00000000..5bfd53b9 --- /dev/null +++ b/openstack/output.tf @@ -0,0 +1,11 @@ +output "rancher_server_url" { + value = module.rancher_common.rancher_url +} + +output "rancher_node_ip" { + value = openstack_networking_floatingip_v2.rancher-server-pip.address +} + +output "workload_node_ip" { + value = openstack_networking_floatingip_v2.quickstart-node-pip.address +} diff --git a/openstack/provider.tf b/openstack/provider.tf new file mode 100644 index 00000000..a5a53b8f --- /dev/null +++ b/openstack/provider.tf @@ -0,0 +1,30 @@ +provider "openstack" { + auth_url = var.openstack_auth_url + cloud = var.openstack_cloud + region = var.openstack_region + user_name = var.openstack_user_name + tenant_name = var.openstack_project_name + password = var.openstack_password + domain_name = var.openstack_domain_name + user_id = var.openstack_user_id + application_credential_id = var.openstack_application_credential_id + application_credential_name = var.openstack_application_credential_name + application_credential_secret = var.openstack_application_credential_secret + tenant_id = var.openstack_project_id + token = var.openstack_token + user_domain_name = var.openstack_user_domain_name + user_domain_id = var.openstack_user_domain_id + project_domain_name = var.openstack_project_domain_name + project_domain_id = var.openstack_project_domain_id + domain_id = var.openstack_domain_id + insecure = var.openstack_insecure + cacert_file = var.openstack_cacert_file + cert = var.openstack_cert + key = var.openstack_key +} + +provider "tls" { +} + +provider "cloudinit" { +} diff --git a/openstack/terraform.tfvars.example b/openstack/terraform.tfvars.example new file mode 100644 index 00000000..785ccedd --- /dev/null +++ b/openstack/terraform.tfvars.example @@ -0,0 +1,110 @@ +# Required variables +# - Fill in before beginning quickstart +# ========================================================== + +# Floating IP Pool +openstack_floating_ip_pool = "" + +# Password used to log in to the `admin` account on the new Rancher server +rancher_server_admin_password = "" + +# Use either the OS_* environment variables or the following variables +# to authenticate with OpenStack infrastructure. + +# OpenStack entry in a clouds.yaml file +# - Required if openstack_auth_url is not specified +# openstack_cloud = "" + +# OpenStack Identity authentication URL +# - Required if openstack_cloud is not specified +# openstack_auth_url = "" + +# OpenStack Region +# openstack_region = "" + +# OpenStack User Name +# openstack_user_name = "" + +# OpenStack Project Name +# openstack_project_name = "" + +# OpenStack Password +# openstack_password = "" + +# OpenStack Domain Name +# openstack_domain_name = "" + +# OpenStack User ID +# openstack_user_id = "" + +# OpenStack Application Credential ID +# openstack_application_credential_id = "" + +# OpenStack Application Credential Name +# openstack_application_credential_name = "" + +# OpenStack Application Credential Secret +# openstack_application_credential_secret = "" + +# OpenStacl Project ID +# openstack_project_id = "" + +# OpenStack Token +# openstack_token = "" + +# OpenStack User Domain Name +# openstack_user_domain_name = "" + +# OpenStack User Domain ID +# openstack_user_domain_id = "" + +# OpenStack Project Domain Nmae +# openstack_project_domain_name = "" + +# OpenStack Project Domain ID +# openstack_project_domain_id = "" + +# OpenStack Domain ID +# openstack_domain_id = "" + +# OpenStack Insecure +# openstack_insecure = "" + +# OpenStack CACert File +# openstack_cacert_file = "" + +# OpenStack Cert +# openstack_cert = "" + +# OpenStack Key +# openstack_key = "" + +# Optional variables, uncomment to customize the quickstart +# ---------------------------------------------------------- + +# Prefix for all resources created by quickstart +# prefix = "" + +# OpenStack virtual machine instance flavor of all created instances +# instance_type = "" + +# Docker version installed on target hosts +# - Must be a version supported by the Rancher install scripts +# docker_version = "" + +# Kubernetes version used for creating management server cluster +# - Must be supported by RKE terraform provider 1.0.1 +# rke_kubernetes_version = "" + +# Kubernetes version used for creating workload cluster +# - Must be supported by RKE terraform provider 1.0.1 +# workload_kubernetes_version = "" + +# Version of cert-manager to install, used in case of older Rancher versions +# cert_manager_version = "" + +# Version of Rancher to install +# rancher_version = "" + +# Rancher network CIDR +# network_cidr = "" diff --git a/openstack/variables.tf b/openstack/variables.tf new file mode 100644 index 00000000..dd119928 --- /dev/null +++ b/openstack/variables.tf @@ -0,0 +1,198 @@ +# Variables for OpenStack infrastructure module + +variable "openstack_floating_ip_pool" { + type = string + description = "The name of the pool from which to obtain the floating IPs." +} + +variable "openstack_auth_url" { + type = string + description = "The OpenStack Identity authentication URL" + default = null +} + +variable "openstack_cloud" { + type = string + description = "The entry in a clouds.yaml file." + default = null +} + +variable "openstack_region" { + type = string + description = "The region of the OpenStack cloud to use." + default = null +} + +variable "openstack_user_name" { + type = string + description = "The Username to login with." + default = null +} + +variable "openstack_project_name" { + type = string + description = "The Name of the Project." + default = null +} + +variable "openstack_password" { + type = string + description = "The Password to login with." + default = null +} + +variable "openstack_domain_name" { + type = string + description = "The Name of the Domain to scope to." + default = null +} + +variable "openstack_user_id" { + type = string + description = "The User ID to login with." + default = null +} + +variable "openstack_application_credential_id" { + type = string + description = "The ID of an application credential to authenticate with." + default = null +} + +variable "openstack_application_credential_name" { + type = string + description = "The name of an application credential to authenticate with." + default = null +} + +variable "openstack_application_credential_secret" { + type = string + description = "The secret of an application credential to authenticate with." + default = null +} + +variable "openstack_project_id" { + type = string + description = "The ID of the Project to login with." + default = null +} + +variable "openstack_token" { + type = string + description = "The auth token to login with." + default = null +} + +variable "openstack_user_domain_name" { + type = string + description = "The domain name where the user is located." + default = null +} + +variable "openstack_user_domain_id" { + type = string + description = "The domain ID where the user is located." + default = null +} + +variable "openstack_project_domain_name" { + type = string + description = "The domain name where the project is located." + default = null +} + +variable "openstack_project_domain_id" { + type = string + description = "The domain ID where the project is located." + default = null +} + +variable "openstack_domain_id" { + type = string + description = "The Name of the Domain to scope to." + default = null +} + +variable "openstack_insecure" { + type = bool + description = "Trust self-signed SSL certificates." + default = null +} + +variable "openstack_cacert_file" { + type = string + description = "Specify a custom CA certificate when communicating over SSL." + default = null +} + +variable "openstack_cert" { + type = string + description = "Specify client certificate file for SSL client authentication." + default = null +} + +variable "openstack_key" { + type = string + description = "Specify client private key file for SSL client authentication." + default = null +} + +variable "prefix" { + type = string + description = "Prefix added to names of all resources" + default = "quickstart" +} + +variable "instance_type" { + type = string + description = "Instance type used for all linux virtual machines" + default = "m1.large" +} + +variable "docker_version" { + type = string + description = "Docker version to install on nodes" + default = "19.03" +} + +variable "rke_kubernetes_version" { + type = string + description = "Kubernetes version to use for Rancher server RKE cluster" + default = "v1.18.3-rancher2-2" +} + +variable "workload_kubernetes_version" { + type = string + description = "Kubernetes version to use for managed workload cluster" + default = "v1.17.6-rancher2-2" +} + +variable "cert_manager_version" { + type = string + description = "Version of cert-mananger to install alongside Rancher (format: 0.0.0)" + default = "0.12.0" +} + +variable "rancher_version" { + type = string + description = "Rancher server version (format: v0.0.0)" + default = "v2.4.5" +} + +variable "network_cidr" { + type = string + description = "The Network CIDR for the Rancher nodes" + default = "10.0.0.0/16" +} + +# Required +variable "rancher_server_admin_password" { + type = string + description = "Admin password to use for Rancher server bootstrap" +} + + +# Local variables used to reduce repetition +locals { + node_username = "ubuntu" +} diff --git a/openstack/versions.tf b/openstack/versions.tf new file mode 100644 index 00000000..e9ab9576 --- /dev/null +++ b/openstack/versions.tf @@ -0,0 +1,20 @@ +terraform { + required_providers { + openstack = { + source = "terraform-providers/openstack" + version = "1.30.0" + } + local = { + source = "hashicorp/local" + } + tls = { + source = "hashicorp/tls" + version = "2.2.0" + } + cloudinit = { + source = "hashicorp/cloudinit" + version = "1.0.0" + } + } + required_version = ">= 0.13" +} diff --git a/test/e2e_test.go b/test/e2e_test.go index 6ad36d90..f536f8ca 100644 --- a/test/e2e_test.go +++ b/test/e2e_test.go @@ -34,6 +34,10 @@ func TestE2E_Gcp(t *testing.T) { runTerraformAndVerify(t, "../gcp") } +func TestE2E_Openstack(t *testing.T) { + runTerraformAndVerify(t, "../openstack") +} + func runTerraformAndVerify(t *testing.T, terraformDir string) { t.Parallel() From 0ea2513abd49074c4fa0e239ea3b7a94b7be4769 Mon Sep 17 00:00:00 2001 From: Hendrik Frenzel Date: Fri, 28 Aug 2020 15:48:13 +0200 Subject: [PATCH 2/6] Updated versions --- openstack/variables.tf | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/openstack/variables.tf b/openstack/variables.tf index dd119928..507859d2 100644 --- a/openstack/variables.tf +++ b/openstack/variables.tf @@ -158,25 +158,25 @@ variable "docker_version" { variable "rke_kubernetes_version" { type = string description = "Kubernetes version to use for Rancher server RKE cluster" - default = "v1.18.3-rancher2-2" + default = "v1.18.6-rancher1-1" } variable "workload_kubernetes_version" { type = string description = "Kubernetes version to use for managed workload cluster" - default = "v1.17.6-rancher2-2" + default = "v1.17.9-rancher1-1" } variable "cert_manager_version" { type = string description = "Version of cert-mananger to install alongside Rancher (format: 0.0.0)" - default = "0.12.0" + default = "0.15.1" } variable "rancher_version" { type = string description = "Rancher server version (format: v0.0.0)" - default = "v2.4.5" + default = "v2.4.6" } variable "network_cidr" { From 6f013fc233638b66995c2fb76ceb624a7f25521f Mon Sep 17 00:00:00 2001 From: Hendrik Frenzel Date: Tue, 1 Sep 2020 14:02:58 +0200 Subject: [PATCH 3/6] Fixed resource names --- openstack/infra.tf | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openstack/infra.tf b/openstack/infra.tf index 838161e9..79186135 100644 --- a/openstack/infra.tf +++ b/openstack/infra.tf @@ -18,7 +18,7 @@ resource "local_file" "ssh_public_key_openssh" { # Upload Ubuntu image resource "openstack_images_image_v2" "rancher-ubuntu-image" { - name = "${var.prefix}-ubuntu-image" + name = "${var.prefix}-rancher-ubuntu-image" image_source_url = "https://cloud-images.ubuntu.com/bionic/current/bionic-server-cloudimg-amd64.img" container_format = "bare" disk_format = "qcow2" @@ -43,14 +43,14 @@ resource "openstack_compute_keypair_v2" "rancher-keypair" { # OpenStack virtual network for quickstart resources resource "openstack_networking_network_v2" "rancher-quickstart" { - name = "${var.prefix}-network" + name = "${var.prefix}-rancher-network" tags = ["rancher-quickstart"] } # OpenStack internal subnet for quickstart resources resource "openstack_networking_subnet_v2" "rancher-quickstart-internal" { - name = "rancher-quickstart-internal" + name = "${var.prefix}-rancher-quickstart-internal" network_id = openstack_networking_network_v2.rancher-quickstart.id cidr = var.network_cidr @@ -85,7 +85,7 @@ resource "openstack_networking_floatingip_v2" "rancher-server-pip" { # OpenStack network interface for quickstart resources resource "openstack_networking_port_v2" "rancher-server-interface" { - name = "rancher-quickstart-interface" + name = "${var.prefix}-rancher-quickstart-interface" network_id = openstack_networking_network_v2.rancher-quickstart.id fixed_ip { @@ -248,7 +248,7 @@ module "rancher_common" { admin_password = var.rancher_server_admin_password workload_kubernetes_version = var.workload_kubernetes_version - workload_cluster_name = "quickstart-openstack-custom" + workload_cluster_name = "${var.prefix}-quickstart-openstack-custom" } # Floating IP of quickstart node @@ -260,7 +260,7 @@ resource "openstack_networking_floatingip_v2" "quickstart-node-pip" { # OpenStack network interface for quickstart resources resource "openstack_networking_port_v2" "quickstart-node-interface" { - name = "quickstart-node-interface" + name = "${var.prefix}-quickstart-node-interface" network_id = openstack_networking_network_v2.rancher-quickstart.id fixed_ip { @@ -293,7 +293,7 @@ data "cloudinit_config" "quickstart-node-cloudinit" { # OpenStack instance for creating a single node RKE cluster and installing the Rancher Server resource "openstack_compute_instance_v2" "quickstart-node" { - name = "${var.prefix}-quickstart-node" + name = "${var.prefix}-rancher-quickstart-node" flavor_name = var.instance_type key_pair = openstack_compute_keypair_v2.rancher-keypair.name user_data = data.cloudinit_config.quickstart-node-cloudinit.rendered From e8c890a717a5204cec6ee017466ebb951b816fa5 Mon Sep 17 00:00:00 2001 From: Hendrik Frenzel Date: Fri, 4 Sep 2020 22:16:06 +0200 Subject: [PATCH 4/6] Added missing secgroup associate on quickstart-node-interface --- openstack/infra.tf | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/openstack/infra.tf b/openstack/infra.tf index 79186135..25141d2c 100644 --- a/openstack/infra.tf +++ b/openstack/infra.tf @@ -270,6 +270,12 @@ resource "openstack_networking_port_v2" "quickstart-node-interface" { tags = ["rancher-quickstart"] } +# Associate security group to Quickstart node port +resource "openstack_networking_port_secgroup_associate_v2" "quickstart-node-interface-secgroup" { + port_id = openstack_networking_port_v2.quickstart-node-interface.id + security_group_ids = [openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id] +} + # Associate Quickstart node floating IP with the Quickstart node port resource "openstack_networking_floatingip_associate_v2" "quickstart-node-pip-associate" { floating_ip = openstack_networking_floatingip_v2.quickstart-node-pip.address From fe2871f0191d9bbca062bc08008c8a5a8d4bf4ba Mon Sep 17 00:00:00 2001 From: Hendrik Frenzel Date: Fri, 4 Sep 2020 22:19:30 +0200 Subject: [PATCH 5/6] Allow all IPv4 & IPv6 network traffic --- openstack/infra.tf | 42 +++--------------------------------------- 1 file changed, 3 insertions(+), 39 deletions(-) diff --git a/openstack/infra.tf b/openstack/infra.tf index 25141d2c..1a12397a 100644 --- a/openstack/infra.tf +++ b/openstack/infra.tf @@ -107,52 +107,16 @@ resource "openstack_networking_secgroup_v2" "rancher-quickstart-secgroup" { } # OpenStack security group rules -resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-ssh" { +resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-v4-all" { 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.rancher-quickstart-secgroup.id } -resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-http" { +resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-v6-all" { direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 80 - port_range_max = 80 - remote_ip_prefix = "0.0.0.0/0" - security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id -} - -resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-https" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 443 - port_range_max = 443 - remote_ip_prefix = "0.0.0.0/0" - security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id -} - -resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-kubeapi" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 6443 - port_range_max = 6443 - remote_ip_prefix = "0.0.0.0/0" - security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id -} - -resource "openstack_networking_secgroup_rule_v2" "rancher-quickstart-secgroup-rule-docker" { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 2376 - port_range_max = 2376 + ethertype = "IPv6" remote_ip_prefix = "0.0.0.0/0" security_group_id = openstack_networking_secgroup_v2.rancher-quickstart-secgroup.id } From 59fb3a447a86bb8d34e4c0dba344e1507980d788 Mon Sep 17 00:00:00 2001 From: Hendrik Frenzel Date: Sat, 5 Sep 2020 01:25:59 +0200 Subject: [PATCH 6/6] Reduced openstack provider variables --- openstack/README.md | 92 +++++------------------------- openstack/provider.tf | 32 ++++------- openstack/terraform.tfvars.example | 54 +++--------------- openstack/variables.tf | 88 +++------------------------- 4 files changed, 40 insertions(+), 226 deletions(-) diff --git a/openstack/README.md b/openstack/README.md index e3e137b2..987633bc 100644 --- a/openstack/README.md +++ b/openstack/README.md @@ -11,96 +11,44 @@ Both instances will have wide-open security groups and will be accessible over S The name of the pool from which to obtain the floating IPs ###### `openstack_auth_url` -- **Optional**; required if `openstack_cloud` is not specified. +- **Optional** The OpenStack Identity authentication URL. If omitted, the `OS_AUTH_URL` environment variable is used. -###### `openstack_cloud` -- **Optional**; required if `openstack_auth_url` is not specified. -An entry in a `clouds.yaml` file. -See the OpenStack openstacksdk documentation for more information about clouds.yaml files. -If omitted, the `OS_CLOUD` environment variable is used. - -###### `openstack_region` -- **Optional** -The region of the OpenStack cloud to use. -If omitted, the `OS_REGION_NAME` environment variable is used. - ###### `openstack_user_name` - **Optional** The Username to login with. -f omitted, the `OS_USERNAME` environment variable is used. - -###### `openstack_project_name` -- **Optional** -The Name of the Project. -If omitted, the `OS_TENANT_ID` or `OS_PROJECT_ID` environment variables are used. +If omitted, the `OS_USERNAME` environment variable is used. ###### `openstack_password` - **Optional** The Password to login with. If omitted, the `OS_PASSWORD` environment variable is used. -###### `openstack_domain_name` -- **Optional** -The Name of the Domain to scope to. -If omitted, the `OS_DOMAIN_NAME` environment variable is used. - -###### `openstack_user_id` -- **Optional** -The User ID to login with. -If omitted, the `OS_USER_ID` environment variable is checked. - -###### `openstack_application_credential_id` +###### `openstack_region` - **Optional** -The ID of an application credential to authenticate with. -An `openstack_application_credential_secret` has to bet set along with this parameter. +The region of the OpenStack cloud to use. +If omitted, the `OS_REGION_NAME` environment variable is used. -###### `openstack_application_credential_name` +###### `openstack_domain_id` - **Optional** -The name of an application credential to authenticate with. -Requires `openstack_user_id`, or `openstack_user_name` and `openstack_user_domain_name` (or `openstack_user_domain_id`) to be set. +The Name of the Domain to scope to. +If omitted, the `OS_DOMAIN_ID` environment variable is checked. -###### `openstack_application_credential_secret` +###### `openstack_domain_name` - **Optional** -The secret of an application credential to authenticate with. -Required by `openstack_application_credential_id` or `openstack_application_credential_name`. +The Name of the Domain to scope to. +If omitted, the `OS_DOMAIN_NAME` environment variable is used. ###### `openstack_project_id` - **Optional** The ID of the Project to login with. If omitted, the `OS_TENANT_ID` or `OS_PROJECT_ID` environment variables are used. -###### `openstack_token` -- **Optional** -The auth token to login with. -A token is an expiring, temporary means of access issued via the Keystone service. -If omitted, the `OS_TOKEN` or `OS_AUTH_TOKEN` environment variables are used. - -###### `openstack_user_domain_name` -- **Optional** -The domain name where the user is located. -If omitted, the `OS_USER_DOMAIN_NAME` environment variable is checked. - -###### `openstack_user_domain_id` -- **Optional** -The domain ID where the user is located. -If omitted, the `OS_USER_DOMAIN_ID` environment variable is checked. - -###### `openstack_project_domain_name` -- **Optional** -The domain name where the project is located. -If omitted, the `OS_PROJECT_DOMAIN_NAME` environment variable is checked. - -###### `openstack_project_domain_id` -- **Optional** -The domain ID where the project is located. -If omitted, the `OS_PROJECT_DOMAIN_ID` environment variable is checked. - -###### `openstack_domain_id` +###### `openstack_project_name` - **Optional** -The Name of the Domain to scope to. -If omitted, the `OS_DOMAIN_ID` environment variable is checked. +The Name of the Project. +If omitted, the `OS_TENANT_ID` or `OS_PROJECT_ID` environment variables are used. ###### `openstack_insecure` - **Optional** @@ -113,18 +61,6 @@ Specify a custom CA certificate when communicating over SSL. You can specify either a path to the file or the contents of the certificate. If omitted, the `OS_CACERT` environment variable is used. -###### `openstack_cert` -- **Optional** -Specify client certificate file for SSL client authentication. -You can specify either a path to the file or the contents of the certificate. -If omitted the `OS_CERT` environment variable is used. - -###### `openstack_key` -- **Optional** -Specify client private key file for SSL client authentication. -You can specify either a path to the file or the contents of the key. -If omitted the `OS_KEY` environment variable is used. - ###### `prefix` - Default: **`"quickstart"`** Prefix added to names of all resources diff --git a/openstack/provider.tf b/openstack/provider.tf index a5a53b8f..4560416f 100644 --- a/openstack/provider.tf +++ b/openstack/provider.tf @@ -1,26 +1,14 @@ provider "openstack" { - auth_url = var.openstack_auth_url - cloud = var.openstack_cloud - region = var.openstack_region - user_name = var.openstack_user_name - tenant_name = var.openstack_project_name - password = var.openstack_password - domain_name = var.openstack_domain_name - user_id = var.openstack_user_id - application_credential_id = var.openstack_application_credential_id - application_credential_name = var.openstack_application_credential_name - application_credential_secret = var.openstack_application_credential_secret - tenant_id = var.openstack_project_id - token = var.openstack_token - user_domain_name = var.openstack_user_domain_name - user_domain_id = var.openstack_user_domain_id - project_domain_name = var.openstack_project_domain_name - project_domain_id = var.openstack_project_domain_id - domain_id = var.openstack_domain_id - insecure = var.openstack_insecure - cacert_file = var.openstack_cacert_file - cert = var.openstack_cert - key = var.openstack_key + auth_url = var.openstack_auth_url + user_name = var.openstack_user_name + password = var.openstack_password + region = var.openstack_region + domain_id = var.openstack_domain_id + domain_name = var.openstack_domain_name + tenant_id = var.openstack_project_id + tenant_name = var.openstack_project_name + insecure = var.openstack_insecure + cacert_file = var.openstack_cacert_file } provider "tls" { diff --git a/openstack/terraform.tfvars.example b/openstack/terraform.tfvars.example index 785ccedd..b6fb5975 100644 --- a/openstack/terraform.tfvars.example +++ b/openstack/terraform.tfvars.example @@ -11,61 +11,29 @@ rancher_server_admin_password = "" # Use either the OS_* environment variables or the following variables # to authenticate with OpenStack infrastructure. -# OpenStack entry in a clouds.yaml file -# - Required if openstack_auth_url is not specified -# openstack_cloud = "" - # OpenStack Identity authentication URL -# - Required if openstack_cloud is not specified # openstack_auth_url = "" -# OpenStack Region -# openstack_region = "" - # OpenStack User Name # openstack_user_name = "" -# OpenStack Project Name -# openstack_project_name = "" - # OpenStack Password # openstack_password = "" -# OpenStack Domain Name -# openstack_domain_name = "" - -# OpenStack User ID -# openstack_user_id = "" - -# OpenStack Application Credential ID -# openstack_application_credential_id = "" +# OpenStack Region +# openstack_region = "" -# OpenStack Application Credential Name -# openstack_application_credential_name = "" +# OpenStack Domain ID +# openstack_domain_id = "" -# OpenStack Application Credential Secret -# openstack_application_credential_secret = "" +# OpenStack Domain Name +# openstack_domain_name = "" # OpenStacl Project ID # openstack_project_id = "" -# OpenStack Token -# openstack_token = "" - -# OpenStack User Domain Name -# openstack_user_domain_name = "" - -# OpenStack User Domain ID -# openstack_user_domain_id = "" - -# OpenStack Project Domain Nmae -# openstack_project_domain_name = "" - -# OpenStack Project Domain ID -# openstack_project_domain_id = "" - -# OpenStack Domain ID -# openstack_domain_id = "" +# OpenStack Project Name +# openstack_project_name = "" # OpenStack Insecure # openstack_insecure = "" @@ -73,12 +41,6 @@ rancher_server_admin_password = "" # OpenStack CACert File # openstack_cacert_file = "" -# OpenStack Cert -# openstack_cert = "" - -# OpenStack Key -# openstack_key = "" - # Optional variables, uncomment to customize the quickstart # ---------------------------------------------------------- diff --git a/openstack/variables.tf b/openstack/variables.tf index 507859d2..7600b46d 100644 --- a/openstack/variables.tf +++ b/openstack/variables.tf @@ -11,63 +11,33 @@ variable "openstack_auth_url" { default = null } -variable "openstack_cloud" { - type = string - description = "The entry in a clouds.yaml file." - default = null -} - -variable "openstack_region" { - type = string - description = "The region of the OpenStack cloud to use." - default = null -} - variable "openstack_user_name" { type = string description = "The Username to login with." default = null } -variable "openstack_project_name" { - type = string - description = "The Name of the Project." - default = null -} - variable "openstack_password" { type = string description = "The Password to login with." default = null } -variable "openstack_domain_name" { - type = string - description = "The Name of the Domain to scope to." - default = null -} - -variable "openstack_user_id" { - type = string - description = "The User ID to login with." - default = null -} - -variable "openstack_application_credential_id" { +variable "openstack_region" { type = string - description = "The ID of an application credential to authenticate with." + description = "The region of the OpenStack cloud to use." default = null } -variable "openstack_application_credential_name" { +variable "openstack_domain_id" { type = string - description = "The name of an application credential to authenticate with." + description = "The Name of the Domain to scope to." default = null } -variable "openstack_application_credential_secret" { +variable "openstack_domain_name" { type = string - description = "The secret of an application credential to authenticate with." + description = "The Name of the Domain to scope to." default = null } @@ -77,39 +47,9 @@ variable "openstack_project_id" { default = null } -variable "openstack_token" { - type = string - description = "The auth token to login with." - default = null -} - -variable "openstack_user_domain_name" { - type = string - description = "The domain name where the user is located." - default = null -} - -variable "openstack_user_domain_id" { - type = string - description = "The domain ID where the user is located." - default = null -} - -variable "openstack_project_domain_name" { - type = string - description = "The domain name where the project is located." - default = null -} - -variable "openstack_project_domain_id" { - type = string - description = "The domain ID where the project is located." - default = null -} - -variable "openstack_domain_id" { +variable "openstack_project_name" { type = string - description = "The Name of the Domain to scope to." + description = "The Name of the Project." default = null } @@ -125,18 +65,6 @@ variable "openstack_cacert_file" { default = null } -variable "openstack_cert" { - type = string - description = "Specify client certificate file for SSL client authentication." - default = null -} - -variable "openstack_key" { - type = string - description = "Specify client private key file for SSL client authentication." - default = null -} - variable "prefix" { type = string description = "Prefix added to names of all resources"