mirror of
https://github.com/ansible/awx-operator.git
synced 2026-04-16 05:41:08 +00:00
Merge pull request #4 from matburt/awxify
Moving towards AWX as the default
This commit is contained in:
11
.travis.yml
11
.travis.yml
@@ -2,8 +2,17 @@
|
||||
services: docker
|
||||
language: python
|
||||
|
||||
before_install:
|
||||
- curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
|
||||
- sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"
|
||||
- sudo apt-get update
|
||||
- sudo apt-get -y -o Dpkg::Options::="--force-confnew" install docker-ce
|
||||
|
||||
env:
|
||||
- DOCKER_API_VERSION=1.38
|
||||
|
||||
install:
|
||||
- pip3 install docker molecule yamllint ansible-lint openshift jmespath
|
||||
- pip3 install docker molecule==3.0.6 yamllint ansible-lint openshift jmespath
|
||||
|
||||
script:
|
||||
- molecule test -s test-local
|
||||
|
||||
75
README.md
75
README.md
@@ -1,8 +1,8 @@
|
||||
# Ansible Tower/AWX Operator
|
||||
|
||||
An [Ansible Tower](https://www.ansible.com/products/tower) operator for Kubernetes built with [Operator SDK](https://github.com/operator-framework/operator-sdk) and Ansible.
|
||||
An [Ansible AWX](https://github.com/ansible/awx) operator for Kubernetes built with [Operator SDK](https://github.com/operator-framework/operator-sdk) and Ansible.
|
||||
|
||||
Also configurable to run the open source [AWX](https://github.com/ansible/awx) instead of Tower (helpful for certain use cases where a license requirement is not warranted, like CI environments).
|
||||
Also configurable to be able to run [Tower](https://ansible.com/products/tower)
|
||||
|
||||
## Purpose
|
||||
|
||||
@@ -11,7 +11,7 @@ There are already official OpenShift/Kubernetes installers available for both AW
|
||||
- [AWX on Kubernetes](https://github.com/ansible/awx/blob/devel/INSTALL.md#kubernetes)
|
||||
- [Ansible Tower on Kubernetes](https://docs.ansible.com/ansible-tower/latest/html/administration/openshift_configuration.html)
|
||||
|
||||
This operator is meant to provide a more Kubernetes-native installation method for Ansible Tower or AWX via a Tower Custom Resource Definition (CRD).
|
||||
This operator is meant to provide a more Kubernetes-native installation method for Ansible Tower or AWX via an AWX Custom Resource Definition (CRD).
|
||||
|
||||
Note that the operator is not supported by Red Hat, and is in alpha status. Long-term, this operator will become the supported method of installing on Kubernetes and Openshift, and will be listed on OperatorHub.io. For now, use it at your own risk!
|
||||
|
||||
@@ -19,59 +19,42 @@ Note that the operator is not supported by Red Hat, and is in alpha status. Long
|
||||
|
||||
This Kubernetes Operator is meant to be deployed in your Kubernetes cluster(s) and can manage one or more Tower or AWX instances in any namespace.
|
||||
|
||||
First you need to deploy Tower Operator into your cluster:
|
||||
First you need to deploy AWX Operator into your cluster:
|
||||
|
||||
kubectl apply -f https://raw.githubusercontent.com/ansible/tower-operator/devel/deploy/tower-operator.yaml
|
||||
kubectl apply -f https://raw.githubusercontent.com/ansible/awx-operator/devel/deploy/awx-operator.yaml
|
||||
|
||||
Then you can create instances of Tower, for example:
|
||||
Then you can create instances of AWX, for example:
|
||||
|
||||
1. Make sure the namespace you're deploying into already exists (e.g. `kubectl create namespace ansible-tower`).
|
||||
1. Create a file named `my-tower.yml` with the following contents:
|
||||
1. Make sure the namespace you're deploying into already exists (e.g. `kubectl create namespace ansible-awx`).
|
||||
2. Create a file named `my-awx.yml` with the following contents:
|
||||
|
||||
```
|
||||
---
|
||||
apiVersion: tower.ansible.com/v1beta1
|
||||
kind: Tower
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: tower
|
||||
namespace: ansible-tower
|
||||
name: awx
|
||||
namespace: ansible-awx
|
||||
spec:
|
||||
deployment_type: tower
|
||||
tower_secret_key: aabbcc
|
||||
deployment_type: awx
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
tower_admin_password: changeme
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
```
|
||||
|
||||
1. Use `kubectl` to create the mcrouter instance in your cluster:
|
||||
3. Use `kubectl` to create the mcrouter instance in your cluster:
|
||||
|
||||
```
|
||||
kubectl apply -f my-tower.yml
|
||||
kubectl apply -f my-awx.yml
|
||||
```
|
||||
|
||||
After a few minutes, your new Tower instance will be accessible at `http://tower.mycompany.com/` (assuming your cluster has an Ingress controller configured). Log in using the `tower_admin_` credentials configured in the `spec`, and supply a valid license to begin using Tower.
|
||||
After a few minutes, your new AWX instance will be accessible at `http://awx.mycompany.com/` (assuming your cluster has an Ingress controller configured). Log in using the `tower_admin_` credentials configured in the `spec`.
|
||||
|
||||
### Red Hat Registry Authentication
|
||||
|
||||
To deploy Ansible Tower, images are pulled from the Red Hat Registry. Your Kubernetes or OpenShift cluster will have to have [Authentication Enabled for the Red Hat Registry](https://access.redhat.com/documentation/en-us/openshift_container_platform/3.11/html/configuring_clusters/install-config-configuring-red-hat-registry) for this to work, otherwise the Tower image will not be pulled.
|
||||
|
||||
If you deploy Ansible AWX, images are available from public registries, so no authentication is required.
|
||||
|
||||
### Deploy AWX instead of Tower
|
||||
|
||||
If you would like to deploy AWX (the open source upstream of Tower) into your cluster instead of Tower, override the default variables in the Tower `spec` for the `tower_task_image` and `tower_web_image`, so the AWX container images are used instead, and set the `deployment_type` to ``awx`:
|
||||
|
||||
---
|
||||
spec:
|
||||
...
|
||||
deployment_type: awx
|
||||
tower_task_image: ansible/awx_task:11.2.0
|
||||
tower_web_image: ansible/awx_web:11.2.0
|
||||
|
||||
### Ingress Types
|
||||
|
||||
Depending on the cluster that you're running on, you may wish to use an `Ingress` to access your tower or you may wish to use a `Route` to access your tower. To toggle between these two options, you can add the following to your Tower custom resource:
|
||||
Depending on the cluster that you're running on, you may wish to use an `Ingress` to access your tower or you may wish to use a `Route` to access your awx. To toggle between these two options, you can add the following to your Tower custom resource:
|
||||
|
||||
---
|
||||
spec:
|
||||
@@ -84,7 +67,7 @@ OR
|
||||
spec:
|
||||
...
|
||||
tower_ingress_type: Ingress
|
||||
tower_hostname: tower.mycompany.com
|
||||
tower_hostname: awx.mycompany.com
|
||||
|
||||
By default, no ingress/route is deployed as the default is set to `none`.
|
||||
|
||||
@@ -97,9 +80,9 @@ Depending on the type of tasks that you'll be running, you may find that you nee
|
||||
...
|
||||
tower_task_privileged: true
|
||||
|
||||
If you are attempting to do this on an OpenShift cluster, you will need to grant the `tower` ServiceAccount the `privileged` SCC, which can be done with:
|
||||
If you are attempting to do this on an OpenShift cluster, you will need to grant the `awx` ServiceAccount the `privileged` SCC, which can be done with:
|
||||
|
||||
oc adm policy add-scc-to-user privileged -z tower
|
||||
oc adm policy add-scc-to-user privileged -z awx
|
||||
|
||||
Again, this is the most relaxed SCC that is provided by OpenShift, so be sure to familiarize yourself with the security concerns that accompany this action.
|
||||
|
||||
@@ -152,8 +135,8 @@ Once the operator is deployed, you can visit the Tower UI in your browser by fol
|
||||
|
||||
There are a few moving parts to this project:
|
||||
|
||||
1. The Docker image which powers Tower Operator.
|
||||
2. The `tower-operator.yaml` Kubernetes manifest file which initially deploys the Operator into a cluster.
|
||||
1. The Docker image which powers AWX Operator.
|
||||
2. The `awx-operator.yaml` Kubernetes manifest file which initially deploys the Operator into a cluster.
|
||||
|
||||
Each of these must be appropriately built in preparation for a new tag:
|
||||
|
||||
@@ -161,17 +144,17 @@ Each of these must be appropriately built in preparation for a new tag:
|
||||
|
||||
Run the following command inside this directory:
|
||||
|
||||
operator-sdk build ansible/tower-operator:0.4.0
|
||||
operator-sdk build ansible/awx-operator:0.4.0
|
||||
|
||||
Then push the generated image to Docker Hub:
|
||||
|
||||
docker push ansible/tower-operator:0.4.0
|
||||
docker push ansible/awx-operator:0.4.0
|
||||
|
||||
#### Build a new version of the `tower-operator.yaml` file
|
||||
#### Build a new version of the `awx-operator.yaml` file
|
||||
|
||||
Update the tower-operator version in two places:
|
||||
Update the awx-operator version in two places:
|
||||
|
||||
1. `deploy/tower-operator.yaml`: in the `ansible` and `operator` container definitions in the `tower-operator` Deployment.
|
||||
1. `deploy/awx-operator.yaml`: in the `ansible` and `operator` container definitions in the `awx-operator` Deployment.
|
||||
2. `build/chain-operator-files.yml`: the `operator_image` variable.
|
||||
|
||||
Once the versions are updated, run the playbook in the `build/` directory:
|
||||
@@ -182,8 +165,8 @@ After it is built, test it on a local cluster:
|
||||
|
||||
minikube start --memory 6g --cpus 4
|
||||
minikube addons enable ingress
|
||||
kubectl apply -f deploy/tower-operator.yaml
|
||||
kubectl create namespace example-tower
|
||||
kubectl apply -f deploy/awx-operator.yaml
|
||||
kubectl create namespace example-awx
|
||||
kubectl apply -f deploy/crds/tower_v1beta1_tower_cr_awx.yaml
|
||||
<test everything>
|
||||
minikube delete
|
||||
|
||||
@@ -6,19 +6,19 @@
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
operator_image: ansible/tower-operator:0.4.0
|
||||
operator_image: ansible/awx-operator:0.4.0
|
||||
pull_policy: Always
|
||||
operator_file_path: "../deploy/tower-operator.yaml"
|
||||
operator_file_path: "../deploy/awx-operator.yaml"
|
||||
operator_template: "../deploy/operator.yaml"
|
||||
|
||||
tasks:
|
||||
- name: Clear out current contents of tower-operator.yml
|
||||
- name: Clear out current contents of awx-operator.yml
|
||||
copy:
|
||||
dest: "{{ operator_file_path }}"
|
||||
content: ''
|
||||
force: true
|
||||
|
||||
- name: Concatenate operator files into tower-operator.yml
|
||||
- name: Concatenate operator files into awx-operator.yml
|
||||
blockinfile:
|
||||
path: "{{ operator_file_path }}"
|
||||
block: "{{ item }}"
|
||||
@@ -33,12 +33,12 @@
|
||||
- "../deploy/service_account.yaml"
|
||||
- "../deploy/operator.yaml"
|
||||
|
||||
- name: Remove space at beginning of tower-operator.yml
|
||||
- name: Remove space at beginning of awx-operator.yml
|
||||
shell: >
|
||||
echo "$(tail -n +2 {{ operator_file_path }})" > {{ operator_file_path }}
|
||||
changed_when: true
|
||||
|
||||
- name: Template the tower-operator.yaml file into tower-operator.yml
|
||||
- name: Template the awx-operator.yaml file into awx-operator.yml
|
||||
template:
|
||||
src: "{{ operator_file_path }}"
|
||||
dest: "{{ operator_file_path }}"
|
||||
|
||||
@@ -3,7 +3,7 @@ FROM ${BASEIMAGE}
|
||||
USER 0
|
||||
|
||||
RUN yum install -y python-devel gcc libffi-devel
|
||||
RUN pip install molecule==2.20.1
|
||||
RUN pip install molecule==3.0.6 jmespath
|
||||
|
||||
ARG NAMESPACEDMAN
|
||||
ADD $NAMESPACEDMAN /namespaced.yaml
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- route.openshift.io
|
||||
@@ -45,7 +45,7 @@ rules:
|
||||
- apiGroups:
|
||||
- apps
|
||||
resourceNames:
|
||||
- tower-operator
|
||||
- awx-operator
|
||||
resources:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
@@ -64,7 +64,7 @@ rules:
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- tower.ansible.com
|
||||
- awx.ansible.com
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
@@ -74,53 +74,54 @@ rules:
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
namespace: default
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
namespace: default
|
||||
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
namespace: default
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
spec:
|
||||
serviceAccountName: tower-operator
|
||||
serviceAccountName: awx-operator
|
||||
containers:
|
||||
- name: ansible
|
||||
command:
|
||||
- /usr/local/bin/ao-logs
|
||||
- /tmp/ansible-operator/runner
|
||||
- stdout
|
||||
image: "ansible/tower-operator:0.4.0"
|
||||
image: "ansible/awx-operator:0.4.0"
|
||||
imagePullPolicy: "Always"
|
||||
volumeMounts:
|
||||
- mountPath: /tmp/ansible-operator/runner
|
||||
name: runner
|
||||
readOnly: true
|
||||
- name: operator
|
||||
image: "ansible/tower-operator:0.4.0"
|
||||
image: "ansible/awx-operator:0.4.0"
|
||||
imagePullPolicy: "Always"
|
||||
volumeMounts:
|
||||
- mountPath: /tmp/ansible-operator/runner
|
||||
@@ -134,7 +135,7 @@ spec:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: OPERATOR_NAME
|
||||
value: tower-operator
|
||||
value: awx-operator
|
||||
volumes:
|
||||
- name: runner
|
||||
emptyDir: {}
|
||||
@@ -143,14 +144,14 @@ spec:
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: towers.tower.ansible.com
|
||||
name: awxs.awx.ansible.com
|
||||
spec:
|
||||
group: tower.ansible.com
|
||||
group: awx.ansible.com
|
||||
names:
|
||||
kind: Tower
|
||||
listKind: TowerList
|
||||
plural: towers
|
||||
singular: tower
|
||||
kind: AWX
|
||||
listKind: AWXList
|
||||
plural: awxs
|
||||
singular: awx
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
@@ -161,7 +162,7 @@ spec:
|
||||
storage: true
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the Tower CRD
|
||||
description: Schema validation for the AWX CRD
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
@@ -170,5 +171,27 @@ spec:
|
||||
deployment_type:
|
||||
type: string
|
||||
pattern: "^(tower|awx)(-)?.*$"
|
||||
external_database:
|
||||
type: bool
|
||||
description: |
|
||||
If true you must supply a secret containing the location and credentials for
|
||||
connecting to the external database by a user who has permission to create
|
||||
and apply a schema.
|
||||
|
||||
The secret should have the name: <custom resource name>-postgres-configuration and
|
||||
should look like:
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <crname>-postgres-configuration
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
address: <external ip or url resolvable by the cluster>
|
||||
port: <external port, this usually defaults to 5432>
|
||||
database: <desired database name>
|
||||
username: <username to connect as>
|
||||
password: <password to connect with>
|
||||
type: Opaque
|
||||
required:
|
||||
- deployment_type
|
||||
@@ -1,24 +1,23 @@
|
||||
---
|
||||
apiVersion: tower.ansible.com/v1beta1
|
||||
kind: Tower
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: example-tower
|
||||
namespace: example-tower
|
||||
name: example-awx
|
||||
namespace: example-awx
|
||||
spec:
|
||||
deployment_type: awx
|
||||
tower_ingress_type: none
|
||||
tower_task_privileged: false
|
||||
|
||||
tower_hostname: example-tower.test
|
||||
tower_secret_key: aabbcc
|
||||
tower_hostname: example-awx.test
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
tower_admin_password: changeme
|
||||
|
||||
tower_task_image: ansible/awx_task:11.2.0
|
||||
tower_web_image: ansible/awx_web:11.2.0
|
||||
tower_task_image: ansible/awx:14.0.0
|
||||
tower_web_image: ansible/awx:14.0.0
|
||||
|
||||
tower_task_mem_request: 1Gi
|
||||
tower_task_cpu_request: 500m
|
||||
@@ -32,7 +31,5 @@ spec:
|
||||
|
||||
tower_redis_image: redis:latest
|
||||
|
||||
tower_postgres_pass: awxpass
|
||||
tower_postgres_image: postgres:10
|
||||
tower_postgres_storage_request: 8Gi
|
||||
tower_postgres_storage_class: ''
|
||||
55
deploy/crds/awx_v1beta1_crd.yaml
Normal file
55
deploy/crds/awx_v1beta1_crd.yaml
Normal file
@@ -0,0 +1,55 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: awxs.awx.ansible.com
|
||||
spec:
|
||||
group: awx.ansible.com
|
||||
names:
|
||||
kind: AWX
|
||||
listKind: AWXList
|
||||
plural: awxs
|
||||
singular: awx
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
version: v1beta1
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the AWX CRD
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
deployment_type:
|
||||
type: string
|
||||
pattern: "^(tower|awx)(-)?.*$"
|
||||
external_database:
|
||||
type: bool
|
||||
description: |
|
||||
If true you must supply a secret containing the location and credentials for
|
||||
connecting to the external database by a user who has permission to create
|
||||
and apply a schema.
|
||||
|
||||
The secret should have the name: <custom resource name>-postgres-configuration and
|
||||
should look like:
|
||||
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: <crname>-postgres-configuration
|
||||
namespace: <target namespace>
|
||||
stringData:
|
||||
address: <external ip or url resolvable by the cluster>
|
||||
port: <external port, this usually defaults to 5432>
|
||||
database: <desired database name>
|
||||
username: <username to connect as>
|
||||
password: <password to connect with>
|
||||
type: Opaque
|
||||
required:
|
||||
- deployment_type
|
||||
@@ -1,24 +1,23 @@
|
||||
---
|
||||
apiVersion: tower.ansible.com/v1beta1
|
||||
kind: Tower
|
||||
apiVersion: awx.ansible.com/v1beta1
|
||||
kind: AWX
|
||||
metadata:
|
||||
name: example-tower
|
||||
namespace: example-tower
|
||||
name: example-awx
|
||||
namespace: example-awx
|
||||
spec:
|
||||
deployment_type: awx
|
||||
tower_ingress_type: ingress
|
||||
tower_task_privileged: false
|
||||
|
||||
tower_hostname: example-tower.test
|
||||
tower_secret_key: aabbcc
|
||||
tower_hostname: example-awx.test
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
tower_admin_password: changeme
|
||||
|
||||
tower_task_image: ansible/awx_task:11.2.0
|
||||
tower_web_image: ansible/awx_web:11.2.0
|
||||
tower_task_image: ansible/awx:14.0.0
|
||||
tower_web_image: ansible/awx:14.0.0
|
||||
|
||||
tower_task_mem_request: 128M
|
||||
tower_task_cpu_request: 500m
|
||||
@@ -1,38 +0,0 @@
|
||||
---
|
||||
apiVersion: tower.ansible.com/v1beta1
|
||||
kind: Tower
|
||||
metadata:
|
||||
name: example-tower
|
||||
namespace: example-tower
|
||||
spec:
|
||||
deployment_type: tower
|
||||
tower_ingress_type: none
|
||||
tower_task_privileged: false
|
||||
|
||||
tower_hostname: example-tower.test
|
||||
tower_secret_key: aabbcc
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
tower_admin_password: changeme
|
||||
|
||||
tower_task_image: registry.redhat.io/ansible-tower-37/ansible-tower-rhel7:3.7.0
|
||||
tower_web_image: registry.redhat.io/ansible-tower-37/ansible-tower-rhel7:3.7.0
|
||||
|
||||
tower_task_mem_request: 1Gi
|
||||
tower_task_cpu_request: 500m
|
||||
|
||||
tower_web_mem_request: 2Gi
|
||||
tower_web_cpu_request: 1000m
|
||||
|
||||
tower_create_preload_data: true
|
||||
|
||||
tower_memcached_image: memcached:alpine
|
||||
|
||||
tower_redis_image: redis:latest
|
||||
|
||||
tower_postgres_pass: awxpass
|
||||
tower_postgres_image: postgres:10
|
||||
tower_postgres_storage_request: 8Gi
|
||||
tower_postgres_storage_class: ''
|
||||
@@ -1,33 +0,0 @@
|
||||
---
|
||||
apiVersion: apiextensions.k8s.io/v1beta1
|
||||
kind: CustomResourceDefinition
|
||||
metadata:
|
||||
name: towers.tower.ansible.com
|
||||
spec:
|
||||
group: tower.ansible.com
|
||||
names:
|
||||
kind: Tower
|
||||
listKind: TowerList
|
||||
plural: towers
|
||||
singular: tower
|
||||
scope: Namespaced
|
||||
subresources:
|
||||
status: {}
|
||||
version: v1beta1
|
||||
versions:
|
||||
- name: v1beta1
|
||||
served: true
|
||||
storage: true
|
||||
validation:
|
||||
openAPIV3Schema:
|
||||
description: Schema validation for the Tower CRD
|
||||
type: object
|
||||
properties:
|
||||
spec:
|
||||
type: object
|
||||
properties:
|
||||
deployment_type:
|
||||
type: string
|
||||
pattern: "^(tower|awx)(-)?.*$"
|
||||
required:
|
||||
- deployment_type
|
||||
@@ -2,18 +2,18 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
spec:
|
||||
serviceAccountName: tower-operator
|
||||
serviceAccountName: awx-operator
|
||||
containers:
|
||||
- name: ansible
|
||||
command:
|
||||
@@ -41,7 +41,7 @@ spec:
|
||||
fieldRef:
|
||||
fieldPath: metadata.name
|
||||
- name: OPERATOR_NAME
|
||||
value: tower-operator
|
||||
value: awx-operator
|
||||
volumes:
|
||||
- name: runner
|
||||
emptyDir: {}
|
||||
|
||||
@@ -3,7 +3,7 @@ apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: ClusterRole
|
||||
metadata:
|
||||
creationTimestamp: null
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
rules:
|
||||
- apiGroups:
|
||||
- route.openshift.io
|
||||
@@ -45,7 +45,7 @@ rules:
|
||||
- apiGroups:
|
||||
- apps
|
||||
resourceNames:
|
||||
- tower-operator
|
||||
- awx-operator
|
||||
resources:
|
||||
- deployments/finalizers
|
||||
verbs:
|
||||
@@ -64,7 +64,7 @@ rules:
|
||||
verbs:
|
||||
- get
|
||||
- apiGroups:
|
||||
- tower.ansible.com
|
||||
- awx.ansible.com
|
||||
resources:
|
||||
- '*'
|
||||
verbs:
|
||||
|
||||
@@ -2,12 +2,12 @@
|
||||
kind: ClusterRoleBinding
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
metadata:
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
namespace: default
|
||||
roleRef:
|
||||
kind: ClusterRole
|
||||
name: tower-operator
|
||||
name: awx-operator
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
|
||||
@@ -2,5 +2,4 @@
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: tower-operator
|
||||
namespace: default
|
||||
name: awx-operator
|
||||
|
||||
@@ -7,14 +7,14 @@
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
|
||||
tasks:
|
||||
- name: Get tower Pod data
|
||||
- name: Get AWX Pod data
|
||||
k8s_info:
|
||||
kind: Pod
|
||||
namespace: example-tower
|
||||
namespace: example-awx
|
||||
label_selectors:
|
||||
- app=tower
|
||||
- app=awx
|
||||
register: tower_pods
|
||||
|
||||
- name: Verify there is one tower pod
|
||||
- name: Verify there is one AWX pod
|
||||
assert:
|
||||
that: '{{ (tower_pods.resources | length) == 1 }}'
|
||||
|
||||
@@ -5,6 +5,6 @@
|
||||
vars:
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
roles:
|
||||
- tower
|
||||
- awx
|
||||
|
||||
- import_playbook: '{{ playbook_dir }}/asserts.yml'
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
tasks:
|
||||
- name: Create Custom Resource Definition
|
||||
k8s:
|
||||
definition: "{{ lookup('file', '/'.join([deploy_dir, 'crds/tower_v1beta1_tower_crd.yaml'])) }}"
|
||||
definition: "{{ lookup('file', '/'.join([deploy_dir, 'crds/awx_v1beta1_crd.yaml'])) }}"
|
||||
|
||||
- name: Ensure specified namespace is present
|
||||
k8s:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
hosts: k8s
|
||||
|
||||
vars:
|
||||
image_name: tower.ansible.com/tower-operator:testing
|
||||
image_name: awx.ansible.com/awx-operator:testing
|
||||
|
||||
tasks:
|
||||
# using command so we don't need to install any dependencies
|
||||
@@ -25,8 +25,8 @@
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
deploy_dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/deploy"
|
||||
pull_policy: Never
|
||||
operator_image: tower.ansible.com/tower-operator:testing
|
||||
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/tower_v1beta1_tower_cr_molecule.yaml'])) | from_yaml }}"
|
||||
operator_image: awx.ansible.com/awx-operator:testing
|
||||
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/awx_v1beta1_molecule.yaml'])) | from_yaml }}"
|
||||
|
||||
tasks:
|
||||
|
||||
@@ -59,14 +59,14 @@
|
||||
namespace: '{{ operator_namespace }}'
|
||||
definition: "{{ lookup('template', '/'.join([deploy_dir, 'operator.yaml'])) }}"
|
||||
|
||||
- name: Ensure the Tower custom_resource namespace exists
|
||||
- name: Ensure the AWX custom_resource namespace exists
|
||||
k8s:
|
||||
state: present
|
||||
name: '{{ custom_resource.metadata.namespace }}'
|
||||
kind: Namespace
|
||||
api_version: v1
|
||||
|
||||
- name: Create the Tower Custom Resource
|
||||
- name: Create the AWX Custom Resource
|
||||
k8s:
|
||||
state: present
|
||||
namespace: '{{ custom_resource.metadata.namespace }}'
|
||||
@@ -99,7 +99,7 @@
|
||||
resource_name=custom_resource.metadata.name
|
||||
)}}'
|
||||
|
||||
- name: debug tower deployment
|
||||
- name: debug awx deployment
|
||||
ignore_errors: yes
|
||||
failed_when: false
|
||||
debug:
|
||||
@@ -109,7 +109,7 @@
|
||||
kind="Deployment",
|
||||
api_version="apps/v1",
|
||||
namespace=custom_resource.metadata.namespace,
|
||||
label_selector="app=tower"
|
||||
label_selector="app=awx"
|
||||
)}}'
|
||||
|
||||
- name: get operator logs
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
regexp: 8443
|
||||
replace: "{{ lookup('env', 'KIND_PORT') }}"
|
||||
path: '{{ kubeconfig }}'
|
||||
mode: 0644
|
||||
delegate_to: localhost
|
||||
|
||||
- name: Wait for the Kubernetes API to become available (this could take a minute)
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
connection: local
|
||||
|
||||
vars:
|
||||
image_name: tower.ansible.com/tower-operator:testing
|
||||
image_name: awx.ansible.com/awx-operator:testing
|
||||
|
||||
tasks:
|
||||
# Use raw Docker commands inside Minikube to avoid extra Python dependencies.
|
||||
@@ -33,9 +33,9 @@
|
||||
ansible_python_interpreter: '{{ ansible_playbook_python }}'
|
||||
deploy_dir: "{{ lookup('env', 'MOLECULE_PROJECT_DIRECTORY') }}/deploy"
|
||||
pull_policy: Never
|
||||
operator_image: tower.ansible.com/tower-operator:testing
|
||||
operator_image: awx.ansible.com/awx-operator:testing
|
||||
# Change this to _awx to test AWX, _tower to test Tower.
|
||||
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/tower_v1beta1_tower_cr_awx.yaml'])) | from_yaml }}"
|
||||
custom_resource: "{{ lookup('file', '/'.join([deploy_dir, 'crds/awx_v1beta1_molecule.yaml'])) | from_yaml }}"
|
||||
|
||||
tasks:
|
||||
- block:
|
||||
@@ -66,14 +66,14 @@
|
||||
namespace: '{{ operator_namespace }}'
|
||||
definition: "{{ lookup('template', '/'.join([deploy_dir, 'operator.yaml'])) }}"
|
||||
|
||||
- name: Ensure the Tower custom_resource namespace exists
|
||||
- name: Ensure the AWX custom_resource namespace exists
|
||||
k8s:
|
||||
state: present
|
||||
name: '{{ custom_resource.metadata.namespace }}'
|
||||
kind: Namespace
|
||||
api_version: v1
|
||||
|
||||
- name: Create the Tower Custom Resource
|
||||
- name: Create the AWX Custom Resource
|
||||
k8s:
|
||||
state: present
|
||||
namespace: '{{ custom_resource.metadata.namespace }}'
|
||||
@@ -106,7 +106,7 @@
|
||||
resource_name=custom_resource.metadata.name
|
||||
)}}'
|
||||
|
||||
- name: debug tower deployment
|
||||
- name: debug awx deployment
|
||||
ignore_errors: yes
|
||||
failed_when: false
|
||||
debug:
|
||||
@@ -116,7 +116,7 @@
|
||||
kind="Deployment",
|
||||
api_version="apps/v1",
|
||||
namespace=custom_resource.metadata.namespace,
|
||||
label_selector="app=tower"
|
||||
label_selector="app=awx"
|
||||
)}}'
|
||||
|
||||
- name: get operator logs
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
tower_task_privileged: false
|
||||
tower_ingress_type: none
|
||||
|
||||
tower_hostname: example-tower.test
|
||||
tower_secret_key: aabbcc
|
||||
tower_hostname: example-awx.test
|
||||
|
||||
tower_admin_user: test
|
||||
tower_admin_email: test@example.com
|
||||
@@ -12,12 +11,12 @@ tower_admin_password: changeme
|
||||
tower_broadcast_websocket_secret: changeme
|
||||
|
||||
# Use these image versions for Ansible Tower.
|
||||
tower_task_image: registry.redhat.io/ansible-tower-37/ansible-tower-rhel7:3.7.0
|
||||
tower_web_image: registry.redhat.io/ansible-tower-37/ansible-tower-rhel7:3.7.0
|
||||
# tower_task_image: registry.redhat.io/ansible-tower-37/ansible-tower-rhel7:3.7.0
|
||||
# tower_web_image: registry.redhat.io/ansible-tower-37/ansible-tower-rhel7:3.7.0
|
||||
|
||||
# Use these image versions for Ansible AWX.
|
||||
# tower_task_image: ansible/awx_task:11.2.0
|
||||
# tower_web_image: ansible/awx_web:11.2.0
|
||||
tower_task_image: ansible/awx:14.0.0
|
||||
tower_web_image: ansible/awx:14.0.0
|
||||
|
||||
tower_create_preload_data: true
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
galaxy_info:
|
||||
author: Ansible
|
||||
description: Tower role for Tower Operator for Kubernetes.
|
||||
description: AWX role for AWX Operator for Kubernetes.
|
||||
company: Red Hat, Inc.
|
||||
|
||||
license: MIT
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
- name: Check if there are any Tower super users defined.
|
||||
- name: Check if there are any AWX super users defined.
|
||||
shell: >-
|
||||
kubectl exec -n {{ meta.namespace }} -c {{ meta.name }}-task {{ tower_pod_name }} -- bash -c
|
||||
"echo 'from django.contrib.auth.models import User;
|
||||
@@ -10,7 +10,7 @@
|
||||
register: users_result
|
||||
changed_when: users_result.rc > 0
|
||||
|
||||
- name: Create Tower super user via Django if it doesn't exist.
|
||||
- name: Create AWX super user via Django if it doesn't exist.
|
||||
shell: >-
|
||||
kubectl exec -n {{ meta.namespace }} -c {{ meta.name }}-task {{ tower_pod_name }} -- bash -c
|
||||
"echo \"from django.contrib.auth.models import User;
|
||||
110
roles/awx/tasks/main.yml
Normal file
110
roles/awx/tasks/main.yml
Normal file
@@ -0,0 +1,110 @@
|
||||
---
|
||||
- name: Include deployment type vars
|
||||
include_vars: "{{ deployment_type }}.yml"
|
||||
|
||||
- name: Check for existing secret key
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
register: secret_key_resources
|
||||
|
||||
- name: Check for existing postgres configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
register: postgres_config_resources
|
||||
|
||||
- name: Create Database configuration if it doesn't already exist
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'tower_postgres_secret.yaml.j2') }}"
|
||||
register: k8s_postgres_config_result
|
||||
when: postgres_config_resources['resources'] | length < 1 and not external_database | default(False) | bool
|
||||
|
||||
- name: Create Database if External Database not selected
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'tower_postgres.yaml.j2') }}"
|
||||
register: k8s_postgres_result
|
||||
when: not external_database | default(False) | bool
|
||||
|
||||
- name: Read Database Configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
register: postgres_configuration
|
||||
|
||||
- name: Store Database Configuration
|
||||
set_fact:
|
||||
awx_postgres_user: "{{ postgres_configuration['resources'][0]['data']['username'] | b64decode }}"
|
||||
awx_postgres_pass: "{{ postgres_configuration['resources'][0]['data']['password'] | b64decode }}"
|
||||
awx_postgres_database: "{{ postgres_configuration['resources'][0]['data']['database'] | b64decode }}"
|
||||
awx_postgres_port: "{{ postgres_configuration['resources'][0]['data']['port'] | b64decode }}"
|
||||
awx_postgres_host: "{{ postgres_configuration['resources'][0]['data']['host'] | b64decode }}"
|
||||
|
||||
- name: Deploy Tower Secret Key if needed
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'tower_secret.yaml.j2') }}"
|
||||
register: k8s_tower_secret_result
|
||||
when: secret_key_resources['resources'] | length < 1
|
||||
|
||||
- name: Ensure configured AWX resources exist in the cluster.
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', item) | from_yaml_all | list }}"
|
||||
register: k8s_defs_result
|
||||
with_items:
|
||||
- tower_config.yaml.j2
|
||||
- launch_awx.yaml.j2
|
||||
- supervisor.yaml.j2
|
||||
|
||||
- name: Apply Tower Deployment Configuration
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', 'tower.yaml.j2') }}"
|
||||
register: tower_deployment_result
|
||||
|
||||
- name: Get the AWX pod information.
|
||||
k8s_info:
|
||||
kind: Pod
|
||||
namespace: '{{ meta.namespace }}'
|
||||
label_selectors:
|
||||
- app=awx
|
||||
register: tower_pods
|
||||
until: "tower_pods['resources'][0]['status']['phase'] == 'Running'"
|
||||
delay: 5
|
||||
retries: 60
|
||||
|
||||
- name: Set the awx pod name as a variable.
|
||||
set_fact:
|
||||
tower_pod_name: "{{ tower_pods['resources'][0]['metadata']['name'] }}"
|
||||
|
||||
- name: Verify tower_pod_name is populated.
|
||||
assert:
|
||||
that: tower_pod_name != ''
|
||||
fail_msg: "Could not find the tower pod's name."
|
||||
|
||||
- name: Check if database is populated (auth_user table exists).
|
||||
shell: >-
|
||||
kubectl exec -n {{ meta.namespace }} -c {{ meta.name }}-task {{ tower_pod_name }} -- bash -c
|
||||
"echo 'from django.db import connection;
|
||||
tbl = \"auth_user\" in connection.introspection.table_names();
|
||||
exit(0 if tbl else 1)'
|
||||
| awx-manage shell"
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
register: database_check
|
||||
when: k8s_defs_result is not changed
|
||||
|
||||
- name: Migrate the database if the K8s resources were updated. # noqa 305
|
||||
shell: >-
|
||||
kubectl exec -n {{ meta.namespace }} -c {{ meta.name }}-task {{ tower_pod_name }} -- bash -c
|
||||
"awx-manage migrate --noinput"
|
||||
register: migrate_result
|
||||
when: (k8s_defs_result is changed) or (database_check is defined and database_check.rc != 0)
|
||||
|
||||
- include_tasks: initialize.yml
|
||||
@@ -2,11 +2,11 @@ DATABASES = {
|
||||
'default': {
|
||||
'ATOMIC_REQUESTS': True,
|
||||
'ENGINE': 'awx.main.db.profiled_pg',
|
||||
'NAME': "awx",
|
||||
'USER': "awx",
|
||||
'PASSWORD': "{{ tower_postgres_pass }}",
|
||||
'HOST': '{{ meta.name }}-postgres',
|
||||
'PORT': "{{ tower_postgres_port }}",
|
||||
'NAME': "{{ awx_postgres_database }}",
|
||||
'USER': "{{ awx_postgres_user }}",
|
||||
'PASSWORD': "{{ awx_postgres_pass }}",
|
||||
'HOST': '{{ awx_postgres_host }}',
|
||||
'PORT': "{{ awx_postgres_port }}",
|
||||
'OPTIONS': { 'sslmode': '{{ pg_sslmode|default("prefer") }}',
|
||||
'sslrootcert': '{{ ca_trust_bundle }}',
|
||||
},
|
||||
5
roles/awx/templates/environment.sh.j2
Normal file
5
roles/awx/templates/environment.sh.j2
Normal file
@@ -0,0 +1,5 @@
|
||||
DATABASE_USER={{ awx_postgres_user }}
|
||||
DATABASE_NAME={{ awx_postgres_database }}
|
||||
DATABASE_HOST={{ awx_postgres_host }}
|
||||
DATABASE_PORT={{ awx_postgres_port }}
|
||||
DATABASE_PASSWORD={{ awx_postgres_pass }}
|
||||
@@ -5,7 +5,7 @@ metadata:
|
||||
name: {{ meta.name }}-launch-awx
|
||||
namespace: {{ meta.namespace }}
|
||||
labels:
|
||||
app: tower
|
||||
app: awx
|
||||
data:
|
||||
launch-awx-task: |
|
||||
#!/usr/bin/env bash
|
||||
@@ -5,12 +5,14 @@ metadata:
|
||||
name: {{ meta.name }}-supervisor-config
|
||||
namespace: {{ meta.namespace }}
|
||||
labels:
|
||||
app: tower
|
||||
app: awx
|
||||
data:
|
||||
supervisor-web-config: |
|
||||
[supervisord]
|
||||
nodaemon = True
|
||||
umask = 022
|
||||
logfile = /dev/stdout
|
||||
logfile_maxbytes = 0
|
||||
|
||||
[program:nginx]
|
||||
command = nginx -g "daemon off;"
|
||||
@@ -96,6 +98,8 @@ data:
|
||||
[supervisord]
|
||||
nodaemon = True
|
||||
umask = 022
|
||||
logfile = /dev/stdout
|
||||
logfile_maxbytes = 0
|
||||
|
||||
[program:dispatcher]
|
||||
command = awx-manage run_dispatcher
|
||||
@@ -1,16 +1,15 @@
|
||||
# Tower Secret.
|
||||
# AWX Secret Configurations
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-secrets'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
data:
|
||||
secret_key: '{{ tower_secret_key | b64encode }}'
|
||||
credentials_py: "{{ lookup('template', 'credentials.py.j2') | b64encode }}"
|
||||
environment_sh: "{{ lookup('template', 'environment.sh.j2') | b64encode }}"
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-secrets'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
data:
|
||||
credentials_py: "{{ lookup('template', 'credentials.py.j2') | b64encode }}"
|
||||
environment_sh: "{{ lookup('template', 'environment.sh.j2') | b64encode }}"
|
||||
|
||||
# Tower Deployment.
|
||||
# AWX Deployment.
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
@@ -18,16 +17,16 @@ metadata:
|
||||
name: '{{ meta.name }}'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: tower
|
||||
app: awx
|
||||
spec:
|
||||
replicas: {{ tower_replicas }}
|
||||
selector:
|
||||
matchLabels:
|
||||
app: tower
|
||||
app: awx
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: tower
|
||||
app: awx
|
||||
spec:
|
||||
containers:
|
||||
- name: memcached
|
||||
@@ -167,25 +166,25 @@ spec:
|
||||
path: 'environment.sh'
|
||||
- name: {{ meta.name }}-secret-key
|
||||
secret:
|
||||
secretName: '{{ meta.name }}-secrets'
|
||||
secretName: '{{ meta.name }}-secret-key'
|
||||
items:
|
||||
- key: secret_key
|
||||
path: SECRET_KEY
|
||||
- name: {{ meta.name }}-settings
|
||||
configMap:
|
||||
name: '{{ meta.name }}-tower-configmap'
|
||||
name: '{{ meta.name }}-awx-configmap'
|
||||
items:
|
||||
- key: settings
|
||||
path: settings.py
|
||||
- name: {{ meta.name }}-nginx-conf
|
||||
configMap:
|
||||
name: '{{ meta.name }}-tower-configmap'
|
||||
name: '{{ meta.name }}-awx-configmap'
|
||||
items:
|
||||
- key: nginx_conf
|
||||
path: nginx.conf
|
||||
- name: {{ meta.name }}-redis-config
|
||||
configMap:
|
||||
name: {{ meta.name }}-tower-configmap
|
||||
name: {{ meta.name }}-awx-configmap
|
||||
items:
|
||||
- key: redis_conf
|
||||
path: redis.conf
|
||||
@@ -226,7 +225,7 @@ spec:
|
||||
- name: rsyslog-dir
|
||||
emptyDir: {}
|
||||
|
||||
# Tower Service.
|
||||
# AWX Service.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
@@ -234,7 +233,7 @@ metadata:
|
||||
name: '{{ meta.name }}-service'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: tower
|
||||
app: awx
|
||||
spec:
|
||||
ports:
|
||||
- port: 80
|
||||
@@ -242,9 +241,9 @@ spec:
|
||||
targetPort: 8052
|
||||
name: http
|
||||
selector:
|
||||
app: tower
|
||||
app: awx
|
||||
|
||||
# Tower Ingress.
|
||||
# AWX Ingress.
|
||||
{% if 'ingress' == tower_ingress_type|lower %}
|
||||
---
|
||||
apiVersion: extensions/v1beta1
|
||||
@@ -1,12 +1,12 @@
|
||||
# Tower Web ConfigMap.
|
||||
# AWX Web ConfigMap.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: '{{ meta.name }}-tower-configmap'
|
||||
name: '{{ meta.name }}-awx-configmap'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: tower
|
||||
app: awx
|
||||
data:
|
||||
environment: |
|
||||
DATABASE_USER=awx
|
||||
@@ -1,13 +1,3 @@
|
||||
# Postgres Secret.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-postgres-pass'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
data:
|
||||
password: '{{ tower_postgres_pass | b64encode }}'
|
||||
|
||||
# Postgres StatefulSet.
|
||||
---
|
||||
apiVersion: v1
|
||||
@@ -16,11 +6,11 @@ metadata:
|
||||
name: '{{ meta.name }}-postgres'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: tower-postgres
|
||||
app: awx-postgres
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
app: tower-postgres
|
||||
app: awx-postgres
|
||||
serviceName: '{{ meta.name }}'
|
||||
replicas: 1
|
||||
updateStrategy:
|
||||
@@ -28,25 +18,31 @@ spec:
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: tower-postgres
|
||||
app: awx-postgres
|
||||
spec:
|
||||
containers:
|
||||
- image: '{{ tower_postgres_image }}'
|
||||
name: postgres
|
||||
env:
|
||||
- name: POSTGRES_DB
|
||||
value: awx
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
key: database
|
||||
- name: POSTGRES_USER
|
||||
value: awx
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
key: username
|
||||
- name: POSTGRES_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: '{{ meta.name }}-postgres-pass'
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
key: password
|
||||
- name: PGDATA
|
||||
value: '{{ tower_postgres_data_path }}'
|
||||
ports:
|
||||
- containerPort: 3306
|
||||
- containerPort: 5432
|
||||
name: postgres
|
||||
volumeMounts:
|
||||
- name: postgres
|
||||
@@ -73,11 +69,11 @@ metadata:
|
||||
name: '{{ meta.name }}-postgres'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
labels:
|
||||
app: tower-postgres
|
||||
app: awx-postgres
|
||||
spec:
|
||||
ports:
|
||||
- port: 5432
|
||||
clusterIP: None
|
||||
selector:
|
||||
app: tower-postgres
|
||||
app: awx-postgres
|
||||
|
||||
13
roles/awx/templates/tower_postgres_secret.yaml.j2
Normal file
13
roles/awx/templates/tower_postgres_secret.yaml.j2
Normal file
@@ -0,0 +1,13 @@
|
||||
# Postgres Secret.
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
stringData:
|
||||
password: '{{ lookup('password', 'p' + meta.name + 'pg length=32 chars=ascii_letters,digits') }}'
|
||||
username: 'awx'
|
||||
database: 'awx'
|
||||
port: '5432'
|
||||
host: {{ meta.name }}-postgres
|
||||
8
roles/awx/templates/tower_secret.yaml.j2
Normal file
8
roles/awx/templates/tower_secret.yaml.j2
Normal file
@@ -0,0 +1,8 @@
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
stringData:
|
||||
secret_key: '{{ lookup('password', 'ts' + meta.name + 'pg length=32 chars=ascii_letters,digits') }}'
|
||||
36
roles/awx_remove/tasks/main.yml
Normal file
36
roles/awx_remove/tasks/main.yml
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
- name: Check for existing secret key
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
register: secret_key_resources
|
||||
|
||||
- name: Check for existing postgres configuration
|
||||
k8s_info:
|
||||
kind: Secret
|
||||
namespace: '{{ meta.namespace }}'
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
register: postgres_config_resources
|
||||
|
||||
- name: Remove ownerReferences from PG configuration if it exists
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-postgres-configuration'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
ownerReferences: null
|
||||
when: postgres_config_resources['resources'] | length > 0
|
||||
|
||||
- name: Remove ownerReferences from Tower Secret if it exists
|
||||
k8s:
|
||||
definition:
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: '{{ meta.name }}-secret-key'
|
||||
namespace: '{{ meta.namespace }}'
|
||||
ownerReferences: null
|
||||
when: secret_key_resources['resources'] | length > 0
|
||||
@@ -1,70 +0,0 @@
|
||||
---
|
||||
- name: Include deployment type vars
|
||||
include_vars: "{{ deployment_type }}.yml"
|
||||
|
||||
- name: Ensure configured Tower resources exist in the cluster.
|
||||
k8s:
|
||||
apply: yes
|
||||
definition: "{{ lookup('template', item) | from_yaml_all | list }}"
|
||||
register: k8s_defs_result
|
||||
with_items:
|
||||
- tower_postgres.yaml.j2
|
||||
- tower_config.yaml.j2
|
||||
- launch_awx.yaml.j2
|
||||
- supervisor.yaml.j2
|
||||
- tower.yaml.j2
|
||||
|
||||
- name: Get the Tower pod information.
|
||||
k8s_info:
|
||||
kind: Pod
|
||||
namespace: '{{ meta.namespace }}'
|
||||
label_selectors:
|
||||
- app=tower
|
||||
register: tower_pods
|
||||
until: "tower_pods['resources'][0]['status']['phase'] == 'Running'"
|
||||
delay: 5
|
||||
retries: 60
|
||||
|
||||
- name: Set the tower pod name as a variable.
|
||||
set_fact:
|
||||
tower_pod_name: "{{ tower_pods['resources'][0]['metadata']['name'] }}"
|
||||
|
||||
- name: Verify tower_pod_name is populated.
|
||||
assert:
|
||||
that: tower_pod_name != ''
|
||||
fail_msg: "Could not find the tower pod's name."
|
||||
|
||||
- name: Check if database is populated (auth_user table exists).
|
||||
shell: >-
|
||||
kubectl exec -n {{ meta.namespace }} -c {{ meta.name }}-task {{ tower_pod_name }} -- bash -c
|
||||
"echo 'from django.db import connection;
|
||||
tbl = \"auth_user\" in connection.introspection.table_names();
|
||||
exit(0 if tbl else 1)'
|
||||
| awx-manage shell"
|
||||
ignore_errors: true
|
||||
changed_when: false
|
||||
register: database_check
|
||||
when: k8s_defs_result is not changed
|
||||
|
||||
- name: Migrate the database if the K8s resources were updated. # noqa 305
|
||||
shell: >-
|
||||
kubectl exec -n {{ meta.namespace }} -c {{ meta.name }}-task {{ tower_pod_name }} -- bash -c
|
||||
"awx-manage migrate --noinput"
|
||||
register: migrate_result
|
||||
when: (k8s_defs_result is changed) or (database_check is defined and database_check.rc != 0)
|
||||
|
||||
- include_tasks: initialize.yml
|
||||
|
||||
- name: Scale the tower deployment to 0 replicas after migration.
|
||||
k8s:
|
||||
definition: "{{ lookup('template', 'tower.yaml.j2') | from_yaml_all | list }}"
|
||||
vars:
|
||||
tower_replicas: "0"
|
||||
when: migrate_result and migrate_result.changed
|
||||
|
||||
- name: Scale the tower deployment back to 1 replica after migration.
|
||||
k8s:
|
||||
definition: "{{ lookup('template', 'tower.yaml.j2') | from_yaml_all | list }}"
|
||||
vars:
|
||||
tower_replicas: "1"
|
||||
when: migrate_result and migrate_result.changed
|
||||
@@ -1,5 +0,0 @@
|
||||
DATABASE_USER=awx
|
||||
DATABASE_NAME=awx
|
||||
DATABASE_HOST={{ meta.name }}-postgres
|
||||
DATABASE_PORT={{ tower_postgres_port }}
|
||||
DATABASE_PASSWORD={{ tower_postgres_pass }}
|
||||
@@ -1,5 +1,8 @@
|
||||
---
|
||||
- version: v1beta1
|
||||
group: tower.ansible.com
|
||||
kind: Tower
|
||||
group: awx.ansible.com
|
||||
kind: AWX
|
||||
playbook: /opt/ansible/main.yml
|
||||
finalizer:
|
||||
name: finalizer.awx.ansible.com
|
||||
role: awx_remove
|
||||
|
||||
Reference in New Issue
Block a user