Skip to content

Commit

Permalink
Merge pull request #84 from ranyodh/gcp-support
Browse files Browse the repository at this point in the history
Example terraform scripts for installing MKE on GCP
  • Loading branch information
ranyodh authored Apr 20, 2022
2 parents e228fdd + 99c794c commit 0cd835c
Show file tree
Hide file tree
Showing 29 changed files with 982 additions and 0 deletions.
1 change: 1 addition & 0 deletions examples/terraform/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ Working examples for using Terraform with Mirantis Launchpad. The scripts are pr

* [AWS](aws/README.md), a complete infrastructure example including VPC, LB, security groups, and other settings.
* [Azure](azure/README.md), a complete example including VNET, LB, network security rules, and other settings.
* [GCP](gcp/README.md), a complete example including VPC, Network/Subnetwork, LB, Firewall Rules and other settings.
* [Hetzner](hetzner/README.md), a simple example with just a couple of VMs provisioned for an MKE cluster.
* [OpenStack](openstack/README.md), a simple example with basic settings.
* [VMware](vmware/README.md), a simple example using existing vSphere network.
28 changes: 28 additions & 0 deletions examples/terraform/gcp/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Bootstrapping MKE cluster on GCP

This directory provides an example flow for using Mirantis Launchpad with Terraform and GCP.

## Prerequisites

* An account and credentials for GCP.
* Terraform [installed](https://learn.hashicorp.com/terraform/getting-started/install)

## Authentication

The Terraform `google` provider uses JSON key file for authentication. Download the JSON key file for a service account and place it in a secure location on your workstation.
See [here](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started#adding-credentials) for more information.

The authentication credentials can be passed to `google` provider in two ways:
* Setting environment variable GOOGLE_APPLICATION_CREDENTIALS with JSON key location.
* Setting `gcp_service_credential` variable in `terraform.tfvars` file.

## Steps

1. Create terraform.tfvars file with needed details. You can use the provided terraform.tfvars.example as a baseline.
2. `terraform init`
3. `terraform apply`
4. `terraform output --raw mke_cluster | launchpad apply --config -`

## Notes

1. Both RDP and WinRM ports are opened for Windows workers.
191 changes: 191 additions & 0 deletions examples/terraform/gcp/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,191 @@
terraform {
required_providers {
google = {
source = "hashicorp/google"
version = "4.11.0"
}
}
}

provider "google" {
credentials = var.gcp_service_credential

project = var.project_id
region = var.gcp_region
zone = var.gcp_zone
}

data "google_compute_zones" "available" {
}

# If the zone is not specified, use the first zone from the available zones
locals {
zone = var.gcp_zone != "" ? var.gcp_zone : data.google_compute_zones.available.names[0]
}

module "vpc" {
source = "./modules/vpc"
project_id = var.project_id
cluster_name = var.cluster_name
host_cidr = var.vpc_cidr
gcp_region = var.gcp_region
vpc_mtu = var.vpc_mtu
}

module "common" {
source = "./modules/common"
project_id = var.project_id
cluster_name = var.cluster_name
vpc_name = module.vpc.vpc_name
}

module "managers" {
source = "./modules/manager"
manager_count = var.manager_count
gcp_region = var.gcp_region
gcp_zone = local.zone
cluster_name = var.cluster_name
image_name = module.common.image_name
vpc_name = module.vpc.vpc_name
subnetwork_name = module.vpc.subnet_name
ssh_key = module.common.ssh_key
}

module "msrs" {
source = "./modules/msr"
msr_count = var.msr_count
gcp_region = var.gcp_region
gcp_zone = local.zone
cluster_name = var.cluster_name
image_name = module.common.image_name
vpc_name = module.vpc.vpc_name
subnetwork_name = module.vpc.subnet_name
ssh_key = module.common.ssh_key
}

module "workers" {
source = "./modules/worker"
worker_count = var.worker_count
gcp_region = var.gcp_region
gcp_zone = local.zone
cluster_name = var.cluster_name
vpc_name = module.vpc.vpc_name
subnetwork_name = module.vpc.subnet_name
image_name = module.common.image_name
ssh_key = module.common.ssh_key
worker_type = var.worker_type
}

module "windows_workers" {
source = "./modules/windows_worker"
worker_count = var.windows_worker_count
gcp_zone = local.zone
cluster_name = var.cluster_name
vpc_name = module.vpc.vpc_name
subnetwork_name = module.vpc.subnet_name
image_name = module.common.windows_2019_image_name
ssh_key = module.common.ssh_key
worker_type = var.worker_type
windows_user = var.windows_user
windows_password = var.windows_password
}

locals {
managers = [
for host in module.managers.machines : {
ssh = {
address = host.network_interface.0.access_config.0.nat_ip
user = "ubuntu"
keyPath = "./ssh_keys/${var.cluster_name}.pem"
}
role = host.metadata["role"]
privateInterface = "ens4"
}
]

msrs = [
for host in module.msrs.machines : {
ssh = {
address = host.network_interface.0.access_config.0.nat_ip
user = "ubuntu"
keyPath = "./ssh_keys/${var.cluster_name}.pem"
}
role = host.metadata["role"]
privateInterface = "ens4"
}
]

workers = [
for host in module.workers.machines : {
ssh = {
address = host.network_interface.0.access_config.0.nat_ip
user = "ubuntu"
keyPath = "./ssh_keys/${var.cluster_name}.pem"
}
role = host.metadata["role"]
privateInterface = "ens4"
}
]

windows_workers = [
for host in module.windows_workers.machines : {
winRM = {
address = host.network_interface.0.access_config.0.nat_ip
user = var.windows_user
password = var.windows_password
useHTTPS = true
insecure = true
}
role = host.metadata["role"]
privateInterface = "Ethernet"
}
]

mke_launchpad_tmpl = {
apiVersion = "launchpad.mirantis.com/mke/v1.3"
kind = "mke"
spec = {
mke = {
version = var.mke_version
adminUsername = "admin"
adminPassword = var.admin_password
installFlags : [
"--default-node-orchestrator=kubernetes",
"--san=${module.managers.lb_public_ip_address}",
]
}
msr = {}
hosts = concat(local.managers, local.msrs, local.workers, local.windows_workers)
}
}

msr_launchpad_tmpl = {
apiVersion = "launchpad.mirantis.com/mke/v1.3"
kind = "mke+msr"
spec = {
mke = {
version = var.mke_version
adminUsername = "admin"
adminPassword = var.admin_password
installFlags : [
"--default-node-orchestrator=kubernetes",
"--san=${module.managers.lb_public_ip_address}",
]
}
msr = {
installFlags : [
"--ucp-insecure-tls",
"--dtr-external-url ${module.msrs.lb_public_ip_address}",
]
}
hosts = concat(local.managers, local.msrs, local.workers, local.windows_workers)
}
}

launchpad_tmpl = var.msr_count > 0 ? local.msr_launchpad_tmpl : local.mke_launchpad_tmpl
}


output "mke_cluster" {
value = yamlencode(local.launchpad_tmpl)
}
59 changes: 59 additions & 0 deletions examples/terraform/gcp/modules/common/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
resource "tls_private_key" "ssh_key" {
algorithm = "RSA"
rsa_bits = "4096"
}

resource "local_file" "ssh_public_key" {
content = tls_private_key.ssh_key.private_key_pem
filename = "ssh_keys/${var.cluster_name}.pem"
provisioner "local-exec" {
command = "chmod 0600 ${local_file.ssh_public_key.filename}"
}
}

data "google_compute_image" "ubuntu" {
family = "ubuntu-1804-lts"
project = "ubuntu-os-cloud"
}

data "google_compute_image" "windows_2019" {
family = "windows-2019-core-for-containers"
project = "windows-cloud"
}

resource "google_compute_firewall" "common_internal" {
name = "${var.cluster_name}-internal"
description = "mke cluster common rule to allow all internal traffic"
network = var.vpc_name
direction = "INGRESS"
allow {
protocol = "all"
}

target_tags = ["allow-internal"]
source_tags = ["allow-internal"]
}

resource "google_compute_firewall" "common_ssh" {
name = "${var.cluster_name}-ssh"
description = "mke cluster common rule"
network = var.vpc_name
direction = "INGRESS"
allow {
protocol = "tcp"
ports = ["22"]
}
target_tags = ["allow-ssh"]
source_ranges = ["0.0.0.0/0"]
}

resource "google_compute_firewall" "common_all_egress" {
name = "${var.cluster_name}-all-egress"
description = "mke cluster common rule"
network = var.vpc_name
direction = "EGRESS"
allow {
protocol = "all"
}
destination_ranges = ["0.0.0.0/0"]
}
11 changes: 11 additions & 0 deletions examples/terraform/gcp/modules/common/outputs.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
output "image_name" {
value = data.google_compute_image.ubuntu.name
}

output "windows_2019_image_name" {
value = data.google_compute_image.windows_2019.name
}

output "ssh_key" {
value = tls_private_key.ssh_key
}
5 changes: 5 additions & 0 deletions examples/terraform/gcp/modules/common/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
variable "cluster_name" {}

variable "project_id" {}

variable "vpc_name" {}
88 changes: 88 additions & 0 deletions examples/terraform/gcp/modules/manager/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
data "google_client_openid_userinfo" "me" {}

resource "google_compute_firewall" "manager_internal" {
name = "${var.cluster_name}-managers-internal"
description = "mke cluster managers nodes internal traffic"
network = var.vpc_name
direction = "INGRESS"
allow {
protocol = "tcp"
ports = ["2379-2380"]
}

target_tags = ["allow-manager"]
source_tags = ["allow-manager"]
}

resource "google_compute_firewall" "manager" {
name = "${var.cluster_name}-managers"
description = "mke cluster managers ingress traffic"
network = var.vpc_name
direction = "INGRESS"
allow {
protocol = "tcp"
ports = ["443", "6443"]
}

source_ranges = ["0.0.0.0/0"]
target_tags = ["allow-manager"]
}

resource "google_compute_instance" "mke_manager" {
count = var.manager_count
name = "${var.cluster_name}-manager-${count.index + 1}"
machine_type = var.manager_type
zone = var.gcp_zone

metadata = tomap({
"role" = "manager"
ssh-keys = "ubuntu:${var.ssh_key.public_key_openssh}"
})

boot_disk {
initialize_params {
image = var.image_name
type = var.manager_volume_type
size = var.manager_volume_size
}
}

network_interface {
network = var.vpc_name
subnetwork = var.subnetwork_name
access_config {
}
}
tags = [
"allow-ssh",
"allow-manager",
"allow-internal"
]
}

resource "google_compute_instance_group" "default" {
name = "${var.cluster_name}-manager-group"
description = "Manager nodes instances group"
zone = var.gcp_zone
instances = [for i in google_compute_instance.mke_manager : i.self_link]

named_port {
name = "api"
port = 443
}

named_port {
name = "kubeapi"
port = 6443
}
}

module "load_balancer_manager" {
source = "../networklb"
region = var.gcp_region
network = var.vpc_name
name = "${var.cluster_name}-manager-lb"
service_ports = [443, 6443]
health_check_port = 443
target_instance_group = google_compute_instance_group.default.self_link
}
Loading

0 comments on commit 0cd835c

Please sign in to comment.