From 478b173c7bed053d47c1a7bd17d6deb878bc46f0 Mon Sep 17 00:00:00 2001 From: Tamas Kiss Date: Thu, 26 May 2022 01:29:23 +0200 Subject: [PATCH] init: copy from lawndale-infra --- .gitignore | 34 +++++++++++++++ .terraform.lock.hcl | 103 ++++++++++++++++++++++++++++++++++++++++++++ README.md | 32 ++++++++++++++ backend.tf | 10 +++++ drone.tf | 66 ++++++++++++++++++++++++++++ locals.tf | 4 ++ namespace.tf | 12 ++++++ oauth.tf | 6 +++ provider.tf | 37 ++++++++++++++++ runner.tf | 32 ++++++++++++++ volume.tf | 7 +++ 11 files changed, 343 insertions(+) create mode 100644 .gitignore create mode 100644 .terraform.lock.hcl create mode 100644 README.md create mode 100644 backend.tf create mode 100644 drone.tf create mode 100644 locals.tf create mode 100644 namespace.tf create mode 100644 oauth.tf create mode 100644 provider.tf create mode 100644 runner.tf create mode 100644 volume.tf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9b8a46e --- /dev/null +++ b/.gitignore @@ -0,0 +1,34 @@ +# Local .terraform directories +**/.terraform/* + +# .tfstate files +*.tfstate +*.tfstate.* + +# Crash log files +crash.log +crash.*.log + +# Exclude all .tfvars files, which are likely to contain sensitive data, such as +# password, private keys, and other secrets. These should not be part of version +# control as they are data points which are potentially sensitive and subject +# to change depending on the environment. +*.tfvars +*.tfvars.json + +# 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* + +# Ignore CLI configuration files +.terraformrc +terraform.rc diff --git a/.terraform.lock.hcl b/.terraform.lock.hcl new file mode 100644 index 0000000..613ed89 --- /dev/null +++ b/.terraform.lock.hcl @@ -0,0 +1,103 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/hashicorp/aws" { + version = "4.9.0" + constraints = "~> 4.9.0" + hashes = [ + "h1:GtmIOZMkKmr9tMLWouHWiGXmKEL/diOTNar5XfOVLjs=", + "zh:084b83aef3335ad4f5e4b8323c6fe43c1ff55e17a7647c6a5cad6af519f72b42", + "zh:132e47ce69f14de4523b84b213cedf7173398acda14245b1ffe7747aac50f050", + "zh:2068baef7dfce3613f3b4f27314175e971f8db68d9cde9ec30b5659f80c68c6c", + "zh:63c6f489683d5f1ac55e82a0df387143ed22701d5f22c109a4d5c9924dd4e437", + "zh:8115fd21965954fa4568c09331e05bb29da967fab8d077419aed09954378e216", + "zh:8efdc95fde108f777ed9c79ae25dc17aea9771903250f5c5c8a4c726b90a345f", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9d42a7bc34d84b70c1d1bcc215cabd63abbcbd0352b70bd84da6c3916634932f", + "zh:aacbcceb241aa475888c0869e87593182edeced3170c76a0c960dd9c905df449", + "zh:c7fe7904511052e4102870256819a1917177572cf684f0611ebf767f9c1fbaa8", + "zh:c8e07c3424663d1d0e7e32f4ade8099c19f6326d37c6da98104d90c986ff66fc", + "zh:e47cafbd38b56ef14fd8d727b4ffea847c166b1c684f585ee5fb78983b537248", + ] +} + +provider "registry.terraform.io/hashicorp/helm" { + version = "2.5.1" + constraints = "2.5.1" + hashes = [ + "h1:NasRPC0qqlpGqcF3dsSoOFu7uc5hM+zJm+okd8FgrnQ=", + "zh:140b9748f0ad193a20d69e59d672f3c4eda8a56cede56a92f931bd3af020e2e9", + "zh:17ae319466ed6538ad49e011998bb86565fe0e97bc8b9ad7c8dda46a20f90669", + "zh:3a8bd723c21ba70e19f0395ed7096fc8e08bfc23366f1c3f06a9107eb37c572c", + "zh:3aae3b82adbe6dca52f1a1c8cf51575446e6b0f01f1b1f3b30de578c9af4a933", + "zh:3f65221f40148df57d2888e4f31ef3bf430b8c5af41de0db39a2b964e1826d7c", + "zh:650c74c4f46f5eb01df11d8392bdb7ebee3bba59ac0721000a6ad731ff0e61e2", + "zh:930fb8ab4cd6634472dfd6aa3123f109ef5b32cbe6ef7b4695fae6751353e83f", + "zh:ae57cd4b0be4b9ca252bc5d347bc925e35b0ed74d3dcdebf06c11362c1ac3436", + "zh:d15b1732a8602b6726eac22628b2f72f72d98b75b9c6aabceec9fd696fda696a", + "zh:d730ede1656bd193e2aea5302acec47c4905fe30b96f550196be4a0ed5f41936", + "zh:f010d4f9d8cd15936be4df12bf256cb2175ca1dedb728bd3a866c03d2ee7591f", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/kubernetes" { + version = "2.11.0" + constraints = "2.11.0" + hashes = [ + "h1:pJiAJwZKUaoAJ4x+3ONJkwEVkjrwGROCGFgj7noPO58=", + "zh:143a19dd0ea3b07fc5e3d9231f3c2d01f92894385c98a67327de74c76c715843", + "zh:1fc757d209e09c3cf7848e4274daa32408c07743698fbed10ee52a4a479b62b6", + "zh:22dfebd0685749c51a8f765d51a1090a259778960ac1cd4f32021a325b2b9b72", + "zh:3039b3b76e870cd8fc404cf75a29c66b171c6ba9b6182e131b6ae2ca648ec7c0", + "zh:3af0a15562fcab4b5684b18802e0239371b2b8ff9197ed069ff4827f795a002b", + "zh:50aaf20336d1296a73315adb66f7687f75bd5c6b1f93a894b95c75cc142810ec", + "zh:682064fabff895ec351860b4fe0321290bbbb17c2a410b62c9bea0039400650e", + "zh:70ac914d5830b3371a2679d8f77cc20c419a6e12925145afae6c977c8eb90934", + "zh:710aa02cccf7b0f3fb50880d6d2a7a8b8c9435248666616844ba71f74648cddc", + "zh:88e418118cd5afbdec4984944c7ab36950bf48e8d3e09e090232e55eecfb470b", + "zh:9cef159377bf23fa331f8724fdc6ce27ad39a217a4bae6df3b1ca408fc643da6", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.2.0" + hashes = [ + "h1:eeUh6cJ6wKLLuo4q9uQ0CA1Zvfqya4Wn1LecLCN8KKs=", + "zh:2960977ce9a7d6a7d3e934e75ec5814735626f95c186ad95a9102344a1a38ac1", + "zh:2fd012abfabe7076f3f2f402eeef4970e20574d20ffec57c162b02b6e848c32f", + "zh:4cd3234671cf01c913023418b227eb78b0659f2cd2e0b387be1f0bb607d29889", + "zh:52e695b4fa3fae735ffc901edff8183745f980923510a744db7616e8f10dc499", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:848b4a294e5ba15192ee4bfd199c07f60a437d7572efcd2d89db036e1ebc0e6e", + "zh:9d49aa432a05748a9527e95448cebee1238c87c97c7e8dec694bfd709683f9c7", + "zh:b4ad4cf289d3f7408649b74b8639918833613f2a1f3cf51b51f4b2fdaa412dd2", + "zh:c1544c4b416096fb8d8dbf84c4488584a2844a30dd533b957e9e9e60a165f24e", + "zh:dc737d6b4591cad8c9a1d0b347e587e846d8d901789b29b4dd401b6cdf82c017", + "zh:f5645fd39f749dbbf847cbdc87ba0dbd141143f12917a6a8904faf8a9b64111e", + "zh:fdedf610e0d020878a8f1fedda8105e0c33a7e23c4792fca54460685552de308", + ] +} + +provider "registry.terraform.io/malarinv/gitea" { + version = "0.0.4" + hashes = [ + "h1:W4u/HfWhyc1zXRb0KHL/dsJWHdyYo+sXAwSJJHDf+PE=", + "zh:20d7d5ee0ebbb0359b014cb6f66b2d94fb3dd5e53abc50313d3fb9b85c629e01", + "zh:21086620ed6a41d7189a00a3caadbd68648311824e4aee842a661ea79e7b0ffe", + "zh:334ebed7a13f503b5a538d56c461f2a42f8ed108776868c076dd7880fab68455", + "zh:3f52c69f0d5dce1b3c04df6c60362bfd43925cbaa9a81698e9721cb58890351f", + "zh:5c475d8ecff582dde0d3e4f02587c730e00efe3b10e1b6d0cd612b25de9303c6", + "zh:5cd331d2dfa47abb3f9950b110fc54dd1674101e61d77ca3f9666175db0aa3f2", + "zh:784bfaff53e564f7ab04e04e9cb821bee8c68e40834009d69424c1d8f54d9a19", + "zh:a4f7176a311c52bb8f47c0ea755ca8d1899fd3155022a11540019a73dee0a73e", + "zh:cd56c1b847d24d3b917836257a88423d76032a908e5822306526f536baea1f2f", + "zh:deecf94952f5e77e452b56fa6a4e2d652e167ee0df4b57fe35e0c37a9c3db58d", + "zh:dfa6529978b92d8db22f2040172d895d4a07e4e46346d4fc1ab3041c508732fd", + "zh:ecf4c9d84348c25049c8ac5d5477807f7cc72b33ecd816cc11f721066dc7fbac", + "zh:f569b65999264a9416862bca5cd2a6177d94ccb0424f3a4ef424428912b9cb3c", + "zh:f58d45a08c6f51da91bcc27ff3095edc03a04897c76a60dfada1c3a6f26daf41", + "zh:f8461ecc0df2c0d6abfd383270b08a7d216d9188f89ef3a30435b8f6a935a1fe", + ] +} diff --git a/README.md b/README.md new file mode 100644 index 0000000..a57bde7 --- /dev/null +++ b/README.md @@ -0,0 +1,32 @@ +# Terraform config for drone +Drone is a self-hosted Continuous Integration platform. This terraform root module will create a Gitea OAuth2 application, a persistent volume for Drone and installs Drone to a Kubernetes namespace on Lawndale. + +**This module assumes Lawndale as the hosting environment!** + +## Provider configurations +The following providers are used and should be configured before calling `init` or `apply`. + +### AWS +AWS is only used for state backend. Check out [AWS Provider config](https://registry.terraform.io/providers/hashicorp/aws/latest/docs#authentication-and-configuration). + +### Gitea +Either `GITEA_TOKEN` or `GITEA_USERNAME` and `GITEA_PASSWORD` must be set for authentication. + +### Kubernetes / Helm +Drone is provisioned with Helm on a kubernetes cluster. + +Helm is using the same environment variables as the Kubernetes provider. + +Set `KUBE_CONFIG_PATH` to use a kubeconfig file, and `KUBE_CTX` to use a different context than set in the kubeconfig. + +For token auth, set `KUBE_TOKEN` and `KUBE_HOST` environment vars. + +A PEM-encoded root certificates bundle for TLS authentication can be sourced by setting +`KUBE_CLUSTER_CA_CERT_DATA`. + +Sources: +[Kubernetes](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs#argument-reference) +[Helm](https://registry.terraform.io/providers/hashicorp/helm/latest/docs) + +## Persistent volume +Persistence is supported by [terraform-modules//9p-persistent-volume](git.thomasklein.me/thomasklein/terraform-modules/9p-persistent-volume). diff --git a/backend.tf b/backend.tf new file mode 100644 index 0000000..486d15d --- /dev/null +++ b/backend.tf @@ -0,0 +1,10 @@ +terraform { + backend "s3" { + bucket = "thomasklein-global-states" + key = "apps/lawndale/drone" + region = "eu-central-1" + encrypt = true + kms_key_id = "a767a3ce-c505-44c0-9f93-6f53678c69c7" + dynamodb_table = "thomasklein-global-state-locks" + } +} diff --git a/drone.tf b/drone.tf new file mode 100644 index 0000000..fe517a0 --- /dev/null +++ b/drone.tf @@ -0,0 +1,66 @@ + +resource "helm_release" "drone_server" { + name = "drone" + chart = "drone" + repository = "https://charts.drone.io" + namespace = kubernetes_namespace.server.metadata.0.name + create_namespace = false + + values = [ + jsonencode({ + env = { + DRONE_SERVER_HOST = local.ingress_domain + DRONE_SERVER_PROTO = "https" + DRONE_GITEA_SERVER = "https://${local.gitea_server}/" + } + }), + jsonencode({ + ingress = { + enabled = true + annotations = { + "kubernetes.io/ingress.class" = "traefik" + "traefik.ingress.kubernetes.io/router.entrypoints" = "websecure" + "traefik.ingress.kubernetes.io/router.tls" = "true" + "traefik.ingress.kubernetes.io/router.tls.certresolver" = "acme-thomasklein-me" + "traefik.ingress.kubernetes.io/router.tls.domains.0.main" = local.ingress_domain + } + hosts = [ + { + host = local.ingress_domain + paths = [ + { + path = "/" + pathType = "Prefix" + } + ] + } + ] + } + }), + jsonencode({ + persistentVolume = { + enabled = true + existingClaim = module.drone_persistance.pvc_name + } + }) + ] + + set_sensitive { + name = "env.DRONE_RPC_SECRET" + value = random_password.drone_rpc_secret.result + } + + set_sensitive { + name = "env.DRONE_GITEA_CLIENT_ID" + value = gitea_oauth2_app.this.client_id + } + set_sensitive { + name = "env.DRONE_GITEA_CLIENT_SECRET" + value = gitea_oauth2_app.this.client_secret + } +} + +resource "random_password" "drone_rpc_secret" { + special = true + length = 32 +} \ No newline at end of file diff --git a/locals.tf b/locals.tf new file mode 100644 index 0000000..fddc08d --- /dev/null +++ b/locals.tf @@ -0,0 +1,4 @@ +locals { + gitea_server = "git.thomasklein.me" + ingress_domain = "drone.thomasklein.me" +} diff --git a/namespace.tf b/namespace.tf new file mode 100644 index 0000000..ed29a95 --- /dev/null +++ b/namespace.tf @@ -0,0 +1,12 @@ + +resource "kubernetes_namespace" "server" { + metadata { + name = "drone" + } +} + +resource "kubernetes_namespace" "jobs" { + metadata { + name = "drone-jobs" + } +} diff --git a/oauth.tf b/oauth.tf new file mode 100644 index 0000000..16e290d --- /dev/null +++ b/oauth.tf @@ -0,0 +1,6 @@ +resource "gitea_oauth2_app" "this" { + name = "Drone" + redirect_uris = [ + "https://drone.thomasklein.me/login", + ] +} diff --git a/provider.tf b/provider.tf new file mode 100644 index 0000000..f37043d --- /dev/null +++ b/provider.tf @@ -0,0 +1,37 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.9.0" + } + + gitea = { + source = "malarinv/gitea" + } + + helm = { + source = "hashicorp/helm" + version = "2.5.1" + } + + kubernetes = { + source = "hashicorp/kubernetes" + version = "2.11.0" + } + + } +} + +provider "gitea" { + base_url = "https://${local.gitea_server}" + token = "915f506e315f263bec1ee7440dff065395e81462" +} + +provider "aws" { + # Configuration options + default_tags { + tags = { + "managed-by" = "terraform" + } + } +} diff --git a/runner.tf b/runner.tf new file mode 100644 index 0000000..0932e34 --- /dev/null +++ b/runner.tf @@ -0,0 +1,32 @@ +resource "helm_release" "drone_runner" { + name = "runner" + chart = "drone-runner-kube" + repository = "https://charts.drone.io" + namespace = kubernetes_namespace.server.metadata.0.name + create_namespace = false + + values = [jsonencode({ + rbac = { + buildNamespaces = [ + kubernetes_namespace.jobs.metadata.0.name + ] + } + }), + jsonencode({ + env = { + DRONE_SERVER_HOST = "https://${local.ingress_domain}" + DRONE_RPC_HOST = "${helm_release.drone_server.name}.${helm_release.drone_server.namespace}.svc.cluster.local" + DRONE_RPC_PROTO = "http" + } + }), + jsonencode({ + ingress = { + enabled = false + } + }) + ] + set_sensitive { + name = "env.DRONE_RPC_SECRET" + value = random_password.drone_rpc_secret.result + } +} diff --git a/volume.tf b/volume.tf new file mode 100644 index 0000000..47c581c --- /dev/null +++ b/volume.tf @@ -0,0 +1,7 @@ +module "drone_persistance" { + source = "git@git.thomasklein.me:thomasklein/terraform-modules//9p-persistent-volume" + + namespace = kubernetes_namespace.server.metadata.0.name + name = "drone" + volume_storage_capacity = "2Gi" +}