diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..44c6b32 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +clouds.yaml +**/clouds.yaml diff --git a/terraform/demo4-scale-out-lb/get-terraform.sh b/terraform/demo4-scale-out-lb/get-terraform.sh deleted file mode 100644 index 46e7ae5..0000000 --- a/terraform/demo4-scale-out-lb/get-terraform.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash -wget https://releases.hashicorp.com/terraform/0.14.10/terraform_0.14.10_linux_amd64.zip -O terraform_0.14.10_linux_amd64.zip -unzip -o terraform_0.14.10_linux_amd64.zip diff --git a/terraform/lab1/get-terraform.sh b/terraform/lab1/get-terraform.sh new file mode 100644 index 0000000..1050621 --- /dev/null +++ b/terraform/lab1/get-terraform.sh @@ -0,0 +1,3 @@ +#!/bin/bash +wget https://releases.hashicorp.com/terraform/1.1.3/terraform_1.1.3_linux_amd64.zip -O terraform_1.1.3_linux_amd64.zip +unzip -o terraform_1.1.3_linux_amd64.zip diff --git a/terraform/lab1/lab1.tf b/terraform/lab1/lab1.tf new file mode 100644 index 0000000..beee5c9 --- /dev/null +++ b/terraform/lab1/lab1.tf @@ -0,0 +1,178 @@ +# Define CloudComp group number +variable "group_number" { + type = string + default = "20" +} + +## OpenStack credentials can be used in a more secure way by using +## cloud.yaml from https://private-cloud.informatik.hs-fulda.de/project/api_access/clouds.yaml/ + +# or by using env vars exported from openrc here, +# e.g., using 'export TF_VAR_os_password=$OS_PASSWORD' + +# Define OpenStack credentials, project config etc. +locals { + auth_url = "https://private-cloud.informatik.hs-fulda.de:5000/v3" + user_name = "CloudComp${var.group_number}" + user_password = "" + tenant_name = "CloudComp${var.group_number}" + #network_name = "CloudComp${var.group_number}-net" + router_name = "CloudComp${var.group_number}-router" + image_name = "Ubuntu 20.04 - Focal Fossa - 64-bit - Cloud Based Image" + flavor_name = "m1.small" + region_name = "RegionOne" +} + +# Define OpenStack provider +terraform { +required_version = ">= 0.14.0" + required_providers { + openstack = { + source = "terraform-provider-openstack/openstack" + version = ">= 1.46.0" + } + } +} + +# Configure the OpenStack Provider +provider "openstack" { + user_name = local.user_name + tenant_name = local.tenant_name + password = local.user_password + auth_url = local.auth_url + region = local.region_name + use_octavia = true +} + + + +########################################################################### +# +# create keypair +# +########################################################################### + +# import keypair, if public_key is not specified, create new keypair to use +resource "openstack_compute_keypair_v2" "terraform-keypair" { + name = "my-terraform-pubkey" + #public_key = file("~/.ssh/id_rsa.pub") +} + + + +########################################################################### +# +# create security group +# +########################################################################### + +resource "openstack_networking_secgroup_v2" "terraform-secgroup" { + name = "my-terraform-secgroup" + description = "for terraform instances" +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-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.terraform-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-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.terraform-secgroup.id +} + + +########################################################################### +# +# create network +# +########################################################################### + +resource "openstack_networking_network_v2" "terraform-network-1" { + name = "my-terraform-network-1" + admin_state_up = "true" +} + +resource "openstack_networking_subnet_v2" "terraform-subnet-1" { + name = "my-terraform-subnet-1" + network_id = openstack_networking_network_v2.terraform-network-1.id + cidr = "192.168.255.0/24" + ip_version = 4 +} + +data "openstack_networking_router_v2" "router-1" { + name = local.router_name +} + +resource "openstack_networking_router_interface_v2" "router_interface_1" { + router_id = data.openstack_networking_router_v2.router-1.id + subnet_id = openstack_networking_subnet_v2.terraform-subnet-1.id +} + + + +########################################################################### +# +# create instances +# +########################################################################### + +resource "openstack_compute_instance_v2" "terraform-instance-1" { + name = "my-terraform-instance-1" + image_name = local.image_name + flavor_name = local.flavor_name + key_pair = openstack_compute_keypair_v2.terraform-keypair.name + security_groups = [openstack_networking_secgroup_v2.terraform-secgroup.name] + + depends_on = [openstack_networking_subnet_v2.terraform-subnet-1] + + network { + uuid = openstack_networking_network_v2.terraform-network-1.id + } + + user_data = <<-EOF + #!/bin/bash + apt-get update + apt-get -y install apache2 + rm /var/www/html/index.html + cat > /var/www/html/index.html << INNEREOF + + + +

It works!

+

hostname

+ + + INNEREOF + sed -i "s/hostname/terraform-instance-1/" /var/www/html/index.html + sed -i "1s/$/ terraform-instance-1/" /etc/hosts + EOF +} + +########################################################################### +# +# assign floating ip to instance +# +########################################################################### +resource "openstack_networking_floatingip_v2" "fip_1" { + pool = "public1" +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1_assoc" { + floating_ip = openstack_networking_floatingip_v2.fip_1.address + instance_id = openstack_compute_instance_v2.terraform-instance-1.id +} + +output "vip_addr" { + value = openstack_networking_floatingip_v2.fip_1 +} diff --git a/terraform/demo4-scale-out-lb/run-terraform.sh b/terraform/lab1/run-terraform.sh similarity index 100% rename from terraform/demo4-scale-out-lb/run-terraform.sh rename to terraform/lab1/run-terraform.sh diff --git a/terraform/demo4-scale-out-lb/stop-terraform.sh b/terraform/lab1/stop-terraform.sh similarity index 100% rename from terraform/demo4-scale-out-lb/stop-terraform.sh rename to terraform/lab1/stop-terraform.sh diff --git a/terraform/demo4-scale-out-lb/demo4-scale-out-lb.tf b/terraform/lab4-scale-out-lb/demo4-scale-out-lb.tf similarity index 100% rename from terraform/demo4-scale-out-lb/demo4-scale-out-lb.tf rename to terraform/lab4-scale-out-lb/demo4-scale-out-lb.tf diff --git a/terraform/lab4-scale-out-lb/get-terraform.sh b/terraform/lab4-scale-out-lb/get-terraform.sh new file mode 100644 index 0000000..1050621 --- /dev/null +++ b/terraform/lab4-scale-out-lb/get-terraform.sh @@ -0,0 +1,3 @@ +#!/bin/bash +wget https://releases.hashicorp.com/terraform/1.1.3/terraform_1.1.3_linux_amd64.zip -O terraform_1.1.3_linux_amd64.zip +unzip -o terraform_1.1.3_linux_amd64.zip diff --git a/terraform/lab4-scale-out-lb/lab4.tf b/terraform/lab4-scale-out-lb/lab4.tf new file mode 100644 index 0000000..f076c51 --- /dev/null +++ b/terraform/lab4-scale-out-lb/lab4.tf @@ -0,0 +1,259 @@ +# Define CloudComp group number +variable "group_number" { + type = string + default = "20" +} + +## OpenStack credentials can be used in a more secure way by using +## cloud.yaml from https://private-cloud.informatik.hs-fulda.de/project/api_access/clouds.yaml/ + +# or by using env vars exported from openrc here, +# e.g., using 'export TF_VAR_os_password=$OS_PASSWORD' + +# Define OpenStack credentials, project config etc. +locals { + auth_url = "https://private-cloud.informatik.hs-fulda.de:5000/v3" + user_name = "CloudComp${var.group_number}" + user_password = "" + tenant_name = "CloudComp${var.group_number}" + #network_name = "CloudComp${var.group_number}-net" + router_name = "CloudComp${var.group_number}-router" + image_name = "Ubuntu 20.04 - Focal Fossa - 64-bit - Cloud Based Image" + flavor_name = "m1.small" + region_name = "RegionOne" +} + +# Define OpenStack provider +terraform { +required_version = ">= 0.14.0" + required_providers { + openstack = { + source = "terraform-provider-openstack/openstack" + version = ">= 1.46.0" + } + } +} + +# Configure the OpenStack Provider +provider "openstack" { + user_name = local.user_name + tenant_name = local.tenant_name + password = local.user_password + auth_url = local.auth_url + region = local.region_name + use_octavia = true +} + + + +########################################################################### +# +# create keypair +# +########################################################################### + +# import keypair, if public_key is not specified, create new keypair to use +resource "openstack_compute_keypair_v2" "terraform-keypair" { + name = "my-terraform-pubkey" + #public_key = file("~/.ssh/id_rsa.pub") +} + + + +########################################################################### +# +# create security group +# +########################################################################### + +resource "openstack_networking_secgroup_v2" "terraform-secgroup" { + name = "my-terraform-secgroup" + description = "for terraform instances" +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-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.terraform-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-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.terraform-secgroup.id +} + + +########################################################################### +# +# create network +# +########################################################################### + +resource "openstack_networking_network_v2" "terraform-network-1" { + name = "my-terraform-network-1" + admin_state_up = "true" +} + +resource "openstack_networking_subnet_v2" "terraform-subnet-1" { + name = "my-terraform-subnet-1" + network_id = openstack_networking_network_v2.terraform-network-1.id + cidr = "192.168.255.0/24" + ip_version = 4 +} + +data "openstack_networking_router_v2" "router-1" { + name = local.router_name +} + +resource "openstack_networking_router_interface_v2" "router_interface_1" { + router_id = data.openstack_networking_router_v2.router-1.id + subnet_id = openstack_networking_subnet_v2.terraform-subnet-1.id +} + + + +########################################################################### +# +# create instances +# +########################################################################### + +resource "openstack_compute_instance_v2" "terraform-instance-1" { + name = "my-terraform-instance-1" + image_name = local.image_name + flavor_name = local.flavor_name + key_pair = openstack_compute_keypair_v2.terraform-keypair.name + security_groups = [openstack_networking_secgroup_v2.terraform-secgroup.name] + + depends_on = [openstack_networking_subnet_v2.terraform-subnet-1] + + network { + uuid = openstack_networking_network_v2.terraform-network-1.id + } + + user_data = <<-EOF + #!/bin/bash + apt-get update + apt-get -y install apache2 + rm /var/www/html/index.html + cat > /var/www/html/index.html << INNEREOF + + + +

It works!

+

hostname

+ + + INNEREOF + sed -i "s/hostname/terraform-instance-1/" /var/www/html/index.html + sed -i "1s/$/ terraform-instance-1/" /etc/hosts + EOF +} + +resource "openstack_compute_instance_v2" "terraform-instance-2" { + name = "my-terraform-instance-2" + image_name = local.image_name + flavor_name = local.flavor_name + key_pair = openstack_compute_keypair_v2.terraform-keypair.name + security_groups = [openstack_networking_secgroup_v2.terraform-secgroup.id] + + depends_on = [openstack_networking_subnet_v2.terraform-subnet-1] + + network { + uuid = openstack_networking_network_v2.terraform-network-1.id + } + + user_data = <<-EOF + #!/bin/bash + apt-get update + apt-get -y install apache2 + rm /var/www/html/index.html + cat > /var/www/html/index.html << INNEREOF + + + +

It works!

+

hostname

+ + + INNEREOF + sed -i "s/hostname/terraform-instance-2/" /var/www/html/index.html + sed -i "1s/$/ terraform-instance-2/" /etc/hosts + EOF +} + + + +########################################################################### +# +# create load balancer +# +########################################################################### +resource "openstack_lb_loadbalancer_v2" "lb_1" { + vip_subnet_id = openstack_networking_subnet_v2.terraform-subnet-1.id +} + +resource "openstack_lb_listener_v2" "listener_1" { + protocol = "HTTP" + protocol_port = 80 + loadbalancer_id = openstack_lb_loadbalancer_v2.lb_1.id + connection_limit = 1024 +} + +resource "openstack_lb_pool_v2" "pool_1" { + protocol = "HTTP" + lb_method = "ROUND_ROBIN" + listener_id = openstack_lb_listener_v2.listener_1.id +} + +resource "openstack_lb_members_v2" "members_1" { + pool_id = openstack_lb_pool_v2.pool_1.id + + member { + address = openstack_compute_instance_v2.terraform-instance-1.access_ip_v4 + protocol_port = 80 + } + + member { + address = openstack_compute_instance_v2.terraform-instance-2.access_ip_v4 + protocol_port = 80 + } +} + +resource "openstack_lb_monitor_v2" "monitor_1" { + pool_id = openstack_lb_pool_v2.pool_1.id + type = "HTTP" + delay = 5 + timeout = 5 + max_retries = 3 + http_method = "GET" + url_path = "/" + expected_codes = 200 + + depends_on = [openstack_lb_loadbalancer_v2.lb_1, openstack_lb_listener_v2.listener_1, openstack_lb_pool_v2.pool_1, openstack_lb_members_v2.members_1 ] +} + + + +########################################################################### +# +# assign floating ip to load balancer +# +########################################################################### +resource "openstack_networking_floatingip_v2" "fip_1" { + pool = "public1" + port_id = openstack_lb_loadbalancer_v2.lb_1.vip_port_id +} + +output "loadbalancer_vip_addr" { + value = openstack_networking_floatingip_v2.fip_1 +} diff --git a/terraform/lab4-scale-out-lb/run-terraform.sh b/terraform/lab4-scale-out-lb/run-terraform.sh new file mode 100644 index 0000000..14929cb --- /dev/null +++ b/terraform/lab4-scale-out-lb/run-terraform.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# initialization of terraform state and download openstack plugin/dependencies +./terraform init + +# show what will done +./terraform plan + +# let terraform create the resources specified in .tf file in same directory +./terraform apply + +# you can also use "terraform apply -auto-approve" to prevent terraform from asking back whether it should proceed + +# among the benefits of terraform, is that is deploys the resources rather quick. It identifies dependencies and +# deploys independent resources in parallel. +# "terraform graph" creates a dependency graph of the resource specified in the .tf file +# another benefit of terraform is, that it does the heavy lifting to support the APIs of multiple cloud +# providers and supports way more features and cloud services than, e.g., libcloud, hence it's quite popular +# +# among the drawbacks however is, that it comes with its own definition language and does not offer the full +# flexibility of a programming language. In this regard, libcloud, boto3, openstack-sdk etc. are way more flexible +# +# we discuss different cloud service deployment solutions and their pros/cons in the course \ No newline at end of file diff --git a/terraform/lab4-scale-out-lb/stop-terraform.sh b/terraform/lab4-scale-out-lb/stop-terraform.sh new file mode 100644 index 0000000..fd38e13 --- /dev/null +++ b/terraform/lab4-scale-out-lb/stop-terraform.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# let terraform remove the resources specified in .tf file in same directory +./terraform destroy + +# you can also use "terraform destroy -auto-approve" to prevent terraform from asking back whether it should proceed diff --git a/terraform/rancher-terraform/example-templates/cluster-options-example.yml b/terraform/rancher-terraform/example-templates/cluster-options-example.yml new file mode 100644 index 0000000..7e7aab4 --- /dev/null +++ b/terraform/rancher-terraform/example-templates/cluster-options-example.yml @@ -0,0 +1,179 @@ +# +# Cluster Config +# +docker_root_dir: /var/lib/docker +enable_cluster_alerting: false +enable_cluster_monitoring: false +enable_network_policy: false +local_cluster_auth_endpoint: + enabled: true +name: openstack-rke +# +# Rancher Config +# +rancher_kubernetes_engine_config: +##################################################################### +# +# Config for OpenStack @ NetLab Hochschule Fulda Start +# +# Paste the following section into rancher_kubernetes_engine_config +# be sure to use correct indention, if in doubt, use YAML syntax +# checker +# +# You need to replace tenant-id with your project id, you can see +# the id, e.g., in the OpenStack Web Interface (Horizon) here: +# - https://private-cloud.informatik.hs-fulda.de/project/api_access/view_credentials/ +# +# Replace floating-network-id with the id of the network "public1". +# Click in network "public1" here: +# - https://private-cloud.informatik.hs-fulda.de/project/networks/ +# and use the value shown for ID. +# +# Replace subnet-id with the id of the subnet (not network!) that you +# use for your RKE node instances. If you use network +# "my-terraform-rancher-network-1" you can got to: +# - https://private-cloud.informatik.hs-fulda.de/project/networks/ +# click on my-terraform-rancher-network-1, then click on its subnet +# my-terraform-rancher-subnet-1, and use the shown ID of the subnet. +# +# Replace the router-id with the id of your router. Go to: +# - https://private-cloud.informatik.hs-fulda.de/project/routers/ +# click on the router you use for the network of your RKE instances +# and use the shown ID of this router. +# +# Replace password with the password of your groups' OpenStack +# account +# +# You can also see other config options in RKE docu here: +# https://rancher.com/docs/rke/latest/en/config-options/cloud-providers/openstack/ +# +##################################################################### + cloud_provider: + name: openstack + openstackCloudProvider: + block_storage: + ignore-volume-az: true + trust-device-path: false + global: + auth-url: 'https://private-cloud.informatik.hs-fulda.de:5000' + domain-name: Default + tenant-id: + username: IntServ19 + password: + load_balancer: + create-monitor: false + floating-network-id: + lb-version: v2 + manage-security-groups: true + monitor-max-retries: 0 + subnet-id: + use-octavia: true + metadata: + request-timeout: 0 + route: + router-id: +##################################################################### +# +# Config for OpenStack @ NetLab Hochschule Fulda End +# +##################################################################### + addon_job_timeout: 45 + authentication: + strategy: x509 + dns: + nodelocal: + ip_address: '' + node_selector: null + update_strategy: {} + enable_cri_dockerd: false + ignore_docker_version: true +# +# # Currently only nginx ingress provider is supported. +# # To disable ingress controller, set `provider: none` +# # To enable ingress on specific nodes, use the node_selector, eg: +# provider: nginx +# node_selector: +# app: ingress +# + ingress: + default_backend: false + default_ingress_class: true + http_port: 0 + https_port: 0 + provider: nginx + kubernetes_version: v1.21.8-rancher1-1 + monitoring: + provider: metrics-server + replicas: 1 +# +# If you are using calico on AWS +# +# network: +# plugin: calico +# calico_network_provider: +# cloud_provider: aws +# +# # To specify flannel interface +# +# network: +# plugin: flannel +# flannel_network_provider: +# iface: eth1 +# +# # To specify flannel interface for canal plugin +# +# network: +# plugin: canal +# canal_network_provider: +# iface: eth1 +# + network: + mtu: 0 + options: + flannel_backend_type: vxlan + plugin: canal + rotate_encryption_key: false +# +# services: +# kube-api: +# service_cluster_ip_range: 10.43.0.0/16 +# kube-controller: +# cluster_cidr: 10.42.0.0/16 +# service_cluster_ip_range: 10.43.0.0/16 +# kubelet: +# cluster_domain: cluster.local +# cluster_dns_server: 10.43.0.10 +# + services: + etcd: + backup_config: + enabled: true + interval_hours: 12 + retention: 6 + safe_timestamp: false + timeout: 300 + creation: 12h + extra_args: + election-timeout: 5000 + heartbeat-interval: 500 + gid: 0 + retention: 72h + snapshot: false + uid: 0 + kube_api: + always_pull_images: false + pod_security_policy: false + secrets_encryption_config: + enabled: false + service_node_port_range: 30000-32767 + ssh_agent_auth: false + upgrade_strategy: + max_unavailable_controlplane: '1' + max_unavailable_worker: 10% + node_drain_input: + delete_local_data: false + force: false + grace_period: -1 + ignore_daemon_sets: true + timeout: 120 +windows_prefered_cluster: false diff --git a/terraform/rancher-terraform/example-templates/node-template-example.json b/terraform/rancher-terraform/example-templates/node-template-example.json new file mode 100644 index 0000000..d748a70 --- /dev/null +++ b/terraform/rancher-terraform/example-templates/node-template-example.json @@ -0,0 +1,49 @@ +{ + "driver": "openstack", + "name": "openstack-template", + "openstackConfig": { + "activeTimeout": "200", + "applicationCredentialId": "", + "applicationCredentialName": "", + "applicationCredentialSecret": "", + "authUrl": "https://private-cloud.informatik.hs-fulda.de:5000", + "availabilityZone": "nova", + "bootFromVolume": false, + "cacert": "", + "configDrive": false, + "domainId": "", + "domainName": "Default", + "endpointType": "", + "flavorId": "", + "flavorName": "m1.medium", + "floatingipPool": "public1", + "imageId": "", + "imageName": "Ubuntu 20.04 - Focal Fossa - 64-bit - Cloud Based Image", + "insecure": false, + "ipVersion": "4", + "keypairName": "rancher-key", + "netId": "", + "netName": "my-terraform-rancher-network-1", + "novaNetwork": false, + "region": "RegionOne", + "secGroups": "my-terraform-rancher-secgroup", + "sshPort": "22", + "sshUser": "ubuntu", + "tenantDomainId": "", + "tenantDomainName": "Default", + "tenantId": "", + "tenantName": "IntServ19", + "userDataFile": "", + "userDomainId": "", + "userDomainName": "Default", + "userId": "", + "username": "IntServ19", + "password": "", + "volumeDevicePath": "", + "volumeId": "", + "volumeName": "", + "volumeSize": "0", + "volumeType": "" + }, + "type": "nodeTemplate", +} \ No newline at end of file diff --git a/terraform/rancher-terraform/main.tf b/terraform/rancher-terraform/main.tf new file mode 100644 index 0000000..87e0553 --- /dev/null +++ b/terraform/rancher-terraform/main.tf @@ -0,0 +1,500 @@ +# Define IntServ group number +# TODO: change to use OS env vars etc. +variable "group_number" { + type = string + default = "19" +} + +## OpenStack credentials can be used in a more secure way by using +## cloud.yaml from https://private-cloud.informatik.hs-fulda.de/project/api_access/clouds.yaml/ + +# Define OpenStack credentials, project config etc. +locals { + auth_url = "https://private-cloud.informatik.hs-fulda.de:5000/v3" + user_name = "IntServ${var.group_number}" + user_password = "" + tenant_name = "IntServ${var.group_number}" + #network_name = "IntServ${var.group_number}-net" + router_name = "IntServ${var.group_number}-router" + image_name = "Ubuntu 20.04 - Focal Fossa - 64-bit - Cloud Based Image" + flavor_name = "m1.medium" + region_name = "RegionOne" + rke_flavor_name = "m1.medium" + availability_zone = "nova" + domain_name = "Default" +# possibly set floating_ip_pool = "" to avoid assigning floating ips to +# every created node and use only load balancer as frontend, however needed +# for node port forwarding etc. using kube proxy + floating_ip_pool = "public1" + ssh_user = "ubuntu" +} + +# Define OpenStack provider +terraform { +required_version = ">= 0.14.0" + required_providers { + openstack = { + source = "terraform-provider-openstack/openstack" + version = ">= 1.46.0" + } + rancher2 = { + source = "rancher/rancher2" + version = ">= 1.22.2" + } + } +} + +# Configure the OpenStack Provider +provider "openstack" { + user_name = local.user_name + tenant_name = local.tenant_name + password = local.user_password + auth_url = local.auth_url + region = local.region_name + use_octavia = true +} + + + +########################################################################### +# +# create keypair +# +########################################################################### + +# import keypair, if public_key is not specified, create new keypair to use +resource "openstack_compute_keypair_v2" "terraform-rancher-keypair" { + name = "my-terraform-rancher-pubkey" + # public_key = file("~/srieger_rsa.pub") +} + + + +########################################################################### +# +# create security group +# +########################################################################### + +resource "openstack_networking_secgroup_v2" "terraform-rancher-secgroup" { + name = "my-terraform-rancher-secgroup" + description = "for terraform rancher instances" +} + +# TODO: possibly cleanup unnecessary ports? + +resource "openstack_networking_secgroup_rule_v2" "terraform-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.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-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.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-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.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-secgroup-rule-2376" { + 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.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-secgroup-rule-2379" { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 2379 + port_range_max = 2379 + #remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-secgroup-rule-2380" { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 2380 + port_range_max = 2380 + #remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-secgroup-rule-6443" { + 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.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-secgroup-rule-9099" { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 9099 + port_range_max = 9099 + #remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-secgroup-rule-10250" { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 10250 + port_range_max = 10250 + #remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-secgroup-rule-10254" { + direction = "ingress" + ethertype = "IPv4" + protocol = "tcp" + port_range_min = 10254 + port_range_max = 10254 + #remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.terraform-rancher-secgroup.id +} + +resource "openstack_networking_secgroup_rule_v2" "terraform-secgroup-rule-8472" { + direction = "ingress" + ethertype = "IPv4" + protocol = "udp" + port_range_min = 8472 + port_range_max = 8472 + #remote_ip_prefix = "0.0.0.0/0" + security_group_id = openstack_networking_secgroup_v2.terraform-rancher-secgroup.id +} + + + + +########################################################################### +# +# create network +# +########################################################################### + +resource "openstack_networking_network_v2" "terraform-rancher-network-1" { + name = "my-terraform-rancher-network-1" + admin_state_up = "true" +} + +resource "openstack_networking_subnet_v2" "terraform-rancher-subnet-1" { + name = "my-terraform-rancher-subnet-1" + network_id = openstack_networking_network_v2.terraform-rancher-network-1.id + cidr = "192.168.254.0/24" + dns_nameservers = [ "192.168.76.253" ] + ip_version = 4 +} + +data "openstack_networking_router_v2" "router-1" { + name = local.router_name +} + +resource "openstack_networking_router_interface_v2" "router_interface_1" { + router_id = data.openstack_networking_router_v2.router-1.id + subnet_id = openstack_networking_subnet_v2.terraform-rancher-subnet-1.id +} + + + +########################################################################### +# +# create instances +# +########################################################################### + +resource "openstack_compute_instance_v2" "terraform-rancher-instance-1" { + name = "my-terraform-rancher-instance-1" + image_name = local.image_name + flavor_name = local.flavor_name + key_pair = openstack_compute_keypair_v2.terraform-rancher-keypair.name + security_groups = [openstack_networking_secgroup_v2.terraform-rancher-secgroup.name] + + network { + uuid = openstack_networking_network_v2.terraform-rancher-network-1.id + } + + user_data = <<-EOF + #!/bin/bash + apt-get update + apt-get -y upgrade + curl https://releases.rancher.com/install-docker/20.10.sh | sh + sudo docker run --privileged -d --restart=unless-stopped -p 80:80 -p 443:443 --env CATTLE_BOOTSTRAP_PASSWORD=this-is-not-a-secure-bootstrap-pw rancher/rancher + #sudo docker ps + #sudo docker logs $(sudo docker ps | grep rancher | cut -d " " -f 1) 2>&1 | grep "Bootstrap Password:" + EOF + + depends_on = [ + openstack_networking_subnet_v2.terraform-rancher-subnet-1 + ] +} + + + +########################################################################### +# +# assign floating ip to rancher instance +# +########################################################################### +resource "openstack_networking_floatingip_v2" "fip_1" { + pool = "public1" +} + +resource "openstack_compute_floatingip_associate_v2" "fip_1" { + floating_ip = "${openstack_networking_floatingip_v2.fip_1.address}" + instance_id = "${openstack_compute_instance_v2.terraform-rancher-instance-1.id}" +} + +output "floating_ip" { + value = openstack_networking_floatingip_v2.fip_1 +} + +########################################################################### +# +# bootstrap rancher +# +########################################################################### + +# Provider bootstrap config +provider "rancher2" { + alias = "bootstrap" + + api_url = "https://${openstack_networking_floatingip_v2.fip_1.address}" + bootstrap = true + insecure = true +# takes roughly ~7 minutes currently + timeout = "600s" +} + +# Create a new rancher2_bootstrap for Rancher v2.6.0 and above +resource "rancher2_bootstrap" "admin" { + provider = rancher2.bootstrap + initial_password = "this-is-not-a-secure-bootstrap-pw" + password = "this-is-not-a-secure-admin-pw" + telemetry = true + token_update=true +} + +# Rancher2 administration provider +provider "rancher2" { + alias = "admin" + + api_url = "https://${openstack_networking_floatingip_v2.fip_1.address}" + insecure = true + # ca_certs = data.kubernetes_secret.rancher_cert.data["ca.crt"] + token_key = rancher2_bootstrap.admin.token +} + +########################################################################### +# +# enable rancher node driver openstack +# +########################################################################### + +#data "rancher2_node_driver" "OpenStack" { +# provider = rancher2.admin +# name = "openstack" +#} + +# Create a new rancher2 Node Driver +# TODO: creates a new builtin driver, maybe better to change existing one +resource "rancher2_node_driver" "OpenStack" { + provider = rancher2.admin + name = "openstack" + active = true + builtin = true + url = "local://" +# external_id = data.rancher2_node_driver.OpenStack +} + + + +########################################################################### +# +# create rancher node template for hsfd openstack +# +########################################################################### + +resource "rancher2_node_template" "hsfd-rancher-openstack" { + provider = rancher2.admin + name = "hsfd-rancher-openstack" + driver_id = rancher2_node_driver.OpenStack.id + openstack_config { + auth_url = local.auth_url + availability_zone = local.availability_zone + region = local.region_name + username = local.user_name +# TODO: (Optional/Sensitive) OpenStack password. Mandatory on Rancher v2.0.x and v2.1.x. Use rancher2_cloud_credential from Rancher v2.2.x (string) + password = local.user_password + active_timeout = "200" + domain_name = local.domain_name + boot_from_volume = false + flavor_name = local.rke_flavor_name + floating_ip_pool = local.floating_ip_pool + image_name = local.image_name + ip_version = "4" + keypair_name = openstack_compute_keypair_v2.terraform-rancher-keypair.name + net_id = openstack_networking_network_v2.terraform-rancher-network-1.id + sec_groups = openstack_networking_secgroup_v2.terraform-rancher-secgroup.name + ssh_user = local.ssh_user + private_key_file = openstack_compute_keypair_v2.terraform-rancher-keypair.private_key + tenant_name = local.tenant_name + } +# TODO: get latest recommended string possible? + engine_install_url = "https://releases.rancher.com/install-docker/20.10.sh" +} + + + +########################################################################### +# +# create rke template for hsfd openstack +# +########################################################################### + +data "openstack_identity_project_v3" "my-project" { + name = local.tenant_name +} + +data "openstack_networking_network_v2" "public1" { + name = local.floating_ip_pool +} + +# Create a new rancher2 Cluster Template +resource "rancher2_cluster_template" "hsfd-rke-openstack" { + provider = rancher2.admin + name = "hsfd-rke-openstack" + template_revisions { + name = "V1" + cluster_config { + rke_config { + cloud_provider { + name = "openstack" + openstack_cloud_provider { + block_storage { + ignore_volume_az = true + trust_device_path = false + } + global { + auth_url = local.auth_url + domain_name = local.domain_name + tenant_id = data.openstack_identity_project_v3.my-project.id + username = local.user_name + password = local.user_password + } + load_balancer { + create_monitor = false + floating_network_id = data.openstack_networking_network_v2.public1.id + lb_version = "v2" + manage_security_groups = true + monitor_max_retries = 0 + subnet_id = openstack_networking_subnet_v2.terraform-rancher-subnet-1.id + use_octavia = true + } + metadata { + request_timeout = 0 + } + route { + router_id = data.openstack_networking_router_v2.router-1.id + } + } + } + } + } + default = true + } + description = "Terraform RKE template for HSFD OpenStack" +} + + + +########################################################################### +# +# create rke demo cluster +# +########################################################################### + +resource "rancher2_cluster" "hsfd-rke-demo" { + provider = rancher2.admin + name = "hsfd-rke-demo" + cluster_template_id = rancher2_cluster_template.hsfd-rke-openstack.id + cluster_template_revision_id = rancher2_cluster_template.hsfd-rke-openstack.template_revisions.0.id + +# if instance is gone before deleting the cluster, we'll not be able to +# reach rke anymore + depends_on = [ + openstack_compute_instance_v2.terraform-rancher-instance-1, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-ssh, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-http, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-https, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-2376, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-2379, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-2380, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-6443, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-9099, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-10250, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-10254, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-8472, + openstack_compute_floatingip_associate_v2.fip_1 + ] +} + +# Create a new rancher2 Node Pool +resource "rancher2_node_pool" "pool1" { + provider = rancher2.admin + cluster_id = rancher2_cluster.hsfd-rke-demo.id + name = "ctrl-etcd-work" + hostname_prefix = "ctrl-etcd-work" + node_template_id = rancher2_node_template.hsfd-rancher-openstack.id + quantity = 1 + control_plane = true + etcd = true + worker = true + +# if instance is gone before deleting the cluster, we'll not be able to +# reach rke anymore + depends_on = [ + openstack_compute_instance_v2.terraform-rancher-instance-1, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-ssh, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-http, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-https, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-2376, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-2379, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-2380, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-6443, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-9099, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-10250, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-10254, + openstack_networking_secgroup_rule_v2.terraform-secgroup-rule-8472, + openstack_compute_floatingip_associate_v2.fip_1 + ] +} diff --git a/terraform/rke-terraform/main.tf b/terraform/rke-terraform/main.tf new file mode 100644 index 0000000..47db9c9 --- /dev/null +++ b/terraform/rke-terraform/main.tf @@ -0,0 +1,20 @@ +# Consider using 'export TF_VAR_os_auth_url=$OS_AUTH_URL' +variable "os_auth_url"{} +# Consider using 'export TF_VAR_os_password=$OS_PASSWORD' +variable "os_password"{} + + module "rke" { + source = "remche/rke/openstack" + image_name = "Ubuntu 20.04 - Focal Fossa - 64-bit - Cloud Based Image" + public_net_name = "public1" + master_flavor_name = "m1.small" + worker_flavor_name = "m1.small" + os_auth_url = var.os_auth_url + os_password = var.os_password + #use_ssh_agent = false + #enable_loadbalancer = true + #use_octavia = true + wait_for_commands = ["while docker info ; [ $? -ne 0 ]; do echo wait for docker; sudo newgrp - docker ; sleep 30 ; done"] + user_data_file = "user-data.sh" + dns_servers = [ "192.168.76.253" ] +} diff --git a/terraform/rke-terraform/user-data.sh b/terraform/rke-terraform/user-data.sh new file mode 100644 index 0000000..6f27852 --- /dev/null +++ b/terraform/rke-terraform/user-data.sh @@ -0,0 +1,6 @@ +#!/bin/bash +#apt-get update +#apt-get -y upgrade +curl https://releases.rancher.com/install-docker/20.10.sh | sh +groupadd docker +usermod -aG docker ubuntu diff --git a/terraform/rke2-terraform/main.tf b/terraform/rke2-terraform/main.tf new file mode 100644 index 0000000..63bd38f --- /dev/null +++ b/terraform/rke2-terraform/main.tf @@ -0,0 +1,11 @@ +module "controlplane" { + source = "remche/rke2/openstack" + cluster_name = var.cluster_name + dns_servers = var.dns_servers + write_kubeconfig = true + image_name = "Ubuntu 20.04 - Focal Fossa - 64-bit - Cloud Based Image" + flavor_name = "m1.medium" + public_net_name = "public1" + use_ssh_agent = false + ssh_key_file = "/root/.ssh/id_rsa" +} diff --git a/terraform/rke2-terraform/outputs.tf b/terraform/rke2-terraform/outputs.tf new file mode 100644 index 0000000..bd325f4 --- /dev/null +++ b/terraform/rke2-terraform/outputs.tf @@ -0,0 +1,5 @@ +output "server_ip" { + description = "Server floating IP" + value = module.controlplane.floating_ip[0] + sensitive = true +} diff --git a/terraform/rke2-terraform/variables.tf b/terraform/rke2-terraform/variables.tf new file mode 100644 index 0000000..7449936 --- /dev/null +++ b/terraform/rke2-terraform/variables.tf @@ -0,0 +1,9 @@ +variable "cluster_name" { + type = string + default = "minimal" +} + +variable "dns_servers" { + type = list(string) + default = ["192.168.76.253"] +}