init: copy from lawndale-infra

This commit is contained in:
2022-05-27 02:51:52 +02:00
commit 6a60d271bf
18 changed files with 1126 additions and 0 deletions

34
.gitignore vendored Normal file
View File

@@ -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

202
.terraform.lock.hcl generated Normal file
View File

@@ -0,0 +1,202 @@
# This file is maintained automatically by "terraform init".
# Manual edits may be lost in future updates.
provider "registry.terraform.io/cloudflare/cloudflare" {
version = "3.15.0"
constraints = "~> 3.15.0"
hashes = [
"h1:EZYITYZwM0Ie9Ny2+95q1xMaoNxJbPW8YwDSFOWViyw=",
"zh:06e8fd36d498dc5dbb63e71dfe58b5847ef448f9db84bf839f65042ba08d541e",
"zh:1dfbd6a6d7110b2d92c9f4e488f95c7f0e82d08ef4ac586dcb10738aac3d37c6",
"zh:2065ced5158da83317cea53042e6e76d28e1c30b64cd7c926acb4744779753b5",
"zh:33482a59c7eec72737cd6e89c6b93f852af7f56718dc5b8f04f23942cede0a99",
"zh:3c7fd43b8c14c3d2b640630a30dffe89a45cecaa0a5d12a1708c63df8b662bd1",
"zh:56cc8bebf7ad2f4e3d4e617db4f597f1bbfca07b5e24c2b52723dfbaf1ffa171",
"zh:58c8edd959e6197194f155787ed0472439acb2ca110c00ad7d94346b6c569ec4",
"zh:8864ca51ce185482e187d329c8e4ccebd145d834f70b7a44509f536d7cb5e6d5",
"zh:942eca8b278447bcf3da2350521470f038a87d87009d02de4dc681f67fe6e4a6",
"zh:a8d849d31a2a50c5faf673b0a442c8eeda43f44ebaa48534bc67bd21c1d81014",
"zh:b52d4d70be1065f67115468824495cd341e0404e543259300f774a556ad6b610",
"zh:c6a0b092f5b68799680a28710e50ff55a8d64a880a1d31069798c9551f1c4759",
"zh:d997b9fcd3e3ee1ca4b92ac2e00505c9503f68de6054a5efd751a3d3c976ce5f",
"zh:f0219d03d25cbdd9338a17a6c42016c20bc254187b0f507215ad87060c46e88d",
]
}
provider "registry.terraform.io/dmacvicar/libvirt" {
version = "0.6.14"
constraints = "0.6.14, ~> 0.6.14"
hashes = [
"h1:JyRYY5LmhQKvolpmwcfiWWlFJMMfvQKqP3PRWT0I2JU=",
"zh:0450e09888e0399722d6714467d5f0a61d2ab6505cd4c66423d58dd98404da80",
"zh:263c80ca9743bcc699983803b85cac19f833663478b644c2b3000a6f3e1b5070",
"zh:2a3eda5b0dc170afd4339910396e6087181dd0f37da0d83ee175fed2975a5a40",
"zh:363b8385d3340688fe58c67ea1e798d99892e25ac0a38f3e3fd615968b829e3e",
"zh:517efa2132c6ff6a849abea324916884a2d8e9361197209c56da99d1419542a3",
"zh:5f1424da9a9c9aef6b5583861750ed958fff4f1f85e17a493b58aff05b5a731b",
"zh:778bd0ea056ed7e918bcc3c05ad651504af86e6b53e6480daf20879e7d01e0a1",
"zh:8576f08eff1596d96072e6eb0c29febbbe316cc26537a949be76c71659bd3b63",
"zh:a1f5bbadad4f809d4b96a332bda1b48787d08a8bf3bf23b40e68138fbaa727fb",
"zh:b24e1f6f1bd09acdfb87f76f76ee7adfa1af1e0798c8c0aeb20d2a5bf67d8a33",
"zh:b6359aab7499b6fab819c867901b32426eb8661f2279e12c0c07cbeadce119e1",
"zh:ca357e2424a41058571f4b437a5e440395755461dcc1041cbbb41ea23c29eab5",
"zh:ec57e6e3ee701522d2cfd57a8ae307e76bff4f4a4af36c0e10d4189fa8dd554d",
"zh:f46534893933d5b11f32fb0d55044ba84f4e69147955d0454a208c494bbb0882",
]
}
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/dns" {
version = "3.2.3"
constraints = "~> 3.2, ~> 3.2.3"
hashes = [
"h1:ODcR+vWOhCAJ2iCChZMVdRglNCx07VNr67OPLRPZyDY=",
"zh:03a304f4b76ac6c8bebffddcdf555bf77578a7f638948a681589def32e140cb8",
"zh:08c7d2498b747054e9c9df7838bfa4e4a6b5d63e2d29f0457247e384f792d56c",
"zh:20adf489819ba51ba9d9d15da2dbe1fecb92491b3d0dd80096873e5e84d8b4bd",
"zh:2959ff209d2578456ca490672b82864d483b9e9db9efc8e4ffada06e23017609",
"zh:3ecd0b22db79550fb1108ff7bd00c4066825e8c23bb64e3cc8d9b8102e8caa45",
"zh:6e53a9232245b4be52b56b078f15f270b89afe6abb9c9b8baab4a282fe0cf9f8",
"zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
"zh:80437bdfa08eb90f70105b52cb06799a8f7967313654b43d28d7f654fcd4edc1",
"zh:816ddaca0ecc29e287376e5b0b8b0729ee13f23a9d74bfad5b14b7983e1a1775",
"zh:82d8ac7ad00c1a71d0a7c1aca03bb59a6b51128f895242df80b1f3d016c3c51a",
"zh:ec9243b8bd80693a6eeeea5d4f7f4e6f57bd44ae796d6d5b1a91790e359f8a61",
"zh:fd821adbfb03a2c9eac111ff27a32b3a5523b18f80333008de85482d3bbea645",
]
}
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, ~> 2.11"
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/hashicorp/template" {
version = "2.2.0"
constraints = "~> 2.2.0"
hashes = [
"h1:94qn780bi1qjrbC3uQtjJh3Wkfwd5+tTtJHOb7KTg9w=",
"zh:01702196f0a0492ec07917db7aaa595843d8f171dc195f4c988d2ffca2a06386",
"zh:09aae3da826ba3d7df69efeb25d146a1de0d03e951d35019a0f80e4f58c89b53",
"zh:09ba83c0625b6fe0a954da6fbd0c355ac0b7f07f86c91a2a97849140fea49603",
"zh:0e3a6c8e16f17f19010accd0844187d524580d9fdb0731f675ffcf4afba03d16",
"zh:45f2c594b6f2f34ea663704cc72048b212fe7d16fb4cfd959365fa997228a776",
"zh:77ea3e5a0446784d77114b5e851c970a3dde1e08fa6de38210b8385d7605d451",
"zh:8a154388f3708e3df5a69122a23bdfaf760a523788a5081976b3d5616f7d30ae",
"zh:992843002f2db5a11e626b3fc23dc0c87ad3729b3b3cff08e32ffb3df97edbde",
"zh:ad906f4cebd3ec5e43d5cd6dc8f4c5c9cc3b33d2243c89c5fc18f97f7277b51d",
"zh:c979425ddb256511137ecd093e23283234da0154b7fa8b21c2687182d9aea8b2",
]
}
provider "registry.terraform.io/hashicorp/time" {
version = "0.7.2"
hashes = [
"h1:YYLAfhMFP5nhV2iZPslqsLkZN+6sZo7gMJW7pLcLfM8=",
"zh:0bbe0158c2a9e3f5be911b7e94477586110c51746bb13d102054f22754565bda",
"zh:3250af7fd49b8aaf2ccc895588af05197d886e38b727e3ba33bcbb8cc96ad34d",
"zh:35e4de0437f4fa9c1ad69aaf8136413be2369ea607d78e04bb68dc66a6a520b8",
"zh:369756417a6272e79cad31eb2c82c202f6a4b6e4204a893f656644ba9e149fa2",
"zh:390370f1179d89b33c3a0731691e772d5450a7d59fc66671ec625e201db74aa2",
"zh:3d12ac905259d225c685bc42e5507ed0fbdaa5a09c30dce7c1932d908df857f7",
"zh:75f63e5e1c68e6c5bccba4568c3564e2774eb3a7a19189eb8e2b6e0d58c8f8cc",
"zh:7c22a2078a608e3e0278c4cbc9c483909062ebd1843bddaf8f176346c6d378b1",
"zh:7cfb3c02f78f0060d59c757c4726ab45a962ce4a9cf4833beca704a1020785bd",
"zh:a0325917f47c28a2ed088dedcea0d9520d91b264e63cc667fe4336ac993c0c11",
"zh:c181551d4c0a40b52e236f1755cc340aeca0fb5dcfd08b3b1c393a7667d2f327",
]
}
provider "registry.terraform.io/ivoronin/macaddress" {
version = "0.3.0"
constraints = "0.3.0, ~> 0.3.0"
hashes = [
"h1:XHlRv4GfEZDHcR06QY3HAUq3hZ1roM7/yBBN6hlzz/I=",
"zh:1076f1bc31a65061e97769c0ac25532c737a905572b814432f678fa1396eb86b",
"zh:18b209900c5c9fba1fad9dc20e917bb93aec99485e69d5729fef3407ff996d75",
"zh:256213bbd4c25f3ca455105c780b29eabdd64c2a3f5ed09a305b974e69c96300",
"zh:2d2b8afae240017e79d30309e16cbfbaaca9ca6b7239a9f7aa850d1a5ed7a87e",
"zh:373e467203d79617fb0496bca0c5baf6e66de4a718e80b24b395f58cf7388a11",
"zh:402d9265b57981bf874bba5ebc21dfc890d47367c70b032bf3f4481c41ee0346",
"zh:51510de325f5f5f53bf1bcfd1de1b5ef257d758a6b8c03226fa429bef0e1e8ab",
"zh:5aae406b754232d6c45b58617510f190c693dbbe2f5a50d8837482f037db6342",
"zh:75b011b4d7f497126a1f5677d19e90e9f0cf0f054044072246f1b6976b129927",
"zh:86cdfd4222fb2083ef92ed977c12653070b055a729341d8593a2107dcf8e9b31",
"zh:88646ecf88b4a988b41faec6973026a858e80bf6168ab7bdaf9a6f471965e57a",
"zh:8ef7cc61be537c3c05f3d47d718cddf97799aa7256a729a945154de5fb6911f1",
"zh:e78f2a54bb5c94b09670c7ed583ec5e402515f079667f51307fd8c745543d178",
]
}

130
README.md Normal file
View File

@@ -0,0 +1,130 @@
## Requirements
The following requirements are needed by this module:
- <a name="requirement_aws"></a> [aws](#requirement\_aws) (~> 4.9.0)
- <a name="requirement_cloudflare"></a> [cloudflare](#requirement\_cloudflare) (~> 3.15.0)
- <a name="requirement_dns"></a> [dns](#requirement\_dns) (~> 3.2.3)
- <a name="requirement_helm"></a> [helm](#requirement\_helm) (2.5.1)
- <a name="requirement_kubernetes"></a> [kubernetes](#requirement\_kubernetes) (~> 2.11.0)
- <a name="requirement_libvirt"></a> [libvirt](#requirement\_libvirt) (0.6.14)
- <a name="requirement_macaddress"></a> [macaddress](#requirement\_macaddress) (0.3.0)
- <a name="requirement_template"></a> [template](#requirement\_template) (~> 2.2.0)
## Providers
The following providers are used by this module:
- <a name="provider_helm"></a> [helm](#provider\_helm) (2.5.1)
- <a name="provider_kubernetes"></a> [kubernetes](#provider\_kubernetes) (2.11.0)
- <a name="provider_libvirt"></a> [libvirt](#provider\_libvirt) (0.6.14)
- <a name="provider_random"></a> [random](#provider\_random) (3.2.0)
- <a name="provider_template"></a> [template](#provider\_template) (2.2.0)
- <a name="provider_time"></a> [time](#provider\_time) (0.7.2)
## Modules
The following Modules are called:
### <a name="module_flannel"></a> [flannel](#module\_flannel)
Source: git@git.thomasklein.me:thomasklein/terraform-modules//kubernetes/flannel
Version:
### <a name="module_kube_proxy"></a> [kube\_proxy](#module\_kube\_proxy)
Source: git@git.thomasklein.me:thomasklein/terraform-modules//kubernetes/kube-proxy
Version:
### <a name="module_worker"></a> [worker](#module\_worker)
Source: git@git.thomasklein.me:thomasklein/terraform-modules//lawndale-vm
Version:
## Resources
The following resources are used by this module:
- [helm_release.coredns](https://registry.terraform.io/providers/hashicorp/helm/2.5.1/docs/resources/release) (resource)
- [helm_release.metrics_server](https://registry.terraform.io/providers/hashicorp/helm/2.5.1/docs/resources/release) (resource)
- [kubernetes_cluster_role.ci_cd](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/cluster_role) (resource)
- [kubernetes_cluster_role.prometheus](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/cluster_role) (resource)
- [kubernetes_cluster_role_binding.auto_approve_node_csrs](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/cluster_role_binding) (resource)
- [kubernetes_cluster_role_binding.auto_approve_node_renewals](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/cluster_role_binding) (resource)
- [kubernetes_cluster_role_binding.nodes_create_csrs](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/cluster_role_binding) (resource)
- [kubernetes_cluster_role_binding.prometheus](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/cluster_role_binding) (resource)
- [kubernetes_cluster_role_binding.terraform_ci_is_a_ci](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/cluster_role_binding) (resource)
- [kubernetes_manifest.lawndale](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/manifest) (resource)
- [kubernetes_namespace.prometheus](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/namespace) (resource)
- [kubernetes_secret.bootstrap_token](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/secret) (resource)
- [kubernetes_service_account.prometheus](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service_account) (resource)
- [kubernetes_service_account.terraform_ci_cd](https://registry.terraform.io/providers/hashicorp/kubernetes/latest/docs/resources/service_account) (resource)
- [libvirt_pool.kubernetes_workers](https://registry.terraform.io/providers/dmacvicar/libvirt/0.6.14/docs/resources/pool) (resource)
- [random_password.bootstrap_token_id](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) (resource)
- [random_password.bootstrap_token_secret](https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/password) (resource)
- [time_rotating.bootstrap_expiry_base](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/rotating) (resource)
- [time_static.lawndale_node_registered](https://registry.terraform.io/providers/hashicorp/time/latest/docs/resources/static) (resource)
- [template_cloudinit_config.worker](https://registry.terraform.io/providers/hashicorp/template/latest/docs/data-sources/cloudinit_config) (data source)
## Required Inputs
The following input variables are required:
### <a name="input_lawndale_dns_key_secret"></a> [lawndale\_dns\_key\_secret](#input\_lawndale\_dns\_key\_secret)
Description: DNSSEC key to use sigining the NSUPDATE queries for Lawndale
Type: `string`
### <a name="input_lawndale_dns_port"></a> [lawndale\_dns\_port](#input\_lawndale\_dns\_port)
Description: Port where the lawndale internal DNS server listens on
Type: `number`
## Optional Inputs
The following input variables are optional (have default values):
### <a name="input_lawndale_dns_host"></a> [lawndale\_dns\_host](#input\_lawndale\_dns\_host)
Description: Address to reach lawndale internal DNS server
Type: `string`
Default: `"lawndale-hyper"`
### <a name="input_lawndale_dns_key_algorithm"></a> [lawndale\_dns\_key\_algorithm](#input\_lawndale\_dns\_key\_algorithm)
Description: DNSSEC key to use sigining the NSUPDATE queries for Lawndale
Type: `string`
Default: `"hmac-sha256"`
### <a name="input_lawndale_dns_transport"></a> [lawndale\_dns\_transport](#input\_lawndale\_dns\_transport)
Description: Port where the lawndale internal DNS server listens on
Type: `string`
Default: `"udp"`
## Outputs
No outputs.

10
backend.tf Normal file
View File

@@ -0,0 +1,10 @@
terraform {
backend "s3" {
bucket = "thomasklein-global-states"
key = "envs/lawndale/k8s/main"
region = "eu-central-1"
encrypt = true
kms_key_id = "a767a3ce-c505-44c0-9f93-6f53678c69c7"
dynamodb_table = "thomasklein-global-state-locks"
}
}

86
bootstrap_token.tf Normal file
View File

@@ -0,0 +1,86 @@
resource "random_password" "bootstrap_token_id" {
special = false
upper = false
length = 6
}
resource "random_password" "bootstrap_token_secret" {
special = false
upper = false
length = 16
}
resource "time_rotating" "bootstrap_expiry_base" {
rotation_days = 60
}
resource "kubernetes_secret" "bootstrap_token" {
metadata {
name = "bootstrap-token-${random_password.bootstrap_token_id.result}"
namespace = "kube-system"
}
type = "bootstrap.kubernetes.io/token"
data = {
"token-id" = random_password.bootstrap_token_id.result
"token-secret" = random_password.bootstrap_token_secret.result
"usage-bootstrap-authentication" = "true"
"usage-bootstrap-signing" = "true"
"auth-extra-groups" = "system:bootstrappers:worker,system:bootstrappers:ingress"
"expiration" = timeadd(time_rotating.bootstrap_expiry_base.id, "${90 * 24}h")
}
}
resource "kubernetes_cluster_role_binding" "auto_approve_node_csrs" {
metadata {
name = "auto-approve-csrs-for-nodes"
}
subject {
kind = "Group"
name = "system:bootstrappers"
api_group = "rbac.authorization.k8s.io"
}
role_ref {
kind = "ClusterRole"
name = "system:certificates.k8s.io:certificatesigningrequests:nodeclient"
api_group = "rbac.authorization.k8s.io"
}
}
resource "kubernetes_cluster_role_binding" "auto_approve_node_renewals" {
metadata {
name = "auto-approve-renewals-for-nodes"
}
subject {
kind = "Group"
name = "system:nodes"
api_group = "rbac.authorization.k8s.io"
}
role_ref {
kind = "ClusterRole"
name = "system:certificates.k8s.io:certificatesigningrequests:selfnodeclient"
api_group = "rbac.authorization.k8s.io"
}
}
resource "kubernetes_cluster_role_binding" "nodes_create_csrs" {
metadata {
name = "create-csrs-for-node-bootstrappers"
}
subject {
kind = "Group"
name = "system:bootstrappers"
api_group = "rbac.authorization.k8s.io"
}
role_ref {
kind = "ClusterRole"
name = "system:node-bootstrapper"
api_group = "rbac.authorization.k8s.io"
}
}

118
ci.tf Normal file
View File

@@ -0,0 +1,118 @@
resource "kubernetes_service_account" "terraform_ci_cd" {
metadata {
namespace = "kube-system"
name = "terraform-ci-cd"
}
automount_service_account_token = false
}
resource "kubernetes_cluster_role_binding" "terraform_ci_is_a_ci" {
metadata {
name = "terraform-ci-cd-is-a-ci-cd"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = kubernetes_cluster_role.ci_cd.metadata.0.name
}
subject {
kind = "ServiceAccount"
name = kubernetes_service_account.terraform_ci_cd.metadata.0.name
namespace = kubernetes_service_account.terraform_ci_cd.metadata.0.namespace
}
}
resource "kubernetes_cluster_role" "ci_cd" {
metadata {
name = "ci-cd"
}
rule {
api_groups = [""]
resources = [
"configmaps",
"persistentvolumes",
"persistentvolumeclaims",
"pods",
"namespaces",
"secrets",
"services",
]
verbs = [
"create",
"delete",
"get",
"list",
"patch",
"update",
"watch",
]
}
rule {
api_groups = ["apps"]
resources = [
"deployments",
"replicasets", # needed for 'helm upgrade --wait'
]
verbs = [
"create",
"delete",
"get",
"list",
"patch",
"update",
"watch",
]
}
rule {
api_groups = ["autoscaling"]
resources = [
"horizontalpodautoscalers"
]
verbs = [
"create",
"delete",
"get",
"list",
"patch",
"update",
"watch",
]
}
rule {
api_groups = ["networking.k8s.io"]
resources = [
"ingresses",
]
verbs = [
"create",
"delete",
"get",
"list",
"patch",
"update",
"watch",
]
}
rule {
api_groups = ["networking.k8s.io"]
resources = [
"networkpolicies"
]
verbs = [
"create",
"delete",
"get",
"list",
"patch",
"update",
"watch",
]
}
}

25
coredns.tf Normal file
View File

@@ -0,0 +1,25 @@
resource "helm_release" "coredns" {
name = "coredns"
namespace = "kube-system"
create_namespace = false
repository = "https://coredns.github.io/helm"
chart = "coredns"
atomic = true
values = [
jsonencode({
service = {
clusterIP = local.cluster_dns
}
}),
jsonencode({
customLabels = {
"prometheus.io/scrape" = "true"
"prometheus.io/port" = "9153"
}
})
]
}

9
dns.tf Normal file
View File

@@ -0,0 +1,9 @@
# resource "cloudflare_record" "k8s_lawndale_thomasklein_me" {
# zone_id = cloudflare_zone.thomasklein_me.id
# name = "k8s.lawndale.thomasklein.me"
# type = "CNAME"
# value = "lawndale-hyper.sch.bme.hu"
# ttl = 300
# }

8
flannel.tf Normal file
View File

@@ -0,0 +1,8 @@
module "flannel" {
source = "git@git.thomasklein.me:thomasklein/terraform-modules//kubernetes/flannel"
vxlan_port = 4789
vxlan_id = 8000
cluster_cidr = local.cluster_cidr
}

7
kube-proxy.tf Normal file
View File

@@ -0,0 +1,7 @@
module "kube_proxy" {
source = "git@git.thomasklein.me:thomasklein/terraform-modules//kubernetes/kube-proxy"
cluster_cidr = local.cluster_cidr
kubernetes_server = local.kubernetes_server
kubernetes_version = local.kubernetes_version
}

54
kubelet.tf Normal file
View File

@@ -0,0 +1,54 @@
locals {
bootstrap_kubeconfig = <<EOM
apiVersion: v1
kind: Config
clusters:
- cluster:
certificate-authority: /var/lib/kubernetes/ca.pem
server: ${local.kubernetes_server}
name: bootstrap
contexts:
- context:
cluster: bootstrap
user: kubelet-bootstrap
name: bootstrap
current-context: bootstrap
preferences: {}
users:
- name: kubelet-bootstrap
user:
token: ${local.bootstrap_token}
EOM
kubelet_config = yamlencode({
kind = "KubeletConfiguration"
apiVersion = "kubelet.config.k8s.io/v1beta1"
authentication = {
anonymous = { enabled = false }
webhook = { enabled = true }
x509 = {
clientCAFile = "/var/lib/kubernetes/ca.pem"
}
}
authorization = {
mode = "Webhook"
}
rotateCertificates = true
serverTLSBootstrap = true
clusterDomain = "cluster.local"
clusterDNS = [local.cluster_dns]
resolvConf = "/run/systemd/resolve/resolv.conf"
maxPods = 110
systemReserved = {
cpu = "200m"
memory = "128M"
}
kubeReserved = {
cpu = "100m"
memory = "128M"
}
})
}

81
lawndale-flannel-hack.tf Normal file
View File

@@ -0,0 +1,81 @@
/*
THIS IS A HACK!
Currently, flannel offers no option for static configuration without etcd or kubernetes api
so in order to make pods accessible from the host, I have to create this phantom node.
This will be picked up by a flannel daemon running on the host,
and will create the necessary interfaces and routing entries on the host
to reach other pods.
This is ugly, yes.
I have no other option currently, no
Maybe a go program can be written to only use the node discovery of flannel
without any need for this phantom node. But it's not a viable option for now, so...
*/
resource "time_static" "lawndale_node_registered" {}
resource "kubernetes_manifest" "lawndale" {
computed_fields = ["spec.taints", "metadata.annotations"]
manifest = {
apiVersion = "v1"
kind = "Node"
metadata = {
annotations = {
"flannel.alpha.coreos.com/backend-data" = jsonencode({ "VNI" = 8000, "VtepMAC" : "86:87:0d:78:6d:58" })
"flannel.alpha.coreos.com/backend-type" = "vxlan"
"flannel.alpha.coreos.com/kube-subnet-manager" = "true"
"flannel.alpha.coreos.com/public-ip" = "192.168.253.254"
"node.alpha.kubernetes.io/ttl" = "0"
}
labels = {
"beta.kubernetes.io/arch" = "amd64"
"beta.kubernetes.io/os" = "linux"
"kubernetes.io/arch" = "amd64"
"kubernetes.io/hostname" = "lawndale"
"kubernetes.io/os" = "linux"
}
name = "lawndale"
}
spec = {
unschedulable = "true"
podCIDR = "192.168.15.128/30"
podCIDRs = ["192.168.15.128/30"]
taints = [
{
effect = "NoSchedule"
key = "node.kubernetes.io/unschedulable"
timeAdded = time_static.lawndale_node_registered.rfc3339
value = null
},
{
effect = "NoSchedule"
key = "node.kubernetes.io/unreachable"
timeAdded = time_static.lawndale_node_registered.rfc3339
value = null
},
{
effect = "NoExecute"
key = "node.kubernetes.io/unreachable"
timeAdded = time_static.lawndale_node_registered.rfc3339
value = null
},
# {
# effect = "NoSchedule"
# key = "node.kubernetes.io/not-ready"
# timeAdded = time_static.lawndale_node_registered.rfc3339
# value = null
# },
{
effect = "NoExecute"
key = "k8s.thomasklein.me/lawndale-hack"
timeAdded = time_static.lawndale_node_registered.rfc3339
value = null
},
]
}
}
}

41
locals.tf Normal file
View File

@@ -0,0 +1,41 @@
locals {
cluster_cidr = "192.168.8.0/21"
kubernetes_server = "https://nat.lawndale:6443"
kubernetes_version = "1.23.5"
cluster_dns = "10.32.0.10"
bootstrap_token = "${random_password.bootstrap_token_id.result}.${random_password.bootstrap_token_secret.result}"
kubernetes_ca = <<EOM
-----BEGIN CERTIFICATE-----
MIIFHDCCAwQCFDlLlwrZsPc25z6SMzshefXKnsCLMA0GCSqGSIb3DQEBCwUAMDcx
CzAJBgNVBAYTAlhYMQowCAYDVQQHDAEgMRwwGgYDVQQKDBNUaG9tYXNrbGVpbiBS
T09UIENBMB4XDTIyMDUxMzIyNDYyN1oXDTI3MDUxMjIyNDYyN1owXjELMAkGA1UE
BhMCSFUxETAPBgNVBAcMCEJ1ZGFwZXN0MRQwEgYDVQQKDAtUaG9tYXNrbGVpbjER
MA8GA1UECwwITGF3bmRhbGUxEzARBgNVBAMMCkt1YmVybmV0ZXMwggIiMA0GCSqG
SIb3DQEBAQUAA4ICDwAwggIKAoICAQDN2l7BtTpoFhITwUdOSCGmni7cH2hWTB6x
wWNoiSUVpJRB7XECwH7Rv42DxKBkVoOSREryFnGVLQwuXJAsTr6BP7rAWEAIT8dB
c1fFwJ2jljKjL5kWmEDqQddW+FrGlhM5n0duhbVLz7/MdpIHEh23UdHvNtWuFdTd
YJs/AgapvqUbc9V7BOCYTTO8fRV0bKN4MVsYiRNpEZbr/XOCi04BAIDPERZBWVL/
a1JA7y0W4fJ3sf45hs1oEl6XlUjDs8fl3zz5PwR/51AVPceXTNUFMulOKmh1KeMU
4dKOGuV0JxSHM8ZRdmwDVU7rVRXWT2qSvk1JPtL/dK77W1ofU5nO4owQMs7tHEAs
8dEKysMunhgoHD63r3ysB5NaC4rvyIRi1MreRlc7/uYflh7UdZlTv0uFscBRwKj0
HoFYWex+aX9HLRbMIqhtGZcEBwUe3OzT3Bc1HjGf3Ue0KDGV53/JHDnOVYy4+8vk
jQLycDXYqN6OuAQROZIK0aNqHWPDiVeEHnhRv5QrjTOSNDwyqCj8vyDH22GdaYl3
6MaoCC/bNvZu/COMUXO66HSWcAetMmOp56TxEe2MYt9jI+RLKam1yBwgwZqCzNS8
u+saNeSV1BbR7k6DFoBpNRvQ9DJF3nonlkxX+tI2hwBQPJ9WR2ye1RyB53n2Ol+9
wRpOVP6YjQIDAQABMA0GCSqGSIb3DQEBCwUAA4ICAQCulsgLk4G0sPcEDHy/InRg
CQ5zJRef9qJgsurxIaBJwxy9cduh0t3rdFTraFlLTbvcygTTtAI1c3UCl1e9Jxkd
+x9ElR/xV4dykeMO6tstrMCK5WInRG3JkDd278sJVQR1jzdl2ZB+jFcOD1u3E+IZ
AdN4Hfmz8XGnOAauspX0SEt9nEnFWudvLc8hcWTyQ94WkPuhOR9fBg7nzenk6l7E
lPueGKVkLba5xZyfywiWBanebWxvtv9N/uhucwF38vDuhmtpQNtlmLrj4s+cLATb
f4BDn5CtnL/9FlwHcmnR5Nfx9gGOSkTDo0pwa2v3HqCCmNtXInODJOjoj9kuXXIo
57Xu7YEWz99r4KNWwLwyOflmUbqV8RL5hjbm+PDghwa/Eih7wyBOtmpeq7065QTI
OeMdOOqcYpRsd1qANCoiTkplQg2Sn/yaG7OZ3WOjNWZfU1xEiE+83XE6YIbwJDvZ
GvMmLc356VAweF1rOi+t/03xk2mx3lRVpNhFyAXfGb7zL1w8hvl8DlcmrxpuSDAm
k6rMYpIMLJORafZowTgE5JHSTZfUBqmNcFsv9rsV4OIj26wPdmHvwin/gytK83Rz
EehXHhbRmbtSZ7c4DrGeR2J0SZTyBQJfZczSGRvEiKyGNnyZlLVYKTTnV9b+aN3q
Xw+ilWL3boYsSiqVN6SIUA==
-----END CERTIFICATE-----
EOM
}

29
metrics-server.tf Normal file
View File

@@ -0,0 +1,29 @@
resource "helm_release" "metrics_server" {
name = "metrics-server"
namespace = "kube-system"
repository = "https://kubernetes-sigs.github.io/metrics-server/"
chart = "metrics-server"
version = "3.8.2"
values = [
jsonencode({
rbac = {
pspEnabled = true
}
apiService = {
create = true
}
metrics = {
enabled = true
}
}),
jsonencode({
podLabels = {
"prometheus.io/scrape" = "true"
"prometheus.io/port" = "4443"
"prometheus.io/scheme" = "https"
}
}),
]
}

79
prometheus_rbac.tf Normal file
View File

@@ -0,0 +1,79 @@
resource "kubernetes_namespace" "prometheus" {
metadata {
name = "prometheus"
}
}
resource "kubernetes_service_account" "prometheus" {
metadata {
name = "prometheus"
namespace = kubernetes_namespace.prometheus.metadata.0.name
}
automount_service_account_token = false
}
resource "kubernetes_cluster_role_binding" "prometheus" {
metadata {
name = "prometheus"
}
role_ref {
api_group = "rbac.authorization.k8s.io"
kind = "ClusterRole"
name = kubernetes_cluster_role.prometheus.metadata.0.name
}
subject {
kind = "ServiceAccount"
name = kubernetes_service_account.prometheus.metadata.0.name
namespace = kubernetes_service_account.prometheus.metadata.0.namespace
}
}
resource "kubernetes_cluster_role" "prometheus" {
metadata {
name = "prometheus"
}
rule {
api_groups = [""]
resources = [
"nodes",
"nodes/metrics",
"nodes/proxy",
"services",
"endpoints",
"pods",
]
verbs = ["get", "list", "watch"]
}
rule {
api_groups = [""]
resources = [
"configmaps",
]
verbs = ["get"]
}
rule {
api_groups = ["networking.k8s.io"]
resources = [
"ingresses",
]
verbs = ["get", "list", "watch"]
}
rule {
api_groups = [""]
resources = [
"pods/proxy",
"services/proxy",
]
verbs = ["get", "list", "watch"]
}
rule {
non_resource_urls = [
"/metrics",
]
verbs = ["get"]
}
}

79
providers.tf Normal file
View File

@@ -0,0 +1,79 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 4.9.0"
}
cloudflare = {
source = "cloudflare/cloudflare"
version = "~> 3.15.0"
}
dns = {
source = "hashicorp/dns"
version = "~> 3.2.3"
}
helm = {
source = "hashicorp/helm"
version = "2.5.1"
}
kubernetes = {
source = "hashicorp/kubernetes"
version = "~> 2.11.0"
}
libvirt = {
source = "dmacvicar/libvirt"
version = "0.6.14"
}
macaddress = {
source = "ivoronin/macaddress"
version = "0.3.0"
}
template = {
source = "hashicorp/template"
version = "~> 2.2.0"
}
}
}
provider "aws" {
# Configuration options
default_tags {
tags = {
"managed-by" = "terraform"
}
}
}
provider "libvirt" {
# no-pty ssh-rsa AAAAB3.....
uri = "qemu+ssh://lawndale-hyper.sch.bme.hu:10022/system?sshauth=privkey"
}
provider "dns" {
update {
server = var.lawndale_dns_host
port = var.lawndale_dns_port
transport = var.lawndale_dns_transport
key_name = "lawndale."
key_secret = var.lawndale_dns_key_secret
key_algorithm = var.lawndale_dns_key_algorithm
}
}
provider "cloudflare" {
# Configuration options
}
provider "helm" {
}
provider "kubernetes" {
}

33
variables.tf Normal file
View File

@@ -0,0 +1,33 @@
variable "lawndale_dns_host" {
type = string
description = "Address to reach lawndale internal DNS server"
default = "lawndale-hyper"
}
variable "lawndale_dns_port" {
type = number
description = "Port where the lawndale internal DNS server listens on"
}
variable "lawndale_dns_transport" {
type = string
description = "Port where the lawndale internal DNS server listens on"
default = "udp"
validation {
condition = can(regex("(udp|tcp)", var.lawndale_dns_transport))
error_message = "Must be either tcp or udp!"
}
}
variable "lawndale_dns_key_secret" {
type = string
sensitive = true
description = "DNSSEC key to use sigining the NSUPDATE queries for Lawndale"
}
variable "lawndale_dns_key_algorithm" {
type = string
description = "DNSSEC key to use sigining the NSUPDATE queries for Lawndale"
default = "hmac-sha256"
}

101
worker.tf Normal file
View File

@@ -0,0 +1,101 @@
locals {
pool_name = "kubernetes-workers"
worker_id_start = 80
worker_count = 1
}
resource "libvirt_pool" "kubernetes_workers" {
name = "kubernetes-workers"
type = "dir"
path = "/vmstore/kubernetes-workers"
}
data "template_cloudinit_config" "worker" {
count = local.worker_count
gzip = false
base64_encode = false
part {
filename = "init.cfg"
content_type = "text/cloud-config"
content = yamlencode({
ssh_authorized_keys = [
"ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQCp7+2y7Y8jOUM2TXFbuKWMmwguNsCoFxE6JUg4VPbGTsX0FA3UTi1AB5TzL7tEPt6/j7MolSIvtupXFrH2pNdOuHXZL0LsR8EQ5uLA2oDRJX3xiyHrgBAXtEjAWkVus1DjUz19vRw/81GGnPucr4WIR4vSc+H0DFLgjJKn/MsMf/Z8DnCwEbguO2qlDPH8ToQQZC2k6BLwEHVpWigKE6MisV9i9GhFFJG9nbcHPq/Vf5fJhIHG+LGD3AgMeEZF9QE2pNbMOJ4lRP2lo16KpxYJCx5shdFqE3kiV/hLXVkDhSDK+p4pw1uuGEz7dFz5Fa1CMIa8iARKMzcYejs0AqqD"
]
write_files = [
{
path = "/var/lib/kubernetes/ca.pem"
content = local.kubernetes_ca
},
{
path = "/var/lib/kubelet/bootstrap-kubeconfig"
encoding = "gzip+base64"
content = base64gzip(local.bootstrap_kubeconfig)
},
{
path = "/var/lib/kubelet/kubelet-config.yaml"
content = local.kubelet_config
}
]
mounts = [
["datastore", "/mnt/datastore", "9p", "trans=virtio"]
]
})
}
}
module "worker" {
source = "git@git.thomasklein.me:thomasklein/terraform-modules//lawndale-vm"
count = local.worker_count
name = "k8s-worker-${count.index}"
id = local.worker_id_start + count.index
description = "Kubernetes worker (${count.index})"
vcpu = 6
memory_mb = 12 * 1024
interface = "nat"
create_root_storage_pool = false
root_storage_pool = local.pool_name
root_storage_volume_size_gb = 8
base_image_pool = "base-images"
base_image_volume = "ubuntu-jammy-20220516-k8s-v1.23.5-20220517"
filesystems = [
{
source = "/mnt/datastore/k8s"
target = "datastore"
readonly = false
accessmode = "mapped"
}
]
depends_on = [libvirt_pool.kubernetes_workers]
user_data = data.template_cloudinit_config.worker[count.index].rendered
### Make the workers headless
xslt = <<EOM
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes"/>
<xsl:strip-space elements="*" />
<xsl:template match="@*|node()">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match="graphics" />
<xsl:template match="video" />
<xsl:template match="audio" />
<xsl:template match="input[@type='mouse']|input[@type='keyboard']" />
</xsl:stylesheet>
EOM
}