Compare commits

...

38 Commits

Author SHA1 Message Date
John Westcott IV
3a6040e0cd Adding GitHub check to ensure PRs have the proper X/Y/Z flags 2022-08-01 14:09:56 -04:00
John Westcott IV
24f3f440f1 Adding GitHub check to ensure PRs have the proper X/Y/Z flags 2022-08-01 13:04:38 -04:00
Christian Adams
87b0511997 Use new postgres pod label when migrating from old instance (#1005) 2022-07-29 16:38:04 -04:00
Christian Adams
fde4a47a14 Bump dependencies stream (#841)
* Bump Postgresql, Nginx and Redis versions
* pg12 --> pg13 upgrade path
* Set supported pg version as a variable to remain DRY
* Make deleting the old db data pvc after upgrade configurable
* Use labels to find the postgres pod

* backup/restore: fix postgres label selector value

We need to use the deployment_name variable for the postgres instance
name.

Signed-off-by: Dimitri Savineau <dsavinea@redhat.com>

* backup/restore: add missing default supported_pg_version variable

Signed-off-by: Dimitri Savineau <dsavinea@redhat.com>

* restore: update database_host fact with pg suffix

Signed-off-by: Dimitri Savineau <dsavinea@redhat.com>

Co-authored-by: Dimitri Savineau <dsavinea@redhat.com>
2022-07-29 13:21:51 -04:00
John Westcott IV
af2e681f1e Please backup before attempting an upgrade (#1002) 2022-07-28 16:19:57 -04:00
lutskevich
82ffa3d348 Restore not managed external postgresql (#877)
* Restore not managed external postgresql

Update postgres.yml for restore from backup not managed external postgresql db.

* Update postgres.yml

* rm trailing spaces #48

Co-authored-by: Viktor Lutskevich <lutskevich.v@mail366.com>
2022-07-27 16:23:51 -04:00
Ming Quah
db6a5b53ed Move custom resource definitions into a CRDs folder (#994)
* Add missing quote for port parameter

* Add step to move CRDs into the correct folder
2022-07-26 18:48:20 -04:00
Shane McDonald
0be17476cd Merge pull request #979 from stanislav-zaprudskiy/allow_skipping_labels_patching_on_awx_resource
Introduce `set_self_labels` in CRDs
2022-07-20 12:41:20 -04:00
Shane McDonald
f4a781ccc5 Merge pull request #984 from bewing/makefile-logic
fix helm-chart Makefile issue
2022-07-20 12:40:20 -04:00
John Westcott IV
fcd2c4c023 Merge pull request #982 from john-westcott-iv/pr_template
Adding PR template
2022-07-19 04:22:41 -04:00
John Westcott IV
8e30a17a77 Adding PR template 2022-07-19 04:12:38 -04:00
Christian Adams
b3037c1067 Deprecate the backup_pvc_namespace field (#988)
- Removes backup_pvc_namespace field from OLM forms
  - This field has created confusion for users and there is no strong
    case for needing this functionality
  - Users will still be able to add it to the yaml for the CR if they
    want to use it with the cluster-scoped AWX operator
  - Remove unneeded advanced descriptors to avoid empty Advanced
    configuration expander

fixes AAP-1176
2022-07-18 17:35:11 -04:00
Brandon Ewing
f7ff132a2e fix helm-chart Makefile issue
GNU make resolves the $(wildcard ) macro when starting a block, and
caches it for the duration of the run.  In order to correctly remove
namespace references from the generated helm charts, we have to split
the generation and editing into two makefile targets.
2022-07-14 14:38:09 -05:00
Shane McDonald
5f06e90906 Merge pull request #963 from miles-w-3/helm-values
Added helm values, templates, and readme
2022-07-12 13:50:27 -04:00
Stanislav Zaprudskiy
36355b6a15 Introduce set_self_labels in CRDs
To allow skipping labels maintenance on CRs processed by the operator.
Resolves https://github.com/ansible/awx-operator/issues/756
2022-07-12 10:48:16 +02:00
Miles Wilson
bc08c4bbbe Added helm values, templates, and readme 2022-07-11 19:59:03 -04:00
Shane McDonald
7697825944 Merge pull request #983 from shanemcd/ingress_path-test
Add tests around ingress_path feature
2022-07-11 19:55:28 -04:00
Shane McDonald
8a325293b1 Add tests around ingress_path feature 2022-07-11 19:45:11 -04:00
Shane McDonald
dd53a1d415 Merge pull request #980 from sdktr/958_pgdump_command_customization
Fix 958: allow pg_dump backup command customization
2022-07-11 19:30:30 -04:00
Shane McDonald
c5db0e7104 Merge pull request #954 from bewing/helm-namespace
remove namespace from helm chart
2022-07-11 19:18:08 -04:00
Stefan de Kooter
59036fc373 Add free format pg_dump backup parameter 2022-07-10 19:03:32 +00:00
Christian Adams
c45a7bd4d7 Add Docs notes for custom secret keys (#969) 2022-06-28 11:05:49 -04:00
Shane McDonald
34b6354001 Merge pull request #956 from Cl0udius/add_auto_upgrade_parameter
added auto_upgrade flag
2022-06-27 13:39:11 -04:00
Shane McDonald
801f392447 Merge pull request #964 from taishen/devel
Add an example of the nodeport_port in readme
2022-06-27 13:38:24 -04:00
Shane McDonald
779572e8ff Merge pull request #944 from viv-dev/backup-cleanup
Option to delete backup dir on PV when AWXBackup object is deleted
2022-06-27 13:35:57 -04:00
Shane McDonald
e7e48f92a0 Merge pull request #962 from rooftopcellist/operator-resource-defaults
Add default resource requests for operator container
2022-06-27 13:33:32 -04:00
Brandon Ewing
3cd9ddd8c6 remove namespace from helm chart
Helm should be able to set the namespace for the operator at deploy time
via the --namespace option.  Use yq to remove all references to
namespaces in the helm chart prior to publishing.

Update CI process to create namespace during install.

Resolves #907
2022-06-27 12:26:14 -05:00
taishen
4e6be0a82c Add an example of the nodeport_port in readme 2022-06-27 22:02:42 +08:00
Viviana Capote
05943687fe Added option to also delete backup directory on PVC when AWXBackup CRD object is deleted 2022-06-27 15:45:33 +10:00
Shane McDonald
9676ebc008 Merge pull request #955 from doanminhtu/tudoan/fix-ldap-password-secret-usage
Fix ldap bind password secret usage: ldap_password_secret
2022-06-26 10:45:26 -04:00
Christian M. Adams
8352237260 Add default resource requests for operator container 2022-06-24 16:40:45 -04:00
Alexander Stock
35d4954027 added auto_update flag 2022-06-23 15:05:05 +02:00
Shane McDonald
4d6a491766 Merge pull request #959 from mac-chaffee/no-latest
Use specific version of redis image
2022-06-23 08:16:21 -04:00
Shane McDonald
fa9eb53f92 Merge pull request #950 from basecom/feature/nginx-ipv6-support
Enable ipv6 listening in nginx config
2022-06-23 07:51:41 -04:00
Tu Doan
00c9f5fbd1 Fix ldap secret to secret file 2022-06-23 10:49:27 +07:00
Mac Chaffee
fe82e9259e Use specific version of redis image
Signed-off-by: Mac Chaffee <machaffe@renci.org>
2022-06-22 16:14:39 -04:00
Tu Doan
635d530dc9 Fix ldap bind password secret usage 2022-06-20 17:03:38 +07:00
Roger Sikorski
8b3a297086 enable ipv6 on nginx 2022-06-15 17:37:02 +02:00
51 changed files with 910 additions and 264 deletions

26
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,26 @@
##### SUMMARY
<!--- Describe the change, including rationale and design decisions -->
<!---
If you are fixing an existing issue, please include "fixes #nnn" in your
commit message and your description; but you should still explain what
the change does.
-->
##### ISSUE TYPE
<!--- Pick one below and delete the rest: -->
- Breaking Change
- New or Enhanced Feature
- Bug, Docs Fix or other nominal change
##### ADDITIONAL INFORMATION
<!---
Include additional information to help people understand the change here.
For bugs that don't have a linked bug report, a step-by-step reproduction
of the problem is helpful.
-->
<!--- Paste verbatim command output below, e.g. before and after your change -->
```
```

View File

@@ -60,7 +60,25 @@ jobs:
kustomize edit add patch --path ../testing/pull_policy/Never.yaml
working-directory: config/default
- name: Build and install helm chart
- name: Build and lint helm chart
run: |
IMG=awx-operator-ci make helm-chart
helm install --wait my-awx-operator ./charts/awx-operator
helm lint ./charts/awx-operator
- name: Install kubeval
run: |
mkdir tmp && cd tmp
wget https://github.com/instrumenta/kubeval/releases/latest/download/kubeval-linux-amd64.tar.gz
tar xf kubeval-linux-amd64.tar.gz
sudo cp kubeval /usr/local/bin
working-directory: ./charts
- name: Run kubeval
run: |
helm template -n awx awx-operator > tmp/test.yaml
kubeval --strict --force-color --ignore-missing-schemas tmp/test.yaml
working-directory: ./charts
- name: Install helm chart
run: |
helm install --wait my-awx-operator --namespace awx --create-namespace ./charts/awx-operator

45
.github/workflows/pr_body_check.yml vendored Normal file
View File

@@ -0,0 +1,45 @@
---
name: PR Check
env:
BRANCH: ${{ github.base_ref || 'devel' }}
on:
pull_request:
types: [opened, edited, reopened, synchronize]
jobs:
pr-check:
name: Scan PR description for semantic versioning keywords
runs-on: ubuntu-latest
permissions:
packages: write
contents: read
steps:
- name: Write PR body to a file
run: |
cat >> pr.body << __SOME_RANDOM_PR_EOF__
${{ github.event.pull_request.body }}
__SOME_RANDOM_PR_EOF__
- name: Display the received body for troubleshooting
run: cat pr.body
# We want to write these out individually just incase the options were joined on a single line
- name: Check for each of the lines
run: |
grep "Bug, Docs Fix or other nominal change" pr.body > Z
grep "New or Enhanced Feature" pr.body > Y
grep "Breaking Change" pr.body > X
exit 0
# We exit 0 and set the shell to prevent the returns from the greps from failing this step
# See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#exit-codes-and-error-action-preference
shell: bash {0}
- name: Check for exactly one item
run: |
if [ $(cat X Y Z | wc -l) != 1 ] ; then
echo "The PR body must contain exactly one of [ 'Bug, Docs Fix or other nominal change', 'New or Enhanced Feature', 'Breaking Change' ]"
echo "We counted $(cat X Y Z | wc -l)"
echo "See the default PR body for examples"
exit 255;
else
exit 0;
fi

1
.gitignore vendored
View File

@@ -6,3 +6,4 @@
/bundle.Dockerfile
/charts
/.cr-release-packages
.vscode/

56
.helm/starter/README.md Normal file
View File

@@ -0,0 +1,56 @@
# AWX Operator Helm Chart
This chart installs the AWX Operator resources configured in [this](https://github.com/ansible/awx-operator) repository.
## Getting Started
To configure your AWX resource using this chart, create your own `yaml` values file. The name is up to personal preference since it will explicitly be passed into the helm chart. Helm will merge whatever values you specify in your file with the default `values.yaml`, overriding any settings you've changed while allowing you to fall back on defaults. Because of this functionality, `values.yaml` should not be edited directly.
In your values config, enable `AWX.enable` and add `AWX.spec` values based on the awx operator's [documentation](https://github.com/ansible/awx-operator/blob/devel/README.md). Consult the docs below for additional functionality.
### Installing
The operator's [helm install](https://github.com/ansible/awx-operator/blob/devel/README.md#helm-install-on-existing-cluster) guide provides key installation instructions.
Example:
```
helm install my-awx-operator awx-operator/awx-operator -n awx --create-namespace -f myvalues.yaml
```
Argument breakdown:
* `-f` passes in the file with your custom values
* `-n` sets the namespace to be installed in
* This value is accessed by `{{ $.Release.Namespace }}` in the templates
* Acts as the default namespace for all unspecified resources
* `--create-namespace` specifies that helm should create the namespace before installing
To update an existing installation, use `helm upgrade` instead of `install`. The rest of the syntax remains the same.
## Configuration
The goal of adding helm configurations is to abstract out and simplify the creation of multi-resource configs. The `AWX.spec` field maps directly to the spec configs of the `AWX` resource that the operator provides, which are detailed in the [main README](https://github.com/ansible/awx-operator/blob/devel/README.md). Other sub-config can be added with the goal of simplifying more involved setups that require additional resources to be specified.
These sub-headers aim to be a more intuitive entrypoint into customizing your deployment, and are easier to manage in the long-term. By design, the helm templates will defer to the manually defined specs to avoid configuration conflicts. For example, if `AWX.spec.postgres_configuration_secret` is being used, the `AWX.postgres` settings will not be applied, even if enabled.
### External Postgres
The `AWX.postgres` section simplifies the creation of the external postgres secret. If enabled, the configs provided will automatically be placed in a `postgres-config` secret and linked to the `AWX` resource. For proper secret management, the `AWX.postgres.password` value, and any other sensitive values, can be passed in at the command line rather than specified in code. Use the `--set` argument with `helm install`.
## Values Summary
### AWX
| Value | Description | Default |
|---|---|---|
| `AWX.enabled` | Enable this AWX resource configuration | `false` |
| `AWX.name` | The name of the AWX resource and default prefix for other resources | `"awx"` |
| `AWX.spec` | specs to directly configure the AWX resource | `{}` |
| `AWX.postgres` | configurations for the external postgres secret | - |
# Contributing
## Adding abstracted sections
Where possible, defer to `AWX.spec` configs before applying the abstracted configs to avoid collision. This can be facilitated by the `(hasKey .spec what_i_will_abstract)` check.
## Building and Testing
This chart is built using the Makefile in the [awx-operator repo](https://github.com/ansible/awx-operator). Clone the repo and run `make helm-chart`. This will create the awx-operator chart in the `charts/awx-operator` directory. In this process, the contents of the `.helm/starter` directory will be added to the chart.
## Future Goals
All values under the `AWX` header are focused on configurations that use the operator. Configurations that relate to the Operator itself could be placed under an `Operator` heading, but that may add a layer of complication over current development.

View File

@@ -0,0 +1,6 @@
{{/*
Generate the name of the postgres secret, expects AWX context passed in
*/}}
{{- define "postgres.secretName" -}}
{{ default (printf "%s-postgres-configuration" .Values.AWX.name) .Values.AWX.postgres.secretName }}
{{- end }}

View File

@@ -0,0 +1,24 @@
{{- if $.Values.AWX.enabled }}
{{- with .Values.AWX }}
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
name: {{ .name }}
namespace: {{ $.Release.Namespace }}
spec:
{{- /* Include raw map from the values file spec */}}
{{ .spec | toYaml | indent 2 }}
{{- /* Provide security context defaults */}}
{{- if not (hasKey .spec "security_context_settings") }}
security_context_settings:
runAsGroup: 0
runAsUser: 0
fsGroup: 0
fsGroupChangePolicy: OnRootMismatch
{{- end }}
{{- /* Postgres configs if enabled and not already present */}}
{{- if and .postgres.enabled (not (hasKey .spec "postgres_configuration_secret")) }}
postgres_configuration_secret: {{ include "postgres.secretName" $ }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,18 @@
{{- if and $.Values.AWX.enabled $.Values.AWX.postgres.enabled }}
apiVersion: v1
kind: Secret
metadata:
name: {{ include "postgres.secretName" . }}
namespace: {{ $.Release.Namespace }}
{{- with $.Values.AWX.postgres }}
stringData:
host: {{ .host }}
port: {{ .port | quote }}
database: {{ .dbName }}
username: {{ .username }}
password: {{ .password }}
sslmode: {{ .sslmode }}
type: {{ .type }}
type: Opaque
{{- end }}
{{- end }}

View File

@@ -0,0 +1,19 @@
AWX:
# enable use of awx-deploy template
enabled: false
name: awx
spec:
admin_user: admin
# configurations for external postgres instance
postgres:
enabled: false
host: Unset
port: 5678
dbName: Unset
username: admin
# for secret management, pass in the password independently of this file
# at the command line, use --set AWX.postgres.password
password: Unset
sslmode: prefer
type: unmanaged

View File

@@ -6,6 +6,7 @@ ignore: |
kustomization.yaml
awx-operator.clusterserviceversion.yaml
bundle
.helm/starter
rules:
truthy: disable

View File

@@ -269,10 +269,12 @@ charts:
mkdir -p $@
.PHONY: helm-chart
helm-chart: kustomize helm kubectl-slice yq charts
helm-chart: helm-chart-generate helm-chart-slice
.PHONY: helm-chart-generate
helm-chart-generate: kustomize helm kubectl-slice yq charts
@echo "== KUSTOMIZE (image and namespace) =="
cd config/manager && $(KUSTOMIZE) edit set image controller=${IMG}
cd config/default && $(KUSTOMIZE) edit set namespace ${NAMESPACE}
@echo "== HELM =="
cd charts && \
@@ -292,7 +294,16 @@ helm-chart: kustomize helm kubectl-slice yq charts
$(KUBECTL_SLICE) --input-file=- \
--output-dir=charts/$(CHART_NAME)/templates \
--sort-by-kind
@echo "Helm Chart $(VERSION)" > charts/$(CHART_NAME)/templates/NOTES.txt
@echo "AWX Operator installed with Helm Chart version $(VERSION)" > charts/$(CHART_NAME)/templates/NOTES.txt
mkdir charts/$(CHART_NAME)/crds
mv charts/$(CHART_NAME)/templates/customresourcedefinition* charts/$(CHART_NAME)/crds
.PHONY: helm-chart-edit
helm-chart-slice:
@echo "== EDIT =="
$(foreach file, $(wildcard charts/$(CHART_NAME)/templates/*),$(YQ) -i 'del(.. | select(has("namespace")).namespace)' $(file);)
$(foreach file, $(wildcard charts/$(CHART_NAME)/templates/*rolebinding*),$(YQ) -i '.subjects[0].namespace = "{{ .Release.Namespace }}"' $(file);)
rm -f charts/$(CHART_NAME)/templates/namespace*.yaml
.PHONY: helm-package

116
README.md
View File

@@ -45,9 +45,12 @@ An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built w
* [Session Cookie Secure Setting](#session-cookie-secure-setting)
* [Extra Settings](#extra-settings)
* [Configure no_log](#no-log)
* [Auto Upgrade](#auto-upgrade)
* [Upgrade of instances without auto upgrade](#upgrade-of-instances-without-auto-upgrade)
* [Service Account](#service-account)
* [Uninstall](#uninstall)
* [Upgrading](#upgrading)
* [Backup](#backup)
* [v0.14.0](#v0140)
* [Cluster-scope to Namespace-scope considerations](#cluster-scope-to-namespace-scope-considerations)
* [Project is now based on v1.x of the operator-sdk project](#project-is-now-based-on-v1x-of-the-operator-sdk-project)
@@ -192,8 +195,12 @@ metadata:
name: awx-demo
spec:
service_type: nodeport
# default nodeport_port is 30080
nodeport_port: <nodeport_port>
```
> It may make sense to create and specify your own secret key for your deployment so that if the k8s secret gets deleted, it can be re-created if needed. If it is not provided, one will be auto-generated, but cannot be recovered if lost. Read more [here](#secret-key-configuration).
Make sure to add this new file to the list of "resources" in your `kustomization.yaml` file:
```yaml
@@ -253,6 +260,8 @@ For an example using the Nginx Controller in Minukube, don't miss our [demo vide
For those that wish to use [Helm](https://helm.sh/) to install the awx-operator to an existing K8s cluster:
The helm chart is generated from the `helm-chart` Makefile section using the starter files in `.helm/starter`. Consult [the documentation](.helm/starter/README.md) on how to customize the AWX resource with your own values.
```bash
$ helm repo add awx-operator https://ansible.github.io/awx-operator/
"awx-operator" has been added to your repositories
@@ -266,7 +275,7 @@ $ helm search repo awx-operator
NAME CHART VERSION APP VERSION DESCRIPTION
awx-operator/awx-operator 0.17.1 0.17.1 A Helm chart for the AWX Operator
$ helm install my-awx-operator awx-operator/awx-operator
$ helm install -n awx --create-namespace my-awx-operator awx-operator/awx-operator
NAME: my-awx-operator
LAST DEPLOYED: Thu Feb 17 22:09:05 2022
NAMESPACE: default
@@ -308,6 +317,41 @@ stringData:
```
### Secret Key Configuration
This key is used to encrypt sensitive data in the database.
| Name | Description | Default |
| ----------------- | ----------------------------------------------------- | ---------------- |
| secret_key_secret | Secret that contains the symmetric key for encryption | Generated |
> :warning: **secret_key_secret must be a Kubernetes secret and not your text clear secret value**.
If `secret_key_secret` is not provided, the operator will look for a secret named `<resourcename>-secret-key` for the secret key. If it is not present, the operator will generate a password and create a Secret from it named `<resourcename>-secret-key`. It is important to not delete this secret as it will be needed for upgrades and if the pods get scaled down at any point. If you are using a GitOps flow, you will want to pass a secret key secret.
The secret should be formatted as follow:
```yaml
---
apiVersion: v1
kind: Secret
metadata:
name: custom-awx-secret-key
namespace: <target namespace>
stringData:
secret_key: supersecuresecretkey
```
Then specify the secret name on the AWX spec:
```yaml
---
spec:
...
secret_key_secret: custom-awx-secret-key
```
### Network and TLS Configuration
#### Service Type
@@ -459,7 +503,7 @@ stringData:
type: Opaque
```
> Please ensure that the value for the variable `password` should _not_ contain single or double quotes (`'`, `"`) or backslashes (`\`) to avoid any issues during deployment, backup or restoration.
> Please ensure that the value for the variable `password` should _not_ contain single or double quotes (`'`, `"`) or backslashes (`\`) to avoid any issues during deployment, [backup](https://github.com/ansible/awx-operator/tree/devel/roles/backup) or [restoration](https://github.com/ansible/awx-operator/tree/devel/roles/restore).
> It is possible to set a specific username, password, port, or database, but still have the database managed by the operator. In this case, when creating the postgres-configuration secret, the `type: managed` field should be added.
@@ -655,8 +699,8 @@ The ability to specify topologySpreadConstraints is also allowed through `topolo
| Name | Description | Default |
| --------------------------- | ----------------------------------- | ------- |
| postgres_image | Path of the image to pull | 12 |
| postgres_image_version | Image version to pull | 12 |
| postgres_image | Path of the image to pull | postgres |
| postgres_image_version | Image version to pull | 13 |
| node_selector | AWX pods' nodeSelector | '' |
| topology_spread_constraints | AWX pods' topologySpreadConstraints | '' |
| tolerations | AWX pods' tolerations | '' |
@@ -903,7 +947,7 @@ Example spec file for volumes and volume mounts
In order to register default execution environments from private registries, the Custom Resource needs to know about the pull credentials. Those credentials should be stored as a secret and either specified as `ee_pull_credentials_secret` at the CR spec level, or simply be present on the namespace under the name `<resourcename>-ee-pull-credentials` . Instance initialization will register a `Container registry` type credential on the deployed instance and assign it to the registered default execution environments.
The secret should be formated as follows:
The secret should be formatted as follows:
```yaml
---
@@ -927,7 +971,7 @@ You can create `image_pull_secret`
```
kubectl create secret <resoucename>-cp-pull-credentials regcred --docker-server=<your-registry-server> --docker-username=<your-name> --docker-password=<your-pword> --docker-email=<your-email>
```
If you need more control (for example, to set a namespace or a label on the new secret) then you can customise the Secret before storing it
If you need more control (for example, to set a namespace or a label on the new secret) then you can customize the Secret before storing it
Example spec file extra-config
@@ -1034,6 +1078,42 @@ Example configuration of `no_log` parameter
no_log: 'true'
```
#### Auto upgrade
With this parameter you can influence the behavior during an operator upgrade.
If set to `true`, the operator will upgrade the specific instance directly.
When the value is set to `false`, and we have a running deployment, the operator will not update the AWX instance.
This can be useful when you have multiple AWX instances which you want to upgrade step by step instead of all at once.
| Name | Description | Default |
| -------------| ---------------------------------- | ------- |
| auto_upgrade | Automatic upgrade of AWX instances | true |
Example configuration of `auto_upgrade` parameter
```yaml
spec:
auto_upgrade: true
```
##### Upgrade of instances without auto upgrade
There are two ways to upgrade instances which are marked with the 'auto_upgrade: false' flag.
Changing flags:
- change the auto_upgrade flag on your AWX object to true
- wait until the upgrade process of that instance is finished
- change the auto_upgrade flag on your AWX object back to false
Delete the deployment:
- delete the deployment object of your AWX instance
```
$ kubectl -n awx delete deployment <yourInstanceName>
```
- wait until the instance gets redeployed
#### Service Account
@@ -1063,12 +1143,31 @@ awx.awx.ansible.com "awx-demo" deleted
Deleting an AWX instance will remove all related deployments and statefulsets, however, persistent volumes and secrets will remain. To enforce secrets also getting removed, you can use `garbage_collect_secrets: true`.
**Note**: If you ever intend to recover an AWX from an existing database you will need a copy of the secrets in order to perform a successful recovery.
### Upgrading
To upgrade AWX, it is recommended to upgrade the awx-operator to the version that maps to the desired version of AWX. To find the version of AWX that will be installed by the awx-operator by default, check the version specified in the `image_version` variable in `roles/installer/defaults/main.yml` for that particular release.
Apply the awx-operator.yml for that release to upgrade the operator, and in turn also upgrade your AWX deployment.
#### Backup
The first part of any upgrade should be a backup. Note, there are secrets in the pod which work in conjunction with the database. Having just a database backup without the required secrets will not be sufficient for recovering from an issue when upgrading to a new version. See the [backup role documentation](https://github.com/ansible/awx-operator/tree/devel/roles/backup) for information on how to backup your database and secrets. In the event you need to recover the backup see the [restore role documentation](https://github.com/ansible/awx-operator/tree/devel/roles/restore).
#### PostgreSQL Upgrade Considerations
If there is a PostgreSQL major version upgrade, after the data directory on the PVC is migrated to the new version, the old PVC is kept by default.
This provides the ability to roll back if needed, but can take up extra storage space in your cluster unnecessarily. You can configure it to be deleted automatically
after a successful upgrade by setting the following variable on the AWX spec.
```yaml
spec:
postgres_keep_pvc_after_upgrade: False
```
#### v0.14.0
##### Cluster-scope to Namespace-scope considerations
@@ -1102,7 +1201,7 @@ Please visit [our contributing guidelines](https://github.com/ansible/awx-operat
## Release Process
The first step is to create a draft release. Typically this will happen in the [Stage Release](https://github.com/ansible/awx/blob/devel/.github/workflows/stage.yml) workflow for AWX and you dont need to do it as a separate step.
The first step is to create a draft release. Typically this will happen in the [Stage Release](https://github.com/ansible/awx/blob/devel/.github/workflows/stage.yml) workflow for AWX and you don't need to do it as a separate step.
If you need to do an independent release of the operator, you can run the [Stage Release](https://github.com/ansible/awx-operator/blob/devel/.github/workflows/stage.yml) in the awx-operator repo. Both of these workflows will run smoke tests, so there is no need to do this manually.
@@ -1121,8 +1220,7 @@ We ask all of our community members and contributors to adhere to the [Ansible c
## Get Involved
We welcome your feedback and ideas. The AWX operator uses the same mailing list and IRC chanel as AWX itself. Here's how to reach us with feedback and questions:
We welcome your feedback and ideas. The AWX operator uses the same mailing list and IRC channel as AWX itself. Here's how to reach us with feedback and questions:
- Join the `#ansible-awx` channel on irc.libera.chat
- Join the [mailing list](https://groups.google.com/forum/#!forum/awx-project)

View File

@@ -379,6 +379,9 @@ spec:
postgres_selector:
description: nodeSelector for the Postgres pods
type: string
postgres_keep_pvc_after_upgrade:
description: Specify whether or not to keep the old PVC after PostgreSQL upgrades
type: boolean
postgres_tolerations:
description: node tolerations for the Postgres pods
type: string
@@ -489,6 +492,14 @@ spec:
description: Key/values that will be set under the pod-level securityContext field
type: object
x-kubernetes-preserve-unknown-fields: true
auto_upgrade:
description: Should AWX instances be automatically upgraded when operator gets upgraded
type: boolean
default: true
set_self_labels:
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
type: boolean
default: true
type: object
status:
properties:
@@ -511,7 +522,10 @@ spec:
description: Secret key secret name of the deployed instance
type: string
migratedFromSecret:
description: The secret used for migrating an old instance.
description: The secret used for migrating an old instance
type: string
upgradedPostgresVersion:
description: Status to indicate that the database has been upgraded to the version in the status
type: string
version:
description: Version of the deployed instance

View File

@@ -32,17 +32,20 @@ spec:
description: Name of the deployment to be backed up
type: string
backup_pvc:
description: Name of the PVC to be used for storing the backup
description: Name of the backup PVC
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
description: (Deprecated) Namespace the PVC is in
type: string
backup_storage_requirements:
description: Storage requirements for the PostgreSQL container
description: Storage requirements for backup PVC (may be similar to existing postgres PVC backing up from)
type: string
backup_storage_class:
description: Storage class to use when creating PVC for backup
type: string
clean_backup_on_delete:
description: Flag to indicate if backup should be deleted on PVC if AWXBackup object is deleted
type: boolean
postgres_label_selector:
description: Label selector used to identify postgres pod for backing up data
type: string
@@ -55,6 +58,10 @@ spec:
no_log:
description: Configure no_log for no_log tasks
type: string
set_self_labels:
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
type: boolean
default: true
status:
type: object
properties:

View File

@@ -33,7 +33,8 @@ spec:
- CR
- PVC
deployment_name:
description: Name of the deployment to be restored to
description: Name of the restored deployment. This should be different from the original deployment name
if the original deployment still exists.
type: string
backup_name:
description: AWXBackup object name
@@ -42,7 +43,7 @@ spec:
description: Name of the PVC to be restored from, set as a status found on the awxbackup object (backupClaim)
type: string
backup_pvc_namespace:
description: Namespace the PVC is in
description: (Deprecated) Namespace the PVC is in
type: string
backup_dir:
description: Backup directory name, set as a status found on the awxbackup object (backupDirectory)
@@ -59,6 +60,10 @@ spec:
no_log:
description: Configure no_log for no_log tasks
type: string
set_self_labels:
description: Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
type: boolean
default: true
status:
type: object
properties:

View File

@@ -54,6 +54,13 @@ spec:
port: 6789
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "32Mi"
cpu: "50m"
limits:
memory: "4096Mi"
cpu: "2000m"
serviceAccountName: controller-manager
imagePullSecrets:
- name: redhat-operators-pull-secret

View File

@@ -28,8 +28,7 @@ spec:
- displayName: Backup persistent volume claim namespace
path: backup_pvc_namespace
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Backup PVC storage requirements
path: backup_storage_requirements
x-descriptors:
@@ -67,12 +66,13 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
version: v1beta1
- description: Restore a previous awx deployment into the namespace
- description: Restore a previous awx deployment from an AWXBackup. The
deployment name you provide will be the name of the new AWX CR that will be created.
displayName: AWX Restore
kind: AWXRestore
name: awxrestores.awx.ansible.com
specDescriptors:
- displayName: Backup source to restore ?
- displayName: Backup source to restore from
path: backup_source
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:select:CR
@@ -94,7 +94,7 @@ spec:
- displayName: Backup namespace
path: backup_pvc_namespace
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:text
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Backup directory in the persistent volume claim
path: backup_dir
x-descriptors:
@@ -107,12 +107,10 @@ spec:
- displayName: PostgreSQL Image
path: postgres_image
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: PostgreSQL Image Version
path: postgres_image_version
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
statusDescriptors:
- description: The state of the restore
@@ -382,6 +380,10 @@ spec:
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:advanced
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Postgres Keep Old Data PVC After Upgrade
path: postgres_keep_pvc_after_upgrade
x-descriptors:
- urn:alm:descriptor:com.tectonic.ui:hidden
- displayName: Postgres Tolerations
path: postgres_tolerations
x-descriptors:

View File

@@ -49,13 +49,13 @@
name: Demo Job Template
wait: yes
validate_certs: no
controller_host: localhost
controller_host: localhost/awx/
controller_username: admin
controller_password: "{{ admin_pw_secret.resources[0].data.password | b64decode }}"
rescue:
- name: Get list of project updates and jobs
uri:
url: "http://localhost/api/v2/{{ resource }}/"
url: "http://localhost/awx/api/v2/{{ resource }}/"
user: admin
password: "{{ admin_pw_secret.resources[0].data.password | b64decode }}"
force_basic_auth: yes

View File

@@ -11,6 +11,7 @@ spec:
image_version: {{ awx_version }}
{% endif %}
ingress_type: ingress
ingress_path: /awx
ingress_annotations: |
kubernetes.io/ingress.class: nginx
web_resource_requirements:

0
projects/.gitkeep Executable file → Normal file
View File

View File

@@ -60,13 +60,7 @@ backup_storage_class: 'standard'
backup_storage_requirements: '20Gi'
```
By default, the backup pvc will be created in the same namespace the awxbackup object is created in. If you want your backup to be stored
in a specific namespace, you can do so by specifying `backup_pvc_namespace`. Keep in mind that you will
need to provide the same namespace when restoring.
```
backup_pvc_namespace: 'custom-namespace'
```
The backup pvc will be created in the same namespace the awxbackup object is created in.
If a custom postgres configuration secret was used when deploying AWX, it will automatically be used by the backup role.
To check the name of this secret, look at the postgresConfigurationSecret status on your AWX object.
@@ -74,7 +68,12 @@ To check the name of this secret, look at the postgresConfigurationSecret status
The postgresql pod for the old deployment is used when backing up data to the new postgresql pod. If your postgresql pod has a custom label,
you can pass that via the `postgres_label_selector` variable to make sure the postgresql pod can be found.
It is also possible to tie the lifetime of the backup files to that of the AWXBackup resource object. To do that you can set the
`clean_backup_on_delete` value to true. This will delete the `backupDirectory` on the pvc associated with the AWXBackup object deleted.
```
clean_backup_on_delete: true
```
Testing
----------------

View File

@@ -13,3 +13,15 @@ backup_storage_requirements: ''
# Set no_log settings on certain tasks
no_log: 'true'
# Variable to set when you want backups to be cleaned up when the CRD object is deleted
clean_backup_on_delete: false
# Variable to signal that this role is being run as a finalizer
finalizer_run: false
# Allow additional parameters to be added to the pg_dump backup command
pg_dump_suffix: ''
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
set_self_labels: true

View File

@@ -0,0 +1,48 @@
---
- name: Patching labels to {{ kind }} kind
k8s:
state: present
definition:
apiVersion: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
metadata:
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
labels:
app.kubernetes.io/name: "{{ ansible_operator_meta.name }}"
app.kubernetes.io/part-of: "{{ ansible_operator_meta.name }}"
app.kubernetes.io/managed-by: "{{ deployment_type }}-operator"
app.kubernetes.io/component: "{{ deployment_type }}"
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
when: set_self_labels | bool
- name: Look up details for this backup object
k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
register: this_backup
- block:
- include_tasks: init.yml
- include_tasks: postgres.yml
- include_tasks: awx-cro.yml
- include_tasks: secrets.yml
- name: Set flag signifying this backup was successful
set_fact:
backup_complete: true
- include_tasks: cleanup.yml
when:
- this_backup['resources'][0]['status']['backupDirectory'] is not defined
- name: Update status variables
include_tasks: update_status.yml

View File

@@ -0,0 +1,7 @@
---
- name: Cleanup backup associated with this option if enabled
k8s_exec:
namespace: "{{ backup_pvc_namespace }}"
pod: "{{ ansible_operator_meta.name }}-db-management"
command: >-
bash -c 'rm -rf {{ backup_dir }}'

View File

@@ -0,0 +1,19 @@
---
- name: Look up details for this backup object
k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
register: this_backup
- block:
- include_tasks: init.yml
- include_tasks: delete_backup.yml
- include_tasks: cleanup.yml
vars:
backup_dir: "{{ this_backup['resources'][0]['status']['backupDirectory'] }}"
when:
- clean_backup_on_delete and backup_dir is defined

View File

@@ -1,5 +1,4 @@
---
- name: Delete any existing management pod
k8s:
name: "{{ ansible_operator_meta.name }}-db-management"
@@ -57,8 +56,8 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: '{{ deployment_name }}-backup-claim'
namespace: '{{ backup_pvc_namespace }}'
name: "{{ deployment_name }}-backup-claim"
namespace: "{{ backup_pvc_namespace }}"
ownerReferences: null
when:
- backup_pvc == '' or backup_pvc is not defined

View File

@@ -1,47 +1,8 @@
---
- name: Patching labels to {{ kind }} kind
k8s:
state: present
definition:
apiVersion: '{{ api_version }}'
kind: '{{ kind }}'
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
- name: Run creation tasks
include_tasks: creation.yml
when: not finalizer_run
- name: Look up details for this backup object
k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
register: this_backup
- block:
- include_tasks: init.yml
- include_tasks: postgres.yml
- include_tasks: awx-cro.yml
- include_tasks: secrets.yml
- name: Set flag signifying this backup was successful
set_fact:
backup_complete: true
- include_tasks: cleanup.yml
when:
- this_backup['resources'][0]['status']['backupDirectory'] is not defined
- name: Update status variables
include_tasks: update_status.yml
- name: Run finalizer tasks
include_tasks: finalizer.yml
when: finalizer_run

View File

@@ -26,7 +26,7 @@
- block:
- name: Delete pod to reload a resource configuration
set_fact:
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ deployment_name }}"
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ supported_pg_version }}-{{ deployment_name }}"
when: postgres_label_selector is not defined
- name: Get the postgres pod information
@@ -91,6 +91,7 @@
-d {{ awx_postgres_database }}
-p {{ awx_postgres_port }}
-F custom
{{ pg_dump_suffix }}
no_log: "{{ no_log }}"
- name: Write pg_dump to backup on PVC

View File

@@ -1,6 +1,7 @@
---
deployment_type: "awx"
_postgres_image: postgres
_postgres_image_version: 12
_postgres_image_version: 13
backup_complete: false
database_type: "unmanaged"
supported_pg_version: 13

View File

@@ -127,9 +127,9 @@ extra_volumes: ''
_image: quay.io/ansible/awx
_image_version: "{{ lookup('env', 'DEFAULT_AWX_VERSION') or 'latest' }}"
_redis_image: docker.io/redis
_redis_image_version: latest
_redis_image_version: 7
_postgres_image: postgres
_postgres_image_version: 12
_postgres_image_version: 13
_init_container_image: quay.io/centos/centos
_init_container_image_version: stream8
image_pull_policy: IfNotPresent
@@ -223,6 +223,9 @@ ee_extra_volume_mounts: ''
# kubernetes.io/os: linux
postgres_selector: ''
# Specify whether or not to keep the old PVC after PostgreSQL upgrades
postgres_keep_pvc_after_upgrade: True
# Add node tolerations for the Postgres pods.
# Specify as literal block. E.g.:
# postgres_tolerations: |
@@ -284,3 +287,10 @@ security_context_settings: {}
# Set no_log settings on certain tasks
no_log: 'true'
# Should AWX instances be automatically upgraded when operator gets upgraded
#
auto_upgrade: true
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
set_self_labels: true

View File

@@ -92,6 +92,62 @@
set_fact:
__postgres_configuration_secret: "{{ pg_config['resources'][0]['metadata']['name'] }}"
- name: Store Database Configuration
set_fact:
awx_postgres_user: "{{ pg_config['resources'][0]['data']['username'] | b64decode }}"
awx_postgres_pass: "{{ pg_config['resources'][0]['data']['password'] | b64decode }}"
awx_postgres_database: "{{ pg_config['resources'][0]['data']['database'] | b64decode }}"
awx_postgres_port: "{{ pg_config['resources'][0]['data']['port'] | b64decode }}"
awx_postgres_host: "{{ pg_config['resources'][0]['data']['host'] | b64decode }}"
awx_postgres_sslmode: "{{ pg_config['resources'][0]['data']['sslmode'] | default('prefer'|b64encode) | b64decode }}"
no_log: "{{ no_log }}"
- name: Set database as managed
set_fact:
managed_database: "{{ pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed' }}"
- name: Get the old postgres pod information
k8s_info:
kind: Pod
namespace: "{{ ansible_operator_meta.namespace }}"
name: "{{ ansible_operator_meta.name }}-postgres-0"
field_selectors:
- status.phase=Running
register: old_postgres_pod
- name: Look up details for this deployment
k8s_info:
api_version: "{{ api_version }}"
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
register: this_awx
- name: Check if postgres pod is running and version 12
block:
- name: Set path to PG_VERSION file for given container image
set_fact:
path_to_pg_version: '{{ postgres_data_path }}/PG_VERSION'
- name: Get old PostgreSQL version
k8s_exec:
namespace: "{{ ansible_operator_meta.namespace }}"
pod: "{{ ansible_operator_meta.name }}-postgres-0"
command: |
bash -c """
cat {{ path_to_pg_version }}
"""
register: _old_pg_version
- name: Upgrade data dir from Postgres 12 to 13 if applicable
include_tasks: upgrade_postgres.yml
when:
- _old_pg_version.stdout | default('0') | trim == '12'
when:
- managed_database
- this_awx['resources'][0]['status']['upgradedPostgresVersion'] | default('none') != '12'
- old_postgres_pod['resources'] | length # upgrade is complete and old pg pod has been removed
- block:
- name: Create Database if no database is specified
k8s:
@@ -111,7 +167,7 @@
kubernetes.core.k8s_scale:
api_version: apps/v1
kind: StatefulSet
name: "{{ ansible_operator_meta.name }}-postgres"
name: "{{ ansible_operator_meta.name }}-postgres-13"
namespace: "{{ ansible_operator_meta.namespace }}"
replicas: 0
wait: yes
@@ -121,7 +177,7 @@
state: absent
api_version: apps/v1
kind: StatefulSet
name: "{{ ansible_operator_meta.name }}-postgres"
name: "{{ ansible_operator_meta.name }}-postgres-13"
namespace: "{{ ansible_operator_meta.namespace }}"
wait: yes
when: create_statefulset_result.error == 422
@@ -130,23 +186,29 @@
k8s:
apply: true
definition: "{{ lookup('template', 'postgres.yaml.j2') }}"
when: pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed'
when: managed_database
- name: Store Database Configuration
- name: Set Default label selector for custom resource generated postgres
set_fact:
awx_postgres_user: "{{ pg_config['resources'][0]['data']['username'] | b64decode }}"
awx_postgres_pass: "{{ pg_config['resources'][0]['data']['password'] | b64decode }}"
awx_postgres_database: "{{ pg_config['resources'][0]['data']['database'] | b64decode }}"
awx_postgres_port: "{{ pg_config['resources'][0]['data']['port'] | b64decode }}"
awx_postgres_host: "{{ pg_config['resources'][0]['data']['host'] | b64decode }}"
awx_postgres_sslmode: "{{ pg_config['resources'][0]['data']['sslmode'] | default('prefer'|b64encode) | b64decode }}"
no_log: "{{ no_log }}"
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}"
when: postgres_label_selector is not defined
- name: Get the postgres pod information
k8s_info:
kind: Pod
namespace: "{{ ansible_operator_meta.namespace }}"
label_selectors:
- "{{ postgres_label_selector }}"
field_selectors:
- status.phase=Running
register: postgres_pod
- name: Wait for Database to initialize if managed DB
k8s_info:
kind: Pod
namespace: '{{ ansible_operator_meta.namespace }}'
name: '{{ ansible_operator_meta.name }}-postgres-0' # using name to keep compatibility
label_selectors:
- "{{ postgres_label_selector }}"
field_selectors:
- status.phase=Running
register: postgres_pod
@@ -156,11 +218,7 @@
- "postgres_pod['resources'][0]['status']['containerStatuses'][0]['ready'] == true"
delay: 5
retries: 60
when: pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed'
- name: Set database as managed
set_fact:
managed_database: "{{ pg_config['resources'][0]['data']['type'] | default('') | b64decode == 'managed' }}"
when: managed_database
- name: Look up details for this deployment
k8s_info:

View File

@@ -0,0 +1,89 @@
---
- name: Patching labels to AWX kind
k8s:
state: present
definition:
apiVersion: '{{ api_version }}'
kind: '{{ kind }}'
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
when: set_self_labels | bool
- name: Include secret key configuration tasks
include_tasks: secret_key_configuration.yml
- name: Load LDAP CAcert certificate
include_tasks: load_ldap_cacert_secret.yml
when:
- ldap_cacert_secret != ''
- name: Load ldap bind password
include_tasks: load_ldap_password_secret.yml
when:
- ldap_password_secret != ''
- name: Load bundle certificate authority certificate
include_tasks: load_bundle_cacert_secret.yml
when:
- bundle_cacert_secret != ''
- name: Include admin password configuration tasks
include_tasks: admin_password_configuration.yml
- name: Include broadcast websocket configuration tasks
include_tasks: broadcast_websocket_configuration.yml
- name: Include set_images tasks
include_tasks: set_images.yml
- name: Include database configuration tasks
include_tasks: database_configuration.yml
- name: Load Route TLS certificate
include_tasks: load_route_tls_secret.yml
when:
- ingress_type | lower == 'route'
- route_tls_secret != ''
- name: Include resources configuration tasks
include_tasks: resources_configuration.yml
- name: Check for pending migrations
k8s_exec:
namespace: "{{ ansible_operator_meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ ansible_operator_meta.name }}-task"
command: >-
bash -c "awx-manage showmigrations | grep -v '[X]' | grep '[ ]' | wc -l"
changed_when: false
register: database_check
- name: Migrate the database if the K8s resources were updated. # noqa 305
k8s_exec:
namespace: "{{ ansible_operator_meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ ansible_operator_meta.name }}-task"
command: >-
bash -c "awx-manage migrate --noinput"
register: migrate_result
when:
- database_check is defined
- (database_check.stdout|trim) != '0'
- name: Initialize Django
include_tasks: initialize_django.yml
- name: Update status variables
include_tasks: update_status.yml
- name: Cleanup & Set garbage collection refs
include_tasks: cleanup.yml

View File

@@ -1,88 +1,13 @@
---
- name: Patching labels to AWX kind
k8s:
state: present
definition:
apiVersion: '{{ api_version }}'
kind: '{{ kind }}'
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
metadata:
name: '{{ ansible_operator_meta.name }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
- name: Include secret key configuration tasks
include_tasks: secret_key_configuration.yml
- name: Load LDAP CAcert certificate
include_tasks: load_ldap_cacert_secret.yml
when:
- ldap_cacert_secret != ''
- name: Load ldap bind password
include_tasks: load_ldap_password_secret.yml
when:
- ldap_password_secret != ''
- name: Load bundle certificate authority certificate
include_tasks: load_bundle_cacert_secret.yml
when:
- bundle_cacert_secret != ''
- name: Include admin password configuration tasks
include_tasks: admin_password_configuration.yml
- name: Include broadcast websocket configuration tasks
include_tasks: broadcast_websocket_configuration.yml
- name: Include set_images tasks
include_tasks: set_images.yml
- name: Include database configuration tasks
include_tasks: database_configuration.yml
- name: Load Route TLS certificate
include_tasks: load_route_tls_secret.yml
when:
- ingress_type | lower == 'route'
- route_tls_secret != ''
- name: Include resources configuration tasks
include_tasks: resources_configuration.yml
- name: Check for pending migrations
k8s_exec:
- name: Check for presence of Deployment
k8s_info:
api_version: v1
kind: Deployment
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ ansible_operator_meta.name }}-task"
command: >-
bash -c "awx-manage showmigrations | grep -v '[X]' | grep '[ ]' | wc -l"
changed_when: false
register: database_check
register: tower_deployment
- name: Migrate the database if the K8s resources were updated. # noqa 305
k8s_exec:
namespace: "{{ ansible_operator_meta.namespace }}"
pod: "{{ tower_pod_name }}"
container: "{{ ansible_operator_meta.name }}-task"
command: >-
bash -c "awx-manage migrate --noinput"
register: migrate_result
when:
- database_check is defined
- (database_check.stdout|trim) != '0'
- name: Initialize Django
include_tasks: initialize_django.yml
- name: Update status variables
include_tasks: update_status.yml
- name: Cleanup & Set garbage collection refs
include_tasks: cleanup.yml
# Just execute deployment steps when auto_upgrade is true or when no deployment exists
- name: Start installation
include_tasks: install.yml
when: (tower_deployment['resources'] | length > 0 and auto_upgrade | bool ) or (tower_deployment['resources'] | length == 0)

View File

@@ -13,25 +13,20 @@
awx_old_postgres_host: "{{ old_pg_config['resources'][0]['data']['host'] | b64decode }}"
no_log: "{{ no_log }}"
- name: Default label selector to custom resource generated postgres
- name: Set Default label selector for custom resource generated postgres
set_fact:
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ ansible_operator_meta.name }}"
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}"
when: postgres_label_selector is not defined
- name: Get the postgres pod information
k8s_info:
kind: Pod
namespace: '{{ ansible_operator_meta.namespace }}'
name: '{{ ansible_operator_meta.name }}-postgres-0' # using name to keep compatibility
namespace: "{{ ansible_operator_meta.namespace }}"
label_selectors:
- "{{ postgres_label_selector }}"
field_selectors:
- status.phase=Running
register: postgres_pod
until:
- "postgres_pod['resources'] | length"
- "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
- "postgres_pod['resources'][0]['status']['containerStatuses'][0]['ready'] == true"
delay: 5
retries: 60
- name: Set the resource pod name as a variable.
set_fact:

View File

@@ -11,11 +11,11 @@
- "app.kubernetes.io/component={{ deployment_type }}"
field_selectors:
- status.phase=Running
register: tower_pods
register: tower_pod
- name: Set the resource pod name as a variable.
set_fact:
tower_pod_name: "{{ tower_pods['resources'][0]['metadata']['name'] | default('') }}"
tower_pod_name: "{{ tower_pod['resources'][0]['metadata']['name'] | default('') }}"
- name: Set user provided control plane ee image
set_fact:
@@ -77,7 +77,7 @@
apply: yes
definition: "{{ lookup('template', 'deployment.yaml.j2') }}"
wait: yes
register: tower_deployment_result
register: this_deployment_result
- block:
- name: Delete pod to reload a resource configuration
@@ -113,7 +113,7 @@
set_fact:
tower_pod_name: '{{ _new_pod["resources"][0]["metadata"]["name"] }}'
when:
- tower_resources_result.changed or tower_deployment_result.changed
- tower_resources_result.changed or this_deployment_result.changed
- name: Verify the resource pod name is populated.
assert:

View File

@@ -6,7 +6,7 @@
kind: Deployment
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
register: tower_deployment
register: this_deployment
- name: Scale down Deployment for migration
kubernetes.core.k8s_scale:
@@ -16,4 +16,4 @@
namespace: "{{ ansible_operator_meta.namespace }}"
replicas: 0
wait: yes
when: tower_deployment['resources'] | length
when: this_deployment['resources'] | length

View File

@@ -101,3 +101,13 @@
status:
migratedFromSecret: "{{ tower_migrated_from_secret }}"
when: tower_migrated_from_secret is defined
- name: Update upgradedPostgresVersion status
operator_sdk.util.k8s_status:
api_version: '{{ api_version }}'
kind: "{{ kind }}"
name: "{{ ansible_operator_meta.name }}"
namespace: "{{ ansible_operator_meta.namespace }}"
status:
upgradedPostgresVersion: "{{ upgraded_postgres_version }}"
when: upgraded_postgres_version is defined

View File

@@ -0,0 +1,132 @@
---
# Upgrade Posgres (Managed Databases only)
# * If postgres version is not 12, and not an external postgres instance (when managed_database is yes),
# then run this playbook with include_tasks from database_configuration.yml
# * Data will be streamed via a pg_dump from the postgres 12 pod to the postgres 13
# pod via a pg_restore.
- name: Scale down Deployment for migration
include_tasks: scale_down_deployment.yml
- name: Delete existing postgres configuration secret
k8s:
api_version: v1
kind: Secret
name: "{{ ansible_operator_meta.name }}-postgres-configuration"
namespace: "{{ ansible_operator_meta.namespace }}"
state: absent
wait: yes
- name: Create Database configuration with new -postgres-{{ supported_pg_version }} hostname
k8s:
apply: true
definition: "{{ lookup('template', 'postgres_upgrade_secret.yaml.j2') }}"
no_log: "{{ no_log }}"
- name: Set new database var to be used when configuring app credentials (resources_configuration.yml)
set_fact:
awx_postgres_host: "{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}"
no_log: "{{ no_log }}"
- name: Create Database if no database is specified
k8s:
apply: true
definition: "{{ lookup('template', 'postgres.yaml.j2') }}"
wait: true
register: create_statefulset_result
- name: Set postgres label if not defined by user
set_fact:
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}"
when: postgres_label_selector is not defined
- name: Get new postgres pod information
k8s_info:
kind: Pod
namespace: "{{ ansible_operator_meta.namespace }}"
label_selectors:
- "{{ postgres_label_selector }}"
field_selectors:
- status.phase=Running
register: postgres_pod
until:
- "postgres_pod['resources'] | length"
- "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
- "postgres_pod['resources'][0]['status']['containerStatuses'][0]['ready'] == true"
delay: 5
retries: 60
- name: Set the resource pod name as a variable.
set_fact:
postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}"
- name: Set full resolvable host name for postgres pod
set_fact:
resolvable_db_host: "{{ ansible_operator_meta.name }}-postgres.{{ ansible_operator_meta.namespace }}.svc.cluster.local" # yamllint disable-line rule:line-length
no_log: "{{ no_log }}"
- name: Set pg_dump command
set_fact:
pgdump: >-
pg_dump
-h {{ resolvable_db_host }}
-U {{ awx_postgres_user }}
-d {{ awx_postgres_database }}
-p {{ awx_postgres_port }}
-F custom
no_log: "{{ no_log }}"
- name: Set pg_restore command
set_fact:
pg_restore: >-
pg_restore
-U {{ awx_postgres_user }}
-d {{ awx_postgres_database }}
no_log: "{{ no_log }}"
- name: Stream backup from pg_dump to the new postgresql container
k8s_exec:
namespace: "{{ ansible_operator_meta.namespace }}"
pod: "{{ postgres_pod_name }}"
command: |
bash -c """
set -e -o pipefail
PGPASSWORD={{ awx_postgres_pass }} {{ pgdump }} | PGPASSWORD={{ awx_postgres_pass }} {{ pg_restore }}
echo 'Successful'
"""
no_log: "{{ no_log }}"
register: data_migration
failed_when: "'Successful' not in data_migration.stdout"
- name: Set flag signifying that this instance has been migrated
set_fact:
upgraded_postgres_version: '13'
# Cleanup old Postgres resources
- name: Remove old Postgres StatefulSet
k8s:
kind: StatefulSet
api_version: v1
namespace: "{{ ansible_operator_meta.namespace }}"
name: "{{ ansible_operator_meta.name }}-postgres"
state: absent
wait: true
- name: Remove old Postgres Service
k8s:
kind: Service
api_version: v1
namespace: "{{ ansible_operator_meta.namespace }}"
name: "{{ ansible_operator_meta.name }}-postgres"
state: absent
- name: Remove old persistent volume claim
k8s:
kind: PersistentVolumeClaim
api_version: v1
namespace: "{{ ansible_operator_meta.namespace }}"
name: "postgres-{{ ansible_operator_meta.name }}-postgres-0"
state: absent
when: postgres_keep_pvc_after_upgrade

View File

@@ -145,6 +145,7 @@ data:
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
server {
listen 8052 default_server;
listen [::]:8052 default_server;
server_name _;
# Redirect all HTTP links to the matching HTTPS page
@@ -155,6 +156,7 @@ data:
server {
{% if route_tls_termination_mechanism | lower == 'passthrough' %}
listen 8053 ssl;
listen [::]:8053 ssl;
ssl_certificate /etc/nginx/pki/web.crt;
ssl_certificate_key /etc/nginx/pki/web.key;
@@ -165,6 +167,7 @@ data:
ssl_prefer_server_ciphers on;
{% else %}
listen 8052 default_server;
listen [::]:8052 default_server;
{% endif %}
# If you have a domain name, this is where to add it

View File

@@ -4,3 +4,8 @@ AUTH_LDAP_GLOBAL_OPTIONS = {
ldap.OPT_X_TLS_CACERTFILE: "/etc/openldap/certs/ldap-ca.crt"
{% endif %}
}
# Load LDAP BIND password from Kubernetes secret if define
{% if ldap_password_secret -%}
AUTH_LDAP_BIND_PASSWORD = "{{ ldap_bind_password }}"
{% endif %}

View File

@@ -3,11 +3,11 @@
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: '{{ ansible_operator_meta.name }}-postgres'
name: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
@@ -16,8 +16,8 @@ metadata:
spec:
selector:
matchLabels:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
serviceName: '{{ ansible_operator_meta.name }}'
@@ -27,8 +27,8 @@ spec:
template:
metadata:
labels:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
@@ -45,20 +45,6 @@ spec:
{% if postgres_priority_class is defined %}
priorityClassName: '{{ postgres_priority_class }}'
{% endif %}
initContainers:
- name: database-check
image: '{{ _init_container_image }}'
resources: {{ postgres_init_container_resource_requirements }}
imagePullPolicy: '{{ image_pull_policy }}'
command:
- /bin/sh
- -c
- |
[[ -d /check-db/pgsql/data ]] && rm -rf /check-db/data && mv /check-db/pgsql/data/ /check-db/data/ && rm -rf /check-db/pgsql || exit 0
volumeMounts:
- name: postgres
mountPath: /check-db
subPath: ''
containers:
- image: '{{ _postgres_image }}'
imagePullPolicy: '{{ image_pull_policy }}'
@@ -67,7 +53,7 @@ spec:
args: {{ postgres_extra_args }}
{% endif %}
env:
# For postgres_image based on rhel8/postgresql-12
# For postgres_image based on rhel8/postgresql-13
- name: POSTGRESQL_DATABASE
valueFrom:
secretKeyRef:
@@ -108,9 +94,9 @@ spec:
value: '{{ postgres_host_auth_method }}'
ports:
- containerPort: {{ awx_postgres_port | default('5432')}}
name: postgres
name: postgres-{{ supported_pg_version }}
volumeMounts:
- name: postgres
- name: postgres-{{ supported_pg_version }}
mountPath: '{{ postgres_data_path | dirname }}'
subPath: '{{ postgres_data_path | dirname | basename }}'
resources: {{ postgres_resource_requirements }}
@@ -124,7 +110,7 @@ spec:
{% endif %}
volumeClaimTemplates:
- metadata:
name: postgres
name: postgres-{{ supported_pg_version }}
spec:
accessModes:
- ReadWriteOnce
@@ -138,11 +124,11 @@ spec:
apiVersion: v1
kind: Service
metadata:
name: '{{ ansible_operator_meta.name }}-postgres'
name: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
@@ -153,8 +139,8 @@ spec:
- port: 5432
clusterIP: None
selector:
app.kubernetes.io/name: 'postgres'
app.kubernetes.io/instance: 'postgres-{{ ansible_operator_meta.name }}'
app.kubernetes.io/name: 'postgres-{{ supported_pg_version }}'
app.kubernetes.io/instance: 'postgres-{{ supported_pg_version }}-{{ ansible_operator_meta.name }}'
app.kubernetes.io/component: 'database'
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'

View File

@@ -16,5 +16,5 @@ stringData:
username: '{{ database_username }}'
database: '{{ database_name }}'
port: '5432'
host: {{ ansible_operator_meta.name }}-postgres
host: {{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}
type: 'managed'

View File

@@ -0,0 +1,20 @@
# Postgres Secret.
---
apiVersion: v1
kind: Secret
metadata:
name: '{{ ansible_operator_meta.name }}-postgres-configuration'
namespace: '{{ ansible_operator_meta.namespace }}'
labels:
app.kubernetes.io/name: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/part-of: '{{ ansible_operator_meta.name }}'
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
stringData:
password: '{{ awx_postgres_pass }}'
username: '{{ awx_postgres_user }}'
database: '{{ awx_postgres_database }}'
port: '{{ awx_postgres_port }}'
host: '{{ ansible_operator_meta.name }}-postgres-{{ supported_pg_version }}'
type: 'managed'

View File

@@ -4,3 +4,4 @@ postgres_host_auth_method: 'scram-sha-256'
ldap_cacert_ca_crt: ''
bundle_ca_crt: ''
projects_existing_claim: ''
supported_pg_version: 13

View File

@@ -33,7 +33,6 @@ metadata:
spec:
deployment_name: mytower
backup_name: awxbackup-2021-04-22
backup_pvc_namespace: 'old-awx-namespace'
```
Note that the `deployment_name` above is the name of the AWX deployment you intend to create and restore to.
@@ -81,11 +80,7 @@ awx-backup-volume-claim
backup_pvc: 'awx-backup-volume-claim'
```
By default, the backup pvc will be created in the same namespace the awxbackup object is created in. This namespace must be specified using the `backup_pvc_namespace` variable.
```
backup_pvc_namespace: 'custom-namespace'
```
The backup pvc will be created in the same namespace the awxbackup object is created in.
If a custom postgres configuration secret was used when deploying AWX, it must be set:

View File

@@ -13,3 +13,6 @@ backup_dir: ''
# Set no_log settings on certain tasks
no_log: 'true'
# Maintain some of the recommended `app.kubernetes.io/*` labels on the resource (self)
set_self_labels: true

View File

@@ -16,6 +16,7 @@
app.kubernetes.io/managed-by: '{{ deployment_type }}-operator'
app.kubernetes.io/component: '{{ deployment_type }}'
app.kubernetes.io/operator-version: '{{ lookup("env", "OPERATOR_VERSION") }}'
when: set_self_labels | bool
- name: Look up details for this restore object
k8s_info:

View File

@@ -22,28 +22,29 @@
awx_postgres_type: "{{ pg_config['resources'][0]['data']['type'] | b64decode | default('unmanaged') }}"
no_log: "{{ no_log }}"
- name: Default label selector to custom resource generated postgres
- name: Set Default label selector for custom resource generated postgres
set_fact:
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ deployment_name }}"
postgres_label_selector: "app.kubernetes.io/instance=postgres-{{ supported_pg_version }}-{{ deployment_name }}"
when: postgres_label_selector is not defined
- name: Get the postgres pod information
k8s_info:
kind: Pod
namespace: '{{ ansible_operator_meta.namespace }}'
label_selectors:
- "{{ postgres_label_selector }}"
register: postgres_pod
until:
- "postgres_pod['resources'] | length"
- "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
- "postgres_pod['resources'][0]['status']['containerStatuses'][0]['ready'] == true"
delay: 5
retries: 60
- name: Set the resource pod name as a variable.
set_fact:
postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}"
- block:
- name: Get the postgres pod information
k8s_info:
kind: Pod
namespace: '{{ ansible_operator_meta.namespace }}'
label_selectors:
- "{{ postgres_label_selector }}"
register: postgres_pod
until:
- "postgres_pod['resources'] | length"
- "postgres_pod['resources'][0]['status']['phase'] == 'Running'"
- "postgres_pod['resources'][0]['status']['containerStatuses'][0]['ready'] == true"
delay: 5
retries: 60
- name: Set the resource pod name as a variable.
set_fact:
postgres_pod_name: "{{ postgres_pod['resources'][0]['metadata']['name'] }}"
when: awx_postgres_type == 'managed'
- name: Check for presence of AWX Deployment
k8s_info:

View File

@@ -30,7 +30,7 @@
block:
- name: Set new database host
set_fact:
database_host: "{{ deployment_name }}-postgres"
database_host: "{{ deployment_name }}-postgres-{{ supported_pg_version }}"
no_log: "{{ no_log }}"
- name: Set tmp postgres secret dict

View File

@@ -2,7 +2,7 @@
deployment_type: "awx"
_postgres_image: postgres
_postgres_image_version: 12
_postgres_image_version: 13
backup_api_version: '{{ deployment_type }}.ansible.com/v1beta1'
backup_kind: 'AWXBackup'
@@ -12,3 +12,4 @@ secret_key_secret: '{{ deployment_name }}-secret-key'
admin_password_secret: '{{ deployment_name }}-admin-password'
broadcast_websocket_secret: '{{ deployment_name }}-broadcast-websocket'
postgres_configuration_secret: '{{ deployment_name }}-postgres-configuration'
supported_pg_version: 13

View File

@@ -11,6 +11,11 @@
kind: AWXBackup
role: backup
snakeCaseParameters: False
finalizer:
name: awx.ansible.com/finalizer
role: backup
vars:
finalizer_run: true
- version: v1beta1
group: awx.ansible.com