environment="test"
release="release/v2"
git checkout -b prepare/${environment} origin/perform/${environment} # (1)
git merge --ff -m"Switch to ${release}" ${release} # (2)
git push -fu origin # (3)
Gerd Aschemann <gerd@aschemann.net>
Gerd Aschemann <gerd@aschemann.net>
Twitter: @GerdAschemann
Mastodon: @ascheman
Freelancer: Java, Groovy, Enterprise, CRM, CI/CD, Architecture, DDD, …
Co-Organizer:
JavaLand (retired)
Visit https://github.com/ascheman/gitops-demo-deployment if you want to actively follow the demo. |
Who is using Continuous Integration (CI)?
Who is using Continuous Delivery (CD)?
Wer is using Continuous Deployment (CD as well?)?
Who is using IaC?
Who is using Ansible/Puppet/Chef/Saltstack?
Who is using Terraform?
Who is using Kubernetes (Manifests)?
Who is using Helm, Kustomize, …?
Who is using a k8s GitOps operator (ArgoCD, Flux, …)?
Who is using GitOps outside of k8s (e.g., by https://www.runatlantis.io/guide/)
How can we control
(initial/continuous) deployment of a certain artefact (version) to a target environment?
that the deployed version remains active in the target environment?
Software delivery items are called artefact
Software deployments consist of
Artefacts, e.g., Docker Image, Java jar/war, RPM package, AMI, …
Configuration settings, e.g., DB connection string + credentials, Service URL, …
Artefacts are described by their coordinates, e.g.
Repository/Registry (URL)
Namespace / Name, e.g., Maven/Gradle Group/Artefact,
Version(s): change over time
→ Similar to Configuration(s)
How can we control
the (initial) deployment of a certain artefact (version) configuration to a target environment?
that the deployed version configuration remains active in the target environment?
A particular configuration can also be treated as state
Use configuration and state synonymously
Distinguish desired state and actual state
State (configurations) can be defined
Declaratively (supports stateful management), e.g.,
Kubernetes (Manifest, Helm, Helmfile, …)
Terraform
Puppet, …
Imperatively (make state management harder), e.g.,
Kustomize (k8s)
Ansible
Cloud SDKs (?)
Kubernetes (k8s): Lucky you!
Ansible:
Apply Playbook(s)
Use Ansible Tower (AWX)
Terraform: Run (terraform plan
+) terraform apply
→ Out-of-scope for this presentation
k8s: Use (Re-) Conciliation Operator
Ansible:
Re-Apply Playbook(s)
Use Ansible Tower (aka. Ansible Automation Platform)
Terraform: Re-Run terraform plan + apply
(???)
On higher level the problem remains
How can we control state (changes)?
How do we ensure a certain configuration is applied to an environment?
How do we know which state is applied?
Who is in control of the change?
What will be changed?
Review Change?
Who approves the Change?
Maintain each configuration (state) in a Git repository/branch
Automatically apply changes by an agent (here: pipeline)
Use Git workflows to control change (i.e., use pull-requests)
→ GitOps
Configure stage(s)/environments in separate repositories.
Configure stage(s)/environments in separate branches.
GitOps,
originally coined by Weaveworks
nowadays used in a wider sense (versioned Continuous Delivery of Cloud Native applications), cf. https://gitops.tech
Principles
Describe (entire) system declarativly
Maintain desired system state in Git
Automatically apply (approved) state changes
Ensure correctness / durability by software agents (k8s: operators)
environment="test"
release="release/v2"
git checkout -b prepare/${environment} origin/perform/${environment} # (1)
git merge --ff -m"Switch to ${release}" ${release} # (2)
git push -fu origin # (3)
1 | Start with the current state (i.e., perform/ branch) |
2 | Merge state change (i.e., release/ branch) |
3 | Push it to Github and let the action prepare the change |
environment="test"
rollback=... # (1)
git checkout -b prepare/${environment} origin/perform/${environment} # (2)
git revert -m 'Roll back to previous version' ${rollback} # (3)
git push -fu origin # (4)
1 | Find the state change to revert |
2 | Start with the current state (i.e., perform/ branch) |
3 | Roll back the change |
4 | Push it to Github and let the action(s) do the rest |
start=release/v2
environment=guug-hfg-2022
git checkout ${start} # <1>
git push -f origin HEAD:init/${environment} # <2>
1 | Checkout a suitable starting point |
2 | Push it to an init/ branch on Github |
Watch Github Actions initializing the new environment
environment=guug-hfg-2022
current=$(git branch --show-current)
git fetch --all --prune
git checkout -b auto-perform/${environment} origin/perform/${environment}
git merge --ff -m"Auto-Perform changes from ${current}" ${current}
git push -fu origin
Watch Github Actions applying the change
environment=guug-hfg-2022
git pull -f
git checkout perform/${environment}
git push -f origin HEAD:auto-destroy/${environment}
Watch Github Actions destroying the environment
CD-Application (C/S) for Terraform
Watch for PRs (Github, Gitlab, Bitbucket, Azure Devops(?), …)
Control by ChatOps (comment PRs)
đ Separation of concerns (CI vs. CD)
đ Product vs. OSS-Project
đ No Pipeline engine needed
đ Reconciliation not covered (as well)
âšī¸ Repository per Environment (very opinionated)
âšī¸ Terraform only
âšī¸ Lacks many use-cases
Reconcilement (neither here, nor Atlantis)
Access Management
No direct grants to target envs necessary
Control access by repository/branch permissions
Complex use cases, e.g.,
release bundling
inhomogeneous resources (for instance: k8s + TF)
Housekeeping
Extensions, e.g., chatbot
GitOps can solve typical control challenges
Persist environment configurations to Git
Enable change management by following well-known Git flows
Include typical quality assurance, e.g., 4 eyes principle/review
Run easily on state based configurations (Terraform, k8s)
Stateless configurations are subject to proof of concept (Ansible Tower)
Gitops-Site by InnoQ
Awesome GitOps by Weave-Works
Github Action based demo by me ;-)