190 lines
4.6 KiB
Markdown
190 lines
4.6 KiB
Markdown
# dda-devops-build
|
|
|
|
[![Slack](https://img.shields.io/badge/chat-clojurians-green.svg?style=flat)](https://clojurians.slack.com/messages/#dda-pallet/) | [<img src="https://meissa-gmbh.de/img/community/Mastodon_Logotype.svg" width=20 alt="team@social.meissa-gmbh.de"> team@social.meissa-gmbh.de](https://social.meissa-gmbh.de/@team) | [Website & Blog](https://domaindrivenarchitecture.org)
|
|
|
|
![release prod](https://github.com/DomainDrivenArchitecture/dda-devops-build/workflows/release%20prod/badge.svg)
|
|
|
|
dda-devops-build integrates all the tools we use to work with clouds & provide some nice functions around.
|
|
|
|
Tools we support are
|
|
|
|
* terraform: for setting up the plain infrastructure around.
|
|
* docker: for creating images
|
|
* c4k: for generating kubernetes manifests
|
|
* provs: for setting up small single-node k3s clusters
|
|
* gopass: for credential management on devops computers
|
|
* cloud providers: hetzner, digitalocean, aws
|
|
|
|
In addition we provide a ReleaseMixin for release related tasks like tag / publish & version-bump
|
|
|
|
```mermaid
|
|
classDiagram
|
|
class DevopsBuild {
|
|
name()
|
|
build_path()
|
|
initialize_build_dir()
|
|
}
|
|
|
|
class DevopsTerraformBuild {
|
|
initialize_build_dir()
|
|
post_build()
|
|
read_output_json()
|
|
plan()
|
|
plan_fail_on_diff()
|
|
apply(auto_approve=False)
|
|
refresh()
|
|
destroy(auto_approve=False)
|
|
tf_import(tf_import_name,tf_import_resource)
|
|
}
|
|
|
|
class DevopsImageBuild {
|
|
initialize_build_dir()
|
|
image()
|
|
drun()
|
|
dockerhub_login()
|
|
dockerhub_publish()
|
|
test()
|
|
}
|
|
|
|
class ReleaseMixin {
|
|
prepare_release()
|
|
tag_and_push_release()
|
|
}
|
|
|
|
class ProvsK3sBuild {
|
|
def update_runtime_config(dns_record)
|
|
write_provs_config()
|
|
provs_apply(dry_run=False)
|
|
}
|
|
|
|
class C4kBuild {
|
|
def update_runtime_config(dns_record)
|
|
def write_c4k_config()
|
|
def write_c4k_auth()
|
|
c4k_apply(dry_run=False)
|
|
}
|
|
|
|
DevopsBuild <|-- DevopsImageBuild
|
|
DevopsBuild <|-- DevopsTerraformBuild
|
|
DevopsBuild <|-- ReleaseMixin
|
|
DevopsBuild <|-- ProvsK3sBuild
|
|
DevopsBuild <|-- C4kBuild
|
|
|
|
link DevopsBuild "./doc/DevopsBuild.md"
|
|
link DevopsImageBuild "./doc/DevopsImageBuild.md"
|
|
|
|
```
|
|
|
|
Principles we follow are:
|
|
|
|
* Seperate build artefacts from version controlled code
|
|
* Domain Driven Design - in order to stay sustainable
|
|
|
|
## Installation
|
|
|
|
Ensure that yout python3 version is at least Python 3.10
|
|
|
|
```
|
|
sudo apt install python3-pip
|
|
pip3 install -r requirements.txt
|
|
export PATH=$PATH:~/.local/bin
|
|
```
|
|
|
|
## Reference
|
|
|
|
* [DevopsBuild](./doc/DevopsBuild.md)
|
|
* [DevopsImageBuild](./doc/DevopsImageBuild.md)
|
|
|
|
|
|
|
|
## Example Build
|
|
|
|
lets assume the following project structure
|
|
|
|
```
|
|
my-project
|
|
| -> my-module
|
|
| | -> build.py
|
|
| | -> some-terraform.tf
|
|
| -> an-other-module
|
|
| -> target (here will the build happen)
|
|
| | -> ...
|
|
```
|
|
|
|
```python
|
|
from pybuilder.core import task, init
|
|
from ddadevops import *
|
|
|
|
name = 'my-project'
|
|
MODULE = 'my-module'
|
|
PROJECT_ROOT_PATH = '..'
|
|
|
|
|
|
@init
|
|
def initialize(project):
|
|
project.build_depends_on("ddadevops>=4.0.0-dev")
|
|
|
|
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": environ["STAGE"],
|
|
"project_root_path": PROJECT_ROOT_PATH,
|
|
"build_types": ["TERRAFORM"],
|
|
"mixin_types": [],
|
|
"tf_provider_types": ["DIGITALOCEAN", "HETZNER"],
|
|
"tf_use_workspace": False,
|
|
"tf_terraform_semantic_version": "1.4.2",
|
|
"do_as_backend": True,
|
|
"do_bucket": "your-bucket",
|
|
}
|
|
|
|
build = DevopsTerraformBuild(project, config)
|
|
build.initialize_build_dir()
|
|
|
|
|
|
@task
|
|
def plan(project):
|
|
build = get_devops_build(project)
|
|
build.plan()
|
|
|
|
|
|
@task
|
|
def apply(project):
|
|
build = get_devops_build(project)
|
|
build.apply(True)
|
|
|
|
|
|
@task
|
|
def destroy(project):
|
|
build = get_devops_build(project)
|
|
build.destroy(True)
|
|
|
|
```
|
|
|
|
## Release
|
|
|
|
```
|
|
adjust version no in build.py to release version no.
|
|
git commit -am "release"
|
|
git tag -am "release" [release version no]
|
|
git push --follow-tags
|
|
increase version no in build.py
|
|
git commit -am "version bump"
|
|
git push
|
|
pip3 install --upgrade --user ddadevops
|
|
```
|
|
|
|
## License
|
|
|
|
Copyright © 2023 meissa GmbH
|
|
Licensed under the [Apache License, Version 2.0](LICENSE) (the "License")
|