-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Ephemeral Environments for GitHub Pull Requests guide
Signed-off-by: Stefan Prodan <[email protected]>
- Loading branch information
1 parent
deee283
commit 6c3c187
Showing
4 changed files
with
199 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,192 @@ | ||
# Ephemeral Environments for GitHub Pull Requests | ||
|
||
This guide demonstrates how to use the Flux Operator ResourceSet API to automate the deployment of | ||
applications changes made in GitHub Pull Requests to ephemeral environments for testing and validation. | ||
|
||
## Development workflow | ||
|
||
- A developer opens a Pull Request with changes to the app code and Helm chart. | ||
- The CI builds and pushes the app container image to GitHub Container Registry. The image is tagged with the Git commit SHA. | ||
- Another developer reviews the changes and labels the Pull Request with the `deploy/flux-preview` label. | ||
- Flux Operator running in the preview cluster scans the repository and finds the new PR using the label filter. | ||
- Flux Operator installs a Helm release using the PR number and the commit SHA inputs to deploy the app and chart changes in the cluster. | ||
- The app is accessible at a preview URL composed of the PR number and the app name. | ||
- The developers iterate over changes, with each push to the PR branch triggering a Helm release upgrade in the cluster. | ||
- Once the PR is approved and merged, the Flux Operator uninstalls the Helm release form the cluster. | ||
|
||
## GitOps configuration | ||
|
||
To enable the above workflow, we'll define a series of Flux Operator custom resources in the preview cluster. | ||
Note that the preview cluster must be provisioned with a [Flux Instance](../fluxinstance.md). | ||
|
||
### Preview namespace | ||
|
||
First we'll create a dedicated namespace called `app-preview` where all the app instances generated | ||
from PRs will be deployed. In that namespace, we'll create a Kubernetes Secret containing a GitHub | ||
token that grants read access to the app repository and PRs. | ||
|
||
```shell | ||
flux -n app-preview create secret git github-token-readonly \ | ||
--url=https://github.com/org/app \ | ||
--username=flux \ | ||
--password=${GITHUB_TOKEN} | ||
``` | ||
|
||
### ResourceSet input provider | ||
|
||
In the `app-preview` namespace, we'll create a [ResourceSetInputProvider](../resourcesetinputprovider.md) | ||
that tells Flux Operator to scan the repository for PRs labeled with `deploy/flux-preview`: | ||
|
||
```yaml | ||
apiVersion: fluxcd.controlplane.io/v1 | ||
kind: ResourceSetInputProvider | ||
metadata: | ||
name: app-pull-requests | ||
namespace: app-preview | ||
annotations: | ||
fluxcd.controlplane.io/reconcileEvery: "10m" | ||
spec: | ||
type: GitHubPullRequest | ||
url: https://github.com/org/app | ||
secretRef: | ||
name: github-token-readonly | ||
filter: | ||
labels: | ||
- "deploy/flux-preview" | ||
defaultValues: | ||
chart: "charts/app" | ||
``` | ||
### GitHub Webhook | ||
Optionally, we can create a Flux [Webhook Receiver](https://fluxcd.io/flux/components/notification/receivers/) | ||
that GitHub will call to notify the Flux Operator when a new PR is opened or updated: | ||
```yaml | ||
apiVersion: notification.toolkit.fluxcd.io/v1 | ||
kind: Receiver | ||
metadata: | ||
name: github-receiver | ||
namespace: app-preview | ||
spec: | ||
type: github | ||
secretRef: | ||
name: receiver-token | ||
resources: | ||
- apiVersion: fluxcd.controlplane.io/v1 | ||
kind: ResourceSetInputProvider | ||
name: app-pull-requests | ||
``` | ||
### ResourceSet | ||
Finally, to deploy the app from PRs we'll create a [ResourceSet](../resourceset.md) | ||
that takes its inputs from the `ResourceSetInputProvider`: | ||
|
||
```yaml | ||
apiVersion: fluxcd.controlplane.io/v1 | ||
kind: ResourceSet | ||
metadata: | ||
name: app | ||
namespace: app-preview | ||
spec: | ||
inputsFrom: | ||
- apiVersion: fluxcd.controlplane.io/v1 | ||
kind: ResourceSetInputProvider | ||
name: app-pull-requests | ||
resources: | ||
- apiVersion: source.toolkit.fluxcd.io/v1 | ||
kind: GitRepository | ||
metadata: | ||
name: app-<< inputs.id >> | ||
namespace: app-preview | ||
spec: | ||
interval: 1h | ||
url: https://github.com/org/app | ||
ref: | ||
commit: << inputs.sha >> | ||
secretRef: | ||
name: github-token-readonly | ||
- apiVersion: helm.toolkit.fluxcd.io/v2 | ||
kind: HelmRelease | ||
metadata: | ||
name: app-<< inputs.id >> | ||
namespace: app-preview | ||
annotations: | ||
event.toolkit.fluxcd.io/preview-url: "https://app-<< inputs.id >>.example.com" | ||
event.toolkit.fluxcd.io/branch: << inputs.branch | quote >> | ||
event.toolkit.fluxcd.io/author: << inputs.author | quote >> | ||
spec: | ||
interval: 10m | ||
releaseName: app-<< inputs.id >> | ||
chart: | ||
spec: | ||
chart: << inputs.chart >> | ||
reconcileStrategy: Revision | ||
sourceRef: | ||
kind: GitRepository | ||
name: app-<< inputs.id >> | ||
values: | ||
image: | ||
tag: << inputs.sha >> | ||
ingress: | ||
hosts: | ||
- host: app-<< inputs.id >>.example.com | ||
``` | ||
|
||
The above `ResouceSet` will generate a Flux `GitRepository` and a `HelmRelease` for each opened PR. | ||
The PR number passed as `<< inputs.id >>` is used as the name suffix for the Flux objects, | ||
and is also used to compose the Ingress host name where the app can be accessed. | ||
|
||
The latest commit SHA pushed to the PR HEAD is passed as `<< inputs.sha >>`, | ||
the SHA is used to set the app image tag in the Helm release values. | ||
|
||
The preview URL, branch name and author are set as annotations on the HelmRelease | ||
object to enrich the Flux notifications that the dev team receives. | ||
|
||
### Notifications | ||
|
||
To receive notifications when a PR triggers a Helm release install, | ||
upgrade and uninstall (including any deploy errors), | ||
a Flux [Alert](https://fluxcd.io/flux/components/notification/alerts/) | ||
can be created in the `app-preview` namespace: | ||
|
||
```yaml | ||
--- | ||
apiVersion: notification.toolkit.fluxcd.io/v1beta3 | ||
kind: Provider | ||
metadata: | ||
name: slack-bot | ||
namespace: app-preview | ||
spec: | ||
type: slack | ||
channel: general | ||
address: https://slack.com/api/chat.postMessage | ||
secretRef: | ||
name: slack-bot-token | ||
--- | ||
apiVersion: notification.toolkit.fluxcd.io/v1beta3 | ||
kind: Alert | ||
metadata: | ||
name: slack | ||
namespace: app-preview | ||
spec: | ||
providerRef: | ||
name: slack-bot | ||
eventSources: | ||
- kind: GitRepository | ||
name: '*' | ||
- kind: HelmRelease | ||
name: '*' | ||
eventMetadata: | ||
cluster: "preview-cluster-1" | ||
region: "us-east-1" | ||
``` | ||
|
||
Note that all the Kubernetes manifests part of this workflow should be stored in the Git repository | ||
used to define the preview cluster desired state. | ||
|
||
To learn more about ResourceSets and the various configuration options, see the following docs: | ||
|
||
- [ResourceSet CRD](../resourceset.md) | ||
- [ResourceSetInputProvider CRD](../resourcesetinputprovider.md) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters