From 8ed0459864872b1e2bc6534f2aa2f63939cbc17c Mon Sep 17 00:00:00 2001 From: romanprog Date: Mon, 25 Jan 2021 09:40:49 +0000 Subject: [PATCH] Initial commit --- .gitignore | 29 ++++++++++++++++++++++++ .pre-commit-config.yaml | 41 ++++++++++++++++++++++++++++++++++ README.md | 40 ++++++++++++++++++++++++++++++++- examples/full/init.tf | 13 +++++++++++ examples/full/main.tf | 37 +++++++++++++++++++++++++++++++ init.tf | 9 ++++++++ locals.tf | 27 +++++++++++++++++++++++ main.tf | 41 ++++++++++++++++++++++++++++++++++ outputs.tf | 11 +++++++++ variables.tf | 49 +++++++++++++++++++++++++++++++++++++++++ 10 files changed, 296 insertions(+), 1 deletion(-) create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 examples/full/init.tf create mode 100644 examples/full/main.tf create mode 100644 init.tf create mode 100644 locals.tf create mode 100644 main.tf create mode 100644 outputs.tf create mode 100644 variables.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7a3e2fd --- /dev/null +++ b/.gitignore @@ -0,0 +1,29 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log + +# Ignore any .tfvars files that are generated automatically for each Terraform run. Most +# .tfvars files are managed as part of configuration and so should be included in +# version control. +# +# example.tfvars + +# Ignore override files as they are usually used to override resources locally and so +# are not checked in +override.tf +override.tf.json +*_override.tf +*_override.tf.json + +# Include override files you do wish to add to version control using negated pattern +# +# !example_override.tf + +# Include tfplan files to ignore the plan output of command: terraform plan -out=tfplan +# example: *tfplan* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..5356e05 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,41 @@ +# How to install: +# pre-commit install --install-hooks && pre-commit install --install-hooks -t commit-msg + +# How temporary skip one of hooks: https://pre-commit.com/#temporarily-disabling-hooks + +repos: +####### +# ALL # +####### +- repo: git://github.com/pre-commit/pre-commit-hooks + rev: v2.2.3 + hooks: + # Git style + - id: check-added-large-files + - id: check-merge-conflict + - id: check-vcs-permalinks + - id: forbid-new-submodules + - id: no-commit-to-branch + + # Common errors + - id: end-of-file-fixer + - id: trailing-whitespace + args: [--markdown-linebreak-ext=md] + + # Cross platform + - id: check-case-conflict + + # Security + - id: detect-aws-credentials + args: ['--allow-missing-credentials'] + - id: detect-private-key + +############# +# TERRAFORM # +############# +- repo: git://github.com/antonbabenko/pre-commit-terraform + rev: v1.43.0 + hooks: + - id: terraform_fmt + - id: terraform_docs +# - id: terraform_validate diff --git a/README.md b/README.md index 4dd4220..1d71cea 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,40 @@ # terraform-do-k8s -Terraform module to create an managed kubernetes cluster in DigitalOcean cloud. +Terraform module to create an managed kubernetes cluster in DigitalOcean cloud. + + +## Requirements + +| Name | Version | +|------|---------| +| terraform | ~> 0.13.0 | +| digitalocean | ~> 2.4.0 | + +## Providers + +| Name | Version | +|------|---------| +| digitalocean | ~> 2.4.0 | + +## Inputs + +| Name | Description | Type | Default | Required | +|------|-------------|------|---------|:--------:| +| additional\_node\_groups | A list of worker groups configs | `any` | `[]` | no | +| cluster\_name | (Required) Provide DigitalOcean cluster name | `string` | n/a | yes | +| default\_node\_group | n/a | `any` | `{}` | no | +| k8s\_version | Provide DigitalOcean Kubernetes minor version (e.g. '1.15' or higher) | `string` | `"1.19.3-do"` | no | +| kubeconfig\_bucket | Bucket name for kubeconfig upload | `string` | n/a | yes | +| kubeconfig\_bucket\_key | Path and filename og kubeconfig in do spaces bucket | `string` | `"kubeconfig"` | no | +| kubeconfig\_bucket\_region | Region of bucket name for kubeconfig upload. Default will be set to kluster rregion. | `string` | `""` | no | +| region | (Required) Provide DigitalOcean region | `string` | n/a | yes | +| vpc\_id | VPC id | `string` | n/a | yes | + +## Outputs + +| Name | Description | +|------|-------------| +| cluster\_endpoint | n/a | +| cluster\_status | n/a | +| kubeconfig | n/a | + + diff --git a/examples/full/init.tf b/examples/full/init.tf new file mode 100644 index 0000000..1ae2d93 --- /dev/null +++ b/examples/full/init.tf @@ -0,0 +1,13 @@ +terraform { + backend "s3" { + bucket = "k8s-data" + key = "k8s-cdev/k8s" + region = "us-east-1" + endpoint = "ams3.digitaloceanspaces.com" + skip_credentials_validation = true + skip_metadata_api_check = true + access_key = "" + secret_key = "" + } + required_version = "~> 0.13" +} diff --git a/examples/full/main.tf b/examples/full/main.tf new file mode 100644 index 0000000..f0e07d9 --- /dev/null +++ b/examples/full/main.tf @@ -0,0 +1,37 @@ +variable "region" { + type = string + default = "ams3" +} + +data "digitalocean_vpc" "default" { + region = var.region +} + +module "k8s" { + source = "../../" + additional_node_groups = { + ng2 = { + auto_scale = false + node_count = 2 + node_type = "s-1vcpu-2gb" + } + ng3 = { + auto_scale = true + max_nodes = 3 + min_nodes = 1 + node_type = "s-1vcpu-2gb" + } + } + cluster_name = "k8s-cluster" + region = var.region + vpc_id = data.digitalocean_vpc.default.vpc_id + k8s_version = "1.19.3-do" + kubeconfig_bucket = "k8s-data" + default_node_group = { + auto_scale = true + max_nodes = 3 + min_nodes = 1 + name = "default-ng" + node_type = "s-1vcpu-2gb" + } +} diff --git a/init.tf b/init.tf new file mode 100644 index 0000000..daf37e5 --- /dev/null +++ b/init.tf @@ -0,0 +1,9 @@ +terraform { + required_version = "~> 0.13.0" + required_providers { + digitalocean = { + version = "~> 2.4.0" + source = "digitalocean/digitalocean" + } + } +} diff --git a/locals.tf b/locals.tf new file mode 100644 index 0000000..f13e420 --- /dev/null +++ b/locals.tf @@ -0,0 +1,27 @@ +locals { + kubeconfig_bucket_regoin = var.kubeconfig_bucket_region == "" ? var.region : var.kubeconfig_bucket_region + default_nodes_tags = [] + default_nodes_labels = {} + default_node_group = { + min_nodes = lookup(var.default_node_group, "min_nodes", null) + max_nodes = lookup(var.default_node_group, "max_nodes", null) + node_count = lookup(var.default_node_group, "node_count", null) + auto_scale = lookup(var.default_node_group, "auto_scale", null) + node_type = var.default_node_group.node_type + name = var.default_node_group.name + labels = merge(lookup(var.default_node_group, "labels", {}), local.default_nodes_labels) + tags = concat(lookup(var.default_node_group, "tags", []), local.default_nodes_tags) + } + worker_groups_map = { + for key, node_group_config in var.additional_node_groups : + key => { + min_nodes = lookup(node_group_config, "min_nodes", null) + max_nodes = lookup(node_group_config, "max_nodes", null) + node_count = lookup(node_group_config, "node_count", null) + auto_scale = lookup(node_group_config, "auto_scale", null) + node_type = node_group_config.node_type + labels = merge(lookup(node_group_config, "labels", {}), local.default_nodes_labels) + tags = concat(lookup(node_group_config, "tags", []), local.default_nodes_tags) + } + } +} diff --git a/main.tf b/main.tf new file mode 100644 index 0000000..73d153a --- /dev/null +++ b/main.tf @@ -0,0 +1,41 @@ +data "digitalocean_kubernetes_versions" "k8s" { + version_prefix = "${var.k8s_version}." +} + +resource "digitalocean_kubernetes_cluster" "k8s" { + name = var.cluster_name + region = var.region + version = data.digitalocean_kubernetes_versions.k8s.latest_version + vpc_uuid = var.vpc_id + + node_pool { + name = "${var.cluster_name}-worker-pool" + size = local.default_node_group.node_type + auto_scale = local.default_node_group.auto_scale + min_nodes = local.default_node_group.min_nodes + max_nodes = local.default_node_group.max_nodes + node_count = local.default_node_group.node_count + labels = local.default_node_group.labels + tags = local.default_node_group.tags + } +} + +resource "digitalocean_spaces_bucket_object" "kubeconfig" { + region = local.kubeconfig_bucket_regoin + bucket = var.kubeconfig_bucket + key = var.kubeconfig_bucket_key + content = digitalocean_kubernetes_cluster.k8s.kube_config.0.raw_config +} + +resource "digitalocean_kubernetes_node_pool" "additional_pool" { + for_each = local.worker_groups_map + cluster_id = digitalocean_kubernetes_cluster.k8s.id + name = each.key + size = each.value.node_type + auto_scale = each.value.auto_scale + min_nodes = each.value.min_nodes + max_nodes = each.value.max_nodes + node_count = each.value.node_count + labels = each.value.labels + tags = each.value.tags +} diff --git a/outputs.tf b/outputs.tf new file mode 100644 index 0000000..9883b26 --- /dev/null +++ b/outputs.tf @@ -0,0 +1,11 @@ +output "cluster_status" { + value = digitalocean_kubernetes_cluster.k8s.status +} + +output "cluster_endpoint" { + value = digitalocean_kubernetes_cluster.k8s.endpoint +} + +output "kubeconfig" { + value = digitalocean_kubernetes_cluster.k8s.kube_config.0.raw_config +} diff --git a/variables.tf b/variables.tf new file mode 100644 index 0000000..e554ec9 --- /dev/null +++ b/variables.tf @@ -0,0 +1,49 @@ +variable cluster_name { + type = string + description = "(Required) Provide DigitalOcean cluster name" +} + +variable region { + type = string + description = "(Required) Provide DigitalOcean region" +} + +variable default_node_group { + type = any + default = {} +} + + +variable k8s_version { + type = string + description = "Provide DigitalOcean Kubernetes minor version (e.g. '1.15' or higher)" + default = "1.19.3-do" +} + +variable vpc_id { + type = string + description = "VPC id" +} + +variable kubeconfig_bucket { + type = string + description = "Bucket name for kubeconfig upload" +} + +variable kubeconfig_bucket_region { + type = string + description = "Region of bucket name for kubeconfig upload. Default will be set to kluster rregion." + default = "" +} + +variable kubeconfig_bucket_key { + type = string + description = "Path and filename og kubeconfig in do spaces bucket" + default = "kubeconfig" +} + +variable additional_node_groups { + description = "A list of worker groups configs" + default = [] + type = any +}