diff --git a/README.md b/README.md index 36ab3c3..7bc6f3c 100644 --- a/README.md +++ b/README.md @@ -75,6 +75,7 @@ classDiagram link DevopsTerraformBuild "./doc/DevopsTerraformBuild.md" link ReleaseMixin "./doc/ReleaseMixin.md" link ProvsK3sBuild "doc/ProvsK3sBuild.md" + link C4kBuild "doc/C4kBuild.md" ``` @@ -103,8 +104,7 @@ export PATH=$PATH:~/.local/bin * [HetznerProvider](doc/DevopsTerraformBuildWithHetznerProvider.md) * [ReleaseMixin](./doc/ReleaseMixin.md) * [ProvsK3sBuild](doc/ProvsK3sBuild.md) - - +* [C4kBuild](doc/C4kBuild.md) ## Example Build diff --git a/doc/C4kBuild.md b/doc/C4kBuild.md new file mode 100644 index 0000000..4f7fdd5 --- /dev/null +++ b/doc/C4kBuild.md @@ -0,0 +1,176 @@ +# C4kBuild + +Generates a kubernetes deployment out of c4k inputs. Can be combined with Terraform- & ProvsK3s-Builds. + +```mermaid +classDiagram + class C4kBuild { + def update_runtime_config(dns_record) - updates informations after terraform apply + def write_c4k_config() - provide the configuration for c4k + def write_c4k_auth() - provide the auth for c4k + c4k_apply(dry_run=False) - genereates the kubernetes manifest + } +``` + +## Input + +| name | description | default | +| -------------------------- | ------------------------------------------------ | ---------------------------------------------------------------- | +| c4k_executable_name | f"c4k-{self.c4k_executable_name}-standalone.jar" | {module} | +| c4k_config | the c4k configuration as map | {} | +| c4k_auth | the c4k auth as map | {} | +| c4k_grafana_cloud_url | url for your prometheus endpoint | "https://prometheus-prod-01-eu-west-0.grafana.net/api/prom/push" | +| c4k_grafana_cloud_user | | | +| c4k_grafana_cloud_password | | | + +### Credentials Mapping defaults + +```python +[ + { + "gopass_path": "server/meissa/grafana-cloud", + "gopass_field": "grafana-cloud-user", + "name": "c4k_grafana_cloud_user", + }, + { + "gopass_path": "server/meissa/grafana-cloud", + "name": "c4k_grafana_cloud_password", + }, +] +``` + +## Example Usage +### build.py + +```python +from os import environ +from pybuilder.core import task, init +from ddadevops import * + +name = 'my-project' +MODULE = 'my-module' +PROJECT_ROOT_PATH = '..' + +class MyBuild(DevopsTerraformBuild, C4kBuild, ProvsK3sBuild): + pass + +@init +def initialize(project): + project.build_depends_on("ddadevops>=4.0.0") + stage = environ["STAGE"] + + if stage == "test": + tmp_letsencrypt_endpoint = "staging" + tmp_jitsi_secrets_path = "server/jitsi-test" + elif stage == "prod": + tmp_letsencrypt_endpoint = "prod" + tmp_jitsi_secrets_path = "server/jitsi-prod" + + c4k_config = {"issuer": tmp_letsencrypt_endpoint} + c4k_auth = { + "jvb-auth-password": gopass_field_from_path( + tmp_jitsi_secrets_path, "jvb-auth-password" + ), + "jicofo-auth-password": gopass_field_from_path( + tmp_jitsi_secrets_path, "jvb-auth-password" + ), + "jicofo-component-secret": gopass_field_from_path( + tmp_jitsi_secrets_path, "jicofo-component-secret" + ), + } + + config = { + "credentials_mapping": [ + { + "gopass_path": environ.get("DIGITALOCEAN_TOKEN_KEY_PATH", None), + "name": "do_api_key", + }, + { + "gopass_path": environ.get("HETZNER_API_KEY_PATH", None), + "name": "hetzner_api_key", + }, + ], + "name": name, + "module": MODULE, + "stage": stage, + "project_root_path": PROJECT_ROOT_PATH, + "build_types": ["TERRAFORM", "C4K", "K3S"], + "mixin_types": [], + "tf_provider_types": ["DIGITALOCEAN", "HETZNER"], + "tf_use_workspace": False, + "tf_terraform_semantic_version": "1.4.2", + "do_as_backend": True, + "do_bucket": "my-configuration", + "k3s_app_filename_to_provision": "out_jitsi.yaml", + "k3s_letsencrypt_endpoint": tmp_letsencrypt_endpoint, + "k3s_letsencrypt_email": "admin@your.domain", + "c4k_config": c4k_config, + "c4k_auth": c4k_auth, + } + + build = MyBuild(project, config) + build.initialize_build_dir() + + +@task +def plan(project): + build = get_devops_build(project) + build.plan() + + +@task +def tf_apply(project): + build = get_devops_build(project) + build.apply(True) + + +@task +def show_config(project): + build = get_devops_build(project) + build.apply(True) + out_json = build.read_output_json() + build.update_runtime_config( + DnsRecord( + fqdn=out_json["fqdn"]["value"], + ipv4=out_json["ipv4"]["value"], + ipv6=out_json["ipv6"]["value"], + ) + ) + build.write_c4k_config() + build.write_c4k_auth() + build.c4k_apply(dry_run=True) + build.write_provs_config() + build.provs_apply(dry_run=True) + + +@task +def apply(project): + build = get_devops_build(project) + build.apply(True) + out_json = build.read_output_json() + build.update_runtime_config( + DnsRecord( + fqdn=out_json["fqdn"]["value"], + ipv4=out_json["ipv4"]["value"], + ipv6=out_json["ipv6"]["value"], + ) + ) + build.write_c4k_config() + build.write_c4k_auth() + build.c4k_apply() + build.write_provs_config() + time.sleep(5) + build.provs_apply() + + +@task +def destroy(project): + build = get_devops_build(project) + build.destroy(True) +``` + +### call the build + +```bash +pyb apply +```