forked from kubernetes-sigs/kubespray
-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added gcp terraform support (kubernetes-sigs#6974)
* Added gcp terraform support * Added http/https firewall rule * Ignoring lifecycle changes for attached disks on the google_compute_instance
- Loading branch information
Showing
9 changed files
with
778 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
# Kubernetes on GCP with Terraform | ||
|
||
Provision a Kubernetes cluster on GCP using Terraform and Kubespray | ||
|
||
## Overview | ||
|
||
The setup looks like following | ||
|
||
``` | ||
Kubernetes cluster | ||
+-----------------------+ | ||
+---------------+ | +--------------+ | | ||
| | | | +--------------+ | | ||
| API server LB +---------> | | | | | ||
| | | | | Master/etcd | | | ||
+---------------+ | | | node(s) | | | ||
| +-+ | | | ||
| +--------------+ | | ||
| ^ | | ||
| | | | ||
| v | | ||
+---------------+ | +--------------+ | | ||
| | | | +--------------+ | | ||
| Ingress LB +---------> | | | | | ||
| | | | | Worker | | | ||
+---------------+ | | | node(s) | | | ||
| +-+ | | | ||
| +--------------+ | | ||
+-----------------------+ | ||
``` | ||
|
||
## Requirements | ||
|
||
* Terraform 0.12.0 or newer | ||
|
||
## Quickstart | ||
|
||
To get a cluster up and running you'll need a JSON keyfile. | ||
Set the path to the file in the `tfvars.json` file and run the following: | ||
|
||
```bash | ||
terraform apply -var-file tfvars.json -state dev-cluster.tfstate -var gcp_project_id=<ID of your GCP project> -var keyfile_location=<location of the json keyfile> | ||
``` | ||
|
||
To generate kubespray inventory based on the terraform state file you can run the following: | ||
|
||
```bash | ||
./generate-inventory.sh dev-cluster.tfstate > inventory.ini | ||
``` | ||
|
||
You should now have a inventory file named `inventory.ini` that you can use with kubespray, e.g. | ||
|
||
```bash | ||
ansible-playbook -i contrib/terraform/gcs/inventory.ini cluster.yml -b -v | ||
``` | ||
|
||
## Variables | ||
|
||
### Required | ||
|
||
* `keyfile_location`: Location to the keyfile to use as credentials for the google terraform provider | ||
* `gcp_project_id`: ID of the GCP project to deploy the cluster in | ||
* `ssh_pub_key`: Path to public ssh key to use for all machines | ||
* `region`: The region where to run the cluster | ||
* `machines`: Machines to provision. Key of this object will be used as the name of the machine | ||
* `node_type`: The role of this node *(master|worker)* | ||
* `size`: The size to use | ||
* `zone`: The zone the machine should run in | ||
* `additional_disks`: Extra disks to add to the machine. Key of this object will be used as the disk name | ||
* `size`: Size of the disk (in GB) | ||
* `boot_disk`: The boot disk to use | ||
* `image_name`: Name of the image | ||
* `size`: Size of the boot disk (in GB) | ||
* `ssh_whitelist`: List of IP ranges (CIDR) that will be allowed to ssh to the nodes | ||
* `api_server_whitelist`: List of IP ranges (CIDR) that will be allowed to connect to the API server | ||
* `nodeport_whitelist`: List of IP ranges (CIDR) that will be allowed to connect to the kubernetes nodes on port 30000-32767 (kubernetes nodeports) | ||
|
||
### Optional | ||
|
||
* `prefix`: Prefix to use for all resources, required to be unique for all clusters in the same project *(Defaults to `default`)* | ||
* `master_sa_email`: Service account email to use for the master nodes *(Defaults to `""`, auto generate one)* | ||
* `master_sa_scopes`: Service account email to use for the master nodes *(Defaults to `["https://www.googleapis.com/auth/cloud-platform"]`)* | ||
* `worker_sa_email`: Service account email to use for the worker nodes *(Defaults to `""`, auto generate one)* | ||
* `worker_sa_scopes`: Service account email to use for the worker nodes *(Defaults to `["https://www.googleapis.com/auth/cloud-platform"]`)* | ||
|
||
An example variables file can be found `tfvars.json` | ||
|
||
## Known limitations | ||
|
||
This solution does not provide a solution to use a bastion host. Thus all the nodes must expose a public IP for kubespray to work. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#!/bin/bash | ||
|
||
# | ||
# Generates a inventory file based on the terraform output. | ||
# After provisioning a cluster, simply run this command and supply the terraform state file | ||
# Default state file is terraform.tfstate | ||
# | ||
|
||
set -e | ||
|
||
usage () { | ||
echo "Usage: $0 <state file>" >&2 | ||
exit 1 | ||
} | ||
|
||
if [[ $# -ne 1 ]]; then | ||
usage | ||
fi | ||
|
||
TF_STATE_FILE=${1} | ||
|
||
if [[ ! -f "${TF_STATE_FILE}" ]]; then | ||
echo "ERROR: state file ${TF_STATE_FILE} doesn't exist" >&2 | ||
usage | ||
fi | ||
|
||
TF_OUT=$(terraform output -state "${TF_STATE_FILE}" -json) | ||
|
||
MASTERS=$(jq -r '.master_ips.value | to_entries[]' <(echo "${TF_OUT}")) | ||
WORKERS=$(jq -r '.worker_ips.value | to_entries[]' <(echo "${TF_OUT}")) | ||
mapfile -t MASTER_NAMES < <(jq -r '.key' <(echo "${MASTERS}")) | ||
mapfile -t WORKER_NAMES < <(jq -r '.key' <(echo "${WORKERS}")) | ||
|
||
API_LB=$(jq -r '.control_plane_lb_ip_address.value' <(echo "${TF_OUT}")) | ||
|
||
# Generate master hosts | ||
i=1 | ||
for name in "${MASTER_NAMES[@]}"; do | ||
private_ip=$(jq -r '. | select( .key=='"\"${name}\""' ) | .value.private_ip' <(echo "${MASTERS}")) | ||
public_ip=$(jq -r '. | select( .key=='"\"${name}\""' ) | .value.public_ip' <(echo "${MASTERS}")) | ||
echo "${name} ansible_user=ubuntu ansible_host=${public_ip} ip=${private_ip} etcd_member_name=etcd${i}" | ||
i=$(( i + 1 )) | ||
done | ||
|
||
# Generate worker hosts | ||
for name in "${WORKER_NAMES[@]}"; do | ||
private_ip=$(jq -r '. | select( .key=='"\"${name}\""' ) | .value.private_ip' <(echo "${WORKERS}")) | ||
public_ip=$(jq -r '. | select( .key=='"\"${name}\""' ) | .value.public_ip' <(echo "${WORKERS}")) | ||
echo "${name} ansible_user=ubuntu ansible_host=${public_ip} ip=${private_ip}" | ||
done | ||
|
||
echo "" | ||
echo "[kube-master]" | ||
for name in "${MASTER_NAMES[@]}"; do | ||
echo "${name}" | ||
done | ||
|
||
echo "" | ||
echo "[kube-master:vars]" | ||
echo "supplementary_addresses_in_ssl_keys = [ '${API_LB}' ]" # Add LB address to API server certificate | ||
echo "" | ||
echo "[etcd]" | ||
for name in "${MASTER_NAMES[@]}"; do | ||
echo "${name}" | ||
done | ||
|
||
echo "" | ||
echo "[kube-node]" | ||
for name in "${WORKER_NAMES[@]}"; do | ||
echo "${name}" | ||
done | ||
|
||
echo "" | ||
echo "[k8s-cluster:children]" | ||
echo "kube-master" | ||
echo "kube-node" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
provider "google" { | ||
credentials = file(var.keyfile_location) | ||
region = var.region | ||
project = var.gcp_project_id | ||
version = "~> 3.48" | ||
} | ||
|
||
module "kubernetes" { | ||
source = "./modules/kubernetes-cluster" | ||
region = var.region | ||
prefix = var.prefix | ||
|
||
machines = var.machines | ||
ssh_pub_key = var.ssh_pub_key | ||
|
||
master_sa_email = var.master_sa_email | ||
master_sa_scopes = var.master_sa_scopes | ||
worker_sa_email = var.worker_sa_email | ||
worker_sa_scopes = var.worker_sa_scopes | ||
|
||
ssh_whitelist = var.ssh_whitelist | ||
api_server_whitelist = var.api_server_whitelist | ||
nodeport_whitelist = var.nodeport_whitelist | ||
} |
Oops, something went wrong.