ansible: Deploy ARA
[ARA Records Ansible][0] is a results storage system for Ansible. It provides a convenient UI for tracking Ansible playbooks and tasks. The data are populated by an Ansible callback plugin. ARA is a fairly simple Python+Django application. It needs a database to store Ansible results, so we've connected it to the main PostgreSQL database and configured it to connect and authenticate using mTLS. Rather than mess with managing and distributing a static password for ARA clients, I've configured Autheliad to allow anonymous access to post data to the ARA API from within the private network or the Kubernetes cluster. Access to the web UI does require authentication. [0]: https://ara.recordsansible.org/pull/48/head
parent
32175156ac
commit
759d8f112f
|
@ -0,0 +1 @@
|
||||||
|
ara/.secrets.toml
|
|
@ -0,0 +1,87 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Service
|
||||||
|
metadata:
|
||||||
|
name: ara
|
||||||
|
labels: &labels
|
||||||
|
app.kubernetes.io/name: ara
|
||||||
|
app.kubernetes.io/component: ara
|
||||||
|
spec:
|
||||||
|
selector: *labels
|
||||||
|
type: ClusterIP
|
||||||
|
ports:
|
||||||
|
- name: http
|
||||||
|
port: 8000
|
||||||
|
targetPort: 8000
|
||||||
|
|
||||||
|
---
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: ara
|
||||||
|
labels: &labels
|
||||||
|
app.kubernetes.io/name: ara
|
||||||
|
app.kubernetes.io/component: ara
|
||||||
|
spec:
|
||||||
|
selector:
|
||||||
|
matchLabels: *labels
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels: *labels
|
||||||
|
spec:
|
||||||
|
enableServiceLinks: false
|
||||||
|
containers:
|
||||||
|
- name: ara-api
|
||||||
|
image: quay.io/recordsansible/ara-api
|
||||||
|
env:
|
||||||
|
- name: ARA_BASE_DIR
|
||||||
|
value: /etc/ara
|
||||||
|
- name: ARA_SETTINGS
|
||||||
|
value: /etc/ara/settings.toml
|
||||||
|
- name: SECRETS_FOR_DYNACONF
|
||||||
|
value: /etc/ara/.secrets.toml
|
||||||
|
ports:
|
||||||
|
- containerPort: 8000
|
||||||
|
name: http
|
||||||
|
readinessProbe: &probe
|
||||||
|
httpGet:
|
||||||
|
port: 8000
|
||||||
|
path: /api/
|
||||||
|
httpHeaders:
|
||||||
|
- name: Host
|
||||||
|
value: ara.ansible.pyrocufflink.blue
|
||||||
|
failureThreshold: 3
|
||||||
|
periodSeconds: 60
|
||||||
|
successThreshold: 1
|
||||||
|
timeoutSeconds: 5
|
||||||
|
startupProbe:
|
||||||
|
<<: *probe
|
||||||
|
failureThreshold: 30
|
||||||
|
initialDelaySeconds: 1
|
||||||
|
periodSeconds: 1
|
||||||
|
timeoutSeconds: 1
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /etc/ara/settings.toml
|
||||||
|
name: config
|
||||||
|
subPath: settings.toml
|
||||||
|
readOnly: true
|
||||||
|
- mountPath: /etc/ara/.secrets.toml
|
||||||
|
name: secrets
|
||||||
|
subPath: .secrets.toml
|
||||||
|
readOnly: true
|
||||||
|
- mountPath: /tmp
|
||||||
|
name: tmp
|
||||||
|
subPath: tmp
|
||||||
|
securityContext:
|
||||||
|
runAsNonRoot: true
|
||||||
|
runAsUser: 7653
|
||||||
|
runAsGroup: 7653
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: ara
|
||||||
|
- name: secrets
|
||||||
|
secret:
|
||||||
|
secretName: ara
|
||||||
|
- name: tmp
|
||||||
|
emptyDir:
|
||||||
|
medium: Memory
|
|
@ -0,0 +1,38 @@
|
||||||
|
[default]
|
||||||
|
ALLOWED_HOSTS = [
|
||||||
|
'ara.ansible.pyrocufflink.blue',
|
||||||
|
]
|
||||||
|
LOG_LEVEL = 'INFO'
|
||||||
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
|
EXTERNAL_AUTH = true
|
||||||
|
READ_LOGIN_REQUIRED = false
|
||||||
|
WRITE_LOGIN_REQUIRED = false
|
||||||
|
|
||||||
|
DATABASE_ENGINE = 'django.db.backends.postgresql'
|
||||||
|
DATABASE_HOST = 'postgresql.pyrocufflink.blue'
|
||||||
|
DATABASE_NAME = 'ara'
|
||||||
|
DATABASE_USER = 'ara'
|
||||||
|
|
||||||
|
[default.DATABASE_OPTIONS]
|
||||||
|
sslmode = 'verify-full'
|
||||||
|
sslcert = '/run/secrets/ara/postgresql/tls.crt'
|
||||||
|
sslkey = '/run/secrets/ara/postgresql/tls.key'
|
||||||
|
sslrootcert = '/run/dch-ca/dch-root-ca.crt'
|
||||||
|
|
||||||
|
[default.LOGGING]
|
||||||
|
version = 1
|
||||||
|
disable_existing_loggers = false
|
||||||
|
|
||||||
|
[default.LOGGING.formatters.normal]
|
||||||
|
format = '%(levelname)s %(name)s: %(message)s'
|
||||||
|
|
||||||
|
[default.LOGGING.handlers.console]
|
||||||
|
class = 'logging.StreamHandler'
|
||||||
|
formatter = 'normal'
|
||||||
|
level = 'INFO'
|
||||||
|
|
||||||
|
[default.LOGGING.loggers.ara]
|
||||||
|
handlers = ['console']
|
||||||
|
level = 'INFO'
|
||||||
|
propagate = false
|
|
@ -0,0 +1,32 @@
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: ara
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: ara
|
||||||
|
app.kubernetes.io/component: ara
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: dch-ca
|
||||||
|
nginx.ingress.kubernetes.io/proxy-buffer-size: "8k"
|
||||||
|
nginx.ingress.kubernetes.io/auth-method: GET
|
||||||
|
nginx.ingress.kubernetes.io/auth-url: http://authelia.authelia.svc.cluster.local:9091/api/verify
|
||||||
|
nginx.ingress.kubernetes.io/auth-signin: https://auth.pyrocufflink.blue/?rm=$request_method
|
||||||
|
nginx.ingress.kubernetes.io/auth-snippet: |
|
||||||
|
proxy_set_header X-Forwarded-Method $request_method;
|
||||||
|
spec:
|
||||||
|
ingressClassName: nginx
|
||||||
|
tls:
|
||||||
|
- hosts:
|
||||||
|
- ara.ansible.pyrocufflink.blue
|
||||||
|
secretName: ara-cert
|
||||||
|
rules:
|
||||||
|
- host: ara.ansible.pyrocufflink.blue
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: ara
|
||||||
|
port:
|
||||||
|
name: http
|
|
@ -0,0 +1,58 @@
|
||||||
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
|
kind: Kustomization
|
||||||
|
|
||||||
|
labels:
|
||||||
|
- pairs:
|
||||||
|
app.kubernetes.io/instance: ansible
|
||||||
|
includeSelectors: true
|
||||||
|
includeTemplates: true
|
||||||
|
- pairs:
|
||||||
|
app.kubernetes.io/part-of: ansible
|
||||||
|
|
||||||
|
namespace: ansible
|
||||||
|
|
||||||
|
resources:
|
||||||
|
- ../dch-root-ca
|
||||||
|
- secrets.yaml
|
||||||
|
- namespace.yaml
|
||||||
|
- ara.yaml
|
||||||
|
- postgres-cert.yaml
|
||||||
|
- ingress.yaml
|
||||||
|
|
||||||
|
configMapGenerator:
|
||||||
|
- name: ara
|
||||||
|
files:
|
||||||
|
- ara/settings.toml
|
||||||
|
options:
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: ara
|
||||||
|
|
||||||
|
patches:
|
||||||
|
- patch: |-
|
||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: ara
|
||||||
|
spec:
|
||||||
|
template:
|
||||||
|
spec:
|
||||||
|
containers:
|
||||||
|
- name: ara-api
|
||||||
|
volumeMounts:
|
||||||
|
- mountPath: /run/dch-ca/dch-root-ca.crt
|
||||||
|
name: dch-root-ca
|
||||||
|
subPath: dch-root-ca.crt
|
||||||
|
readOnly: true
|
||||||
|
- mountPath: /run/secrets/ara/postgresql
|
||||||
|
name: postgresql-cert
|
||||||
|
readOnly: true
|
||||||
|
securityContext:
|
||||||
|
fsGroup: 7653
|
||||||
|
volumes:
|
||||||
|
- name: postgresql-cert
|
||||||
|
secret:
|
||||||
|
secretName: ara-postgres-cert
|
||||||
|
defaultMode: 0640
|
||||||
|
- name: dch-root-ca
|
||||||
|
configMap:
|
||||||
|
name: dch-root-ca
|
|
@ -0,0 +1,6 @@
|
||||||
|
apiVersion: v1
|
||||||
|
kind: Namespace
|
||||||
|
metadata:
|
||||||
|
name: ansible
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: ansible
|
|
@ -0,0 +1,12 @@
|
||||||
|
apiVersion: cert-manager.io/v1
|
||||||
|
kind: Certificate
|
||||||
|
metadata:
|
||||||
|
name: ara-postgres-cert
|
||||||
|
spec:
|
||||||
|
commonName: ara
|
||||||
|
privateKey:
|
||||||
|
algorithm: ECDSA
|
||||||
|
secretName: ara-postgres-cert
|
||||||
|
issuerRef:
|
||||||
|
name: postgresql-ca
|
||||||
|
kind: ClusterIssuer
|
|
@ -0,0 +1,19 @@
|
||||||
|
---
|
||||||
|
apiVersion: bitnami.com/v1alpha1
|
||||||
|
kind: SealedSecret
|
||||||
|
metadata:
|
||||||
|
name: ara
|
||||||
|
namespace: ansible
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: ara
|
||||||
|
app.kubernetes.io/component: ara
|
||||||
|
spec:
|
||||||
|
encryptedData:
|
||||||
|
.secrets.toml: AgAiObM2t8Cmr87pMRhZN4RBqb4soEdG0OJeAmaUCl//in2LihZyOHKu5RDeLBaPneoX5G/t5eQX7KkPCW7hffjBSngVbPMZ+U8Txb1IY3uFFHGAPnJBXwHo6FgRq5uKt3LQ6UmtWLoIF4ZB4K0f/g5BHR3N6FIah/x5pKrnU9lOltVgDFSEd7Ewgrj8AorASdE7ZxBAGuUPNktQZZ9MS0d2YiOhgfZiGHDnLZoqk0osDOZzKJX47yiYg5SR4NHoGzd7gfSvBtbrU4SIQCUGZJYtOKeUGaNtCgKnLe3oCphqV3izUY1JudVF8eN5MDgUH5vG2GcqDqMYTX2oRuk+rgRjiMJTkxQ/OZlbrXGxUocTR51EoM01vgjvvCsqaE3R5MhcKE7oOHrqTXzhDY6UzBPUu6QWrkWWMegBeIVCWA2ID3m8CPljyA0oZuClqVZpx/23cs3aHcyl2vye5ey3ca5QzLkkmKK7826H3przUYdwti9gMNp0sPszsDOTzfmN9iZD33a+WvEPfbf7+ZBXBAnoH06pLXeCGc43Q2S619xdHRw4caVGeczZAWYVjlnq8BUQGmHU2Ra5W6dzYM+i3vUimJRiuzeaG+APgY4KIdZNEjPguiwg93g9NtDWgap1h5rF3Yx4nEQelEN0pNAqT8CP67gW1Kp+wjNRNHkz45Ld3mJbMsvFqjZG5cCqk1s67mBNxhani0HBJM3vEV36wnDBzWwSmemuMUdjrG0zFwQHHeZwQe7oR+9XNz1DLPxvvp6KfEbHA3YMagQa2RYxN/C9APBBC+dmk6+TJn1n
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
name: ara
|
||||||
|
namespace: ansible
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: ara
|
||||||
|
app.kubernetes.io/component: ara
|
|
@ -5,6 +5,9 @@ access_control:
|
||||||
networks:
|
networks:
|
||||||
- 172.30.0.0/26
|
- 172.30.0.0/26
|
||||||
- 172.31.1.0/24
|
- 172.31.1.0/24
|
||||||
|
- name: cluster
|
||||||
|
networks:
|
||||||
|
- 10.149.0.0/16
|
||||||
rules:
|
rules:
|
||||||
- domain: paperless.pyrocufflink.blue
|
- domain: paperless.pyrocufflink.blue
|
||||||
policy: two_factor
|
policy: two_factor
|
||||||
|
@ -54,6 +57,16 @@ access_control:
|
||||||
resources:
|
resources:
|
||||||
- '^/submit/.*'
|
- '^/submit/.*'
|
||||||
policy: bypass
|
policy: bypass
|
||||||
|
- domain: ara.ansible.pyrocufflink.blue
|
||||||
|
networks:
|
||||||
|
- internal
|
||||||
|
- cluster
|
||||||
|
resources:
|
||||||
|
- '^/api/.*'
|
||||||
|
methods:
|
||||||
|
- POST
|
||||||
|
- PATCH
|
||||||
|
policy: bypass
|
||||||
|
|
||||||
authentication_backend:
|
authentication_backend:
|
||||||
ldap:
|
ldap:
|
||||||
|
|
Loading…
Reference in New Issue