review: setup awx server with ansible

master
Sven Ketelsen 4 years ago
parent 9acca552c1
commit 3042b8cacd

@ -43,3 +43,10 @@ IPFire
Prometheus (Grafana) Prometheus (Grafana)
docker exec -i df4d6b176f5e sh -c 'grafana-cli plugins install grafana-piechart-panel' docker exec -i df4d6b176f5e sh -c 'grafana-cli plugins install grafana-piechart-panel'
docker restart df4d6b176f5e docker restart df4d6b176f5e
AWX
-> /etc/kubernetes/k9s
wget https://github.com/derailed/k9s/releases/download/v0.24.14/k9s_Linux_x86_64.tar.gz
tar -xzf k9s_*.tar.gz -C .
ln -s /etc/kubernetes/k9s/k9s /usr/bin/k9s
kubectl taint nodes --all node-role.kubernetes.io/master-

@ -3,3 +3,5 @@
hetzner_server_labels: "stage={{ stage }} service=awx" hetzner_server_labels: "stage={{ stage }} service=awx"
hetzner_server_type: cpx31 hetzner_server_type: cpx31
traefik_enabled: false

@ -0,0 +1,20 @@
The MIT License (MIT)
Copyright (c) 2018 Jeff Geerling
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

@ -0,0 +1,188 @@
# Ansible Role: Kubernetes
[![CI](https://github.com/geerlingguy/ansible-role-kubernetes/workflows/CI/badge.svg?event=push)](https://github.com/geerlingguy/ansible-role-kubernetes/actions?query=workflow%3ACI)
An Ansible Role that installs [Kubernetes](https://kubernetes.io) on Linux.
## Requirements
Requires Docker or another [Container Runtime](https://kubernetes.io/docs/setup/production-environment/container-runtimes) ; recommended role for Docker installation: `geerlingguy.docker`.
## Role Variables
Available variables are listed below, along with default values (see `defaults/main.yml`):
kubernetes_packages:
- name: kubelet
state: present
- name: kubectl
state: present
- name: kubeadm
state: present
- name: kubernetes-cni
state: present
Kubernetes packages to be installed on the server. You can either provide a list of package names, or set `name` and `state` to have more control over whether the package is `present`, `absent`, `latest`, etc.
kubernetes_version: '1.20'
kubernetes_version_rhel_package: '1.20.4'
The minor version of Kubernetes to install. The plain `kubernetes_version` is used to pin an apt package version on Debian, and as the Kubernetes version passed into the `kubeadm init` command (see `kubernetes_version_kubeadm`). The `kubernetes_version_rhel_package` variable must be a specific Kubernetes release, and is used to pin the version on Red Hat / CentOS servers.
kubernetes_role: master
Whether the particular server will serve as a Kubernetes `master` (default) or `node`. The master will have `kubeadm init` run on it to intialize the entire K8s control plane, while `node`s will have `kubeadm join` run on them to join them to the `master`.
### Variables to configure kubeadm and kubelet with `kubeadm init` through a config file (recommended)
With this role, `kubeadm init` will be run with `--config <FILE>`.
kubernetes_kubeadm_kubelet_config_file_path: '/etc/kubernetes/kubeadm-kubelet-config.yaml'
Path for `<FILE>`. If the directory does not exist, this role will create it.
The following variables are parsed as options to <FILE>. To understand its syntax, see https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/kubelet-integration and https://kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-init/#config-file . The skeleton (`apiVersion`, `kind`) of the config file will be created by this role, so do not define them within the variables. (See `templates/kubeadm-kubelet-config.yaml`).
kubernetes_config_init_configuration:
localAPIEndpoint:
advertiseAddress: "{{ kubernetes_apiserver_advertise_address | default(ansible_default_ipv4.address, true) }}"
Defines the options under `kind: InitConfiguration`. Including `kubernetes_apiserver_advertise_address` here is for backward-compatibilty to older versions of this role, where `kubernetes_apiserver_advertise_address` was used with a command-line-option.
kubernetes_config_cluster_configuration:
networking:
podSubnet: "{{ kubernetes_pod_network.cidr }}"
kubernetesVersion: "{{ kubernetes_version_kubeadm }}"
Options under `kind: ClusterConfiguration`. Including `kubernetes_pod_network.cidr` and `kubernetes_version_kubeadm` here are for backward-compatibilty to older versions of this role, where they were used with command-line-options.
kubernetes_config_kubelet_configuration:
cgroupDriver: cgroupfs
Options to configure kubelet on any nodes in your cluster through the `kubeadm init` process. To get the syntax of this options see https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file and https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/kubelet-integration.
NOTE: This is the recommended way to do the kubelet-configuration. Most command-line-options are deprecated.
NOTE: The recommended cgroupDriver depends on your [Container Runtime](https://kubernetes.io/docs/setup/production-environment/container-runtimes). When using this role with containerd instead of docker, this value should be changed to `systemd`.
### Variables to configure kubeadm and kubelet through command-line-options
kubernetes_kubelet_extra_args: ""
kubernetes_kubelet_extra_args_config_file: /etc/default/kubelet
Extra args to pass to `kubelet` during startup. E.g. to allow `kubelet` to start up even if there is swap is enabled on your server, set this to: `"--fail-swap-on=false"`. Or to specify the node-ip advertised by `kubelet`, set this to `"--node-ip={{ ansible_host }}"`. *This is deprecated. Please use `kubernetes_config_kubelet_configuration` instead.*
kubernetes_kubeadm_init_extra_opts: ""
Extra args to pass to `kubeadm init` during K8s control plane initialization. E.g. to specify extra Subject Alternative Names for API server certificate, set this to: `"--apiserver-cert-extra-sans my-custom.host"`
kubernetes_join_command_extra_opts: ""
Extra args to pass to the generated `kubeadm join` command during K8s node initialization. E.g. to ignore certain preflight errors like swap being enabled, set this to: `--ignore-preflight-errors=Swap`
### Additional variables
kubernetes_allow_pods_on_master: true
Whether to remove the taint that denies pods from being deployed to the Kubernetes master. If you have a single-node cluster, this should definitely be `True`. Otherwise, set to `False` if you want a dedicated Kubernetes master which doesn't run any other pods.
kubernetes_enable_web_ui: false
kubernetes_web_ui_manifest_file: https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/recommended/kubernetes-dashboard.yaml
Whether to enable the Kubernetes web dashboard UI (only accessible on the master itself, or proxied), and the file containing the web dashboard UI manifest.
kubernetes_pod_network:
# Flannel CNI.
cni: 'flannel'
cidr: '10.244.0.0/16'
#
# Calico CNI.
# cni: 'calico'
# cidr: '192.168.0.0/16'
#
# Weave CNI.
# cni: 'weave'
# cidr: '192.168.0.0/16'
This role currently supports `flannel` (default), `calico` or `weave` for cluster pod networking. Choose only one for your cluster; converting between them is not done automatically and could result in broken networking; if you need to switch from one to another, it should be done outside of this role.
kubernetes_apiserver_advertise_address: ''
kubernetes_version_kubeadm: 'stable-{{ kubernetes_version }}'
kubernetes_ignore_preflight_errors: 'all'
Options passed to `kubeadm init` when initializing the Kubernetes master. The `kubernetes_apiserver_advertise_address` defaults to `ansible_default_ipv4.address` if it's left empty.
kubernetes_apt_release_channel: main
kubernetes_apt_repository: "deb http://apt.kubernetes.io/ kubernetes-xenial {{ kubernetes_apt_release_channel }}"
kubernetes_apt_ignore_key_error: false
Apt repository options for Kubernetes installation.
kubernetes_yum_arch: x86_64
kubernetes_yum_base_url: "https://packages.cloud.google.com/yum/repos/kubernetes-el7-{{ kubernetes_yum_arch }}"
kubernetes_yum_gpg_key:
- https://packages.cloud.google.com/yum/doc/yum-key.gpg
- https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
Yum repository options for Kubernetes installation. You can change `kubernete_yum_gpg_key` to a different url if you are behind a firewall or provide a trustworthy mirror. Usually in combination with changing `kubernetes_yum_base_url` as well.
kubernetes_flannel_manifest_file_rbac: https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml
kubernetes_flannel_manifest_file: https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
Flannel manifest files to apply to the Kubernetes cluster to enable networking. You can copy your own files to your server and apply them instead, if you need to customize the Flannel networking configuration.
## Dependencies
None.
## Example Playbooks
### Single node (master-only) cluster
```yaml
- hosts: all
vars:
kubernetes_allow_pods_on_master: true
roles:
- geerlingguy.docker
- geerlingguy.kubernetes
```
### Two or more nodes (single master) cluster
Master inventory vars:
```yaml
kubernetes_role: "master"
```
Node(s) inventory vars:
```yaml
kubernetes_role: "node"
```
Playbook:
```yaml
- hosts: all
vars:
kubernetes_allow_pods_on_master: true
roles:
- geerlingguy.docker
- geerlingguy.kubernetes
```
Then, log into the Kubernetes master, and run `kubectl get nodes` as root, and you should see a list of all the servers.
## License
MIT / BSD
## Author Information
This role was created in 2018 by [Jeff Geerling](https://www.jeffgeerling.com/), author of [Ansible for DevOps](https://www.ansiblefordevops.com/).

@ -0,0 +1,71 @@
---
kubernetes_packages:
- name: kubelet
state: present
- name: kubectl
state: present
- name: kubeadm
state: present
- name: kubernetes-cni
state: present
kubernetes_version: '1.20'
kubernetes_version_rhel_package: '1.20.4'
kubernetes_role: master
# This is deprecated. Please use kubernetes_config_kubelet_configuration instead.
kubernetes_kubelet_extra_args: ""
kubernetes_kubeadm_init_extra_opts: ""
kubernetes_join_command_extra_opts: ""
kubernetes_allow_pods_on_master: true
kubernetes_enable_web_ui: true
# https://github.com/kubernetes/dashboard/blob/master/docs/user/installation.md
kubernetes_web_ui_manifest_file: https://raw.githubusercontent.com/kubernetes/dashboard/v2.2.0/aio/deploy/recommended.yaml
kubernetes_pod_network:
# Flannel CNI.
cni: 'flannel'
cidr: '10.244.0.0/16'
# Calico CNI.
# cni: 'calico'
# cidr: '192.168.0.0/16'
kubernetes_kubeadm_kubelet_config_file_path: '/etc/kubernetes/kubeadm-kubelet-config.yaml'
kubernetes_config_kubelet_configuration:
cgroupDriver: "cgroupfs"
kubernetes_config_init_configuration:
localAPIEndpoint:
advertiseAddress: "{{ kubernetes_apiserver_advertise_address | default(ansible_default_ipv4.address, true) }}"
# if you use the next lines, remove the command line argument below
# nodeRegistration:
# ignorePreflightErrors:
# - all
kubernetes_config_cluster_configuration:
networking:
podSubnet: "{{ kubernetes_pod_network.cidr }}"
kubernetesVersion: "{{ kubernetes_version_kubeadm }}"
kubernetes_apiserver_advertise_address: ''
kubernetes_version_kubeadm: 'stable-{{ kubernetes_version }}'
kubernetes_ignore_preflight_errors: 'all'
kubernetes_apt_release_channel: main
# Note that xenial repo is used for all Debian derivatives at this time.
kubernetes_apt_repository: "deb http://apt.kubernetes.io/ kubernetes-xenial {{ kubernetes_apt_release_channel }}"
kubernetes_apt_ignore_key_error: false
kubernetes_yum_arch: '$basearch'
kubernetes_yum_base_url: "https://packages.cloud.google.com/yum/repos/kubernetes-el7-{{ kubernetes_yum_arch }}"
kubernetes_yum_gpg_key:
- https://packages.cloud.google.com/yum/doc/yum-key.gpg
- https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
# Flannel config files.
kubernetes_flannel_manifest_file_rbac: https://raw.githubusercontent.com/coreos/flannel/master/Documentation/k8s-manifests/kube-flannel-rbac.yml
kubernetes_flannel_manifest_file: https://raw.githubusercontent.com/coreos/flannel/master/Documentation/kube-flannel.yml
# Calico config files
kubernetes_calico_manifest_file: https://docs.projectcalico.org/v3.10/manifests/calico.yaml

@ -0,0 +1,3 @@
---
- name: restart kubelet
service: name=kubelet state=restarted

@ -0,0 +1,35 @@
---
dependencies: []
galaxy_info:
role_name: kubernetes
author: geerlingguy
description: Kubernetes for Linux.
company: "Midwestern Mac, LLC"
license: "license (BSD, MIT)"
min_ansible_version: 2.4
platforms:
- name: EL
versions:
- 7
- 8
- name: Debian
versions:
- stretch
- buster
- name: Ubuntu
versions:
- xenial
- bionic
- focal
galaxy_tags:
- system
- containers
- docker
- rkt
- orchestration
- kubernetes
- k8s
- paas
- saas
- hosting

@ -0,0 +1,50 @@
---
- name: Converge
hosts: all
become: true
vars:
kubernetes_pod_network:
cni: 'calico'
cidr: '192.168.0.0/16'
# Allow swap in test environments (hard to control in some Docker envs).
kubernetes_kubelet_extra_args: "--fail-swap-on=false --cgroup-driver=cgroupfs"
docker_install_compose: false
pre_tasks:
- name: Update apt cache.
apt: update_cache=true cache_valid_time=600
when: ansible_os_family == 'Debian'
- name: Ensure test dependencies are installed (RedHat).
package: name=iproute state=present
when: ansible_os_family == 'RedHat'
- name: Ensure test dependencies are installed (Debian).
package: name=iproute2 state=present
when: ansible_os_family == 'Debian'
- name: Gather facts.
action: setup
roles:
- role: geerlingguy.docker
- role: geerlingguy.kubernetes
post_tasks:
- name: Get cluster info.
command: kubectl cluster-info
changed_when: false
register: kubernetes_info
- name: Print cluster info.
debug: var=kubernetes_info.stdout
- name: Get all running pods.
command: kubectl get pods --all-namespaces
changed_when: false
register: kubernetes_pods
- name: Print list of running pods.
debug: var=kubernetes_pods.stdout

@ -0,0 +1,46 @@
---
- name: Converge
hosts: all
become: true
vars:
# Allow swap in test environments (hard to control in some Docker envs).
kubernetes_kubelet_extra_args: "--fail-swap-on=false --cgroup-driver=cgroupfs"
docker_install_compose: false
pre_tasks:
- name: Update apt cache.
apt: update_cache=true cache_valid_time=600
when: ansible_os_family == 'Debian'
- name: Ensure test dependencies are installed (RedHat).
package: name=iproute state=present
when: ansible_os_family == 'RedHat'
- name: Ensure test dependencies are installed (Debian).
package: name=iproute2 state=present
when: ansible_os_family == 'Debian'
- name: Gather facts.
action: setup
roles:
- role: geerlingguy.docker
- role: geerlingguy.kubernetes
post_tasks:
- name: Get cluster info.
command: kubectl cluster-info
changed_when: false
register: kubernetes_info
- name: Print cluster info.
debug: var=kubernetes_info.stdout
- name: Get all running pods.
command: kubectl get pods --all-namespaces
changed_when: false
register: kubernetes_pods
- name: Print list of running pods.
debug: var=kubernetes_pods.stdout

@ -0,0 +1,18 @@
---
dependency:
name: galaxy
driver:
name: docker
platforms:
- name: instance
image: "geerlingguy/docker-${MOLECULE_DISTRO:-centos7}-ansible:latest"
command: ${MOLECULE_DOCKER_COMMAND:-""}
volumes:
- /sys/fs/cgroup:/sys/fs/cgroup:ro
- /var/lib/docker
privileged: true
pre_build_image: true
provisioner:
name: ansible
playbooks:
converge: ${MOLECULE_PLAYBOOK:-converge.yml}

@ -0,0 +1,42 @@
---
# ---- DEPRECATED ----------------
#
# Most of the kubernetes_kubelet_extra_args are deprecated. See https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet for details.
# Use the kubernetes_kubelet_config variable instead, which will be used to create the kubelet config file.
- name: Check for existence of kubelet environment file. (deprecated)
stat:
path: '{{ kubelet_environment_file_path }}'
register: kubelet_environment_file
- name: Set facts for KUBELET_EXTRA_ARGS task if environment file exists. (deprecated)
set_fact:
kubelet_args_path: '{{ kubelet_environment_file_path }}'
kubelet_args_line: "{{ 'KUBELET_EXTRA_ARGS=' + kubernetes_kubelet_extra_args }}"
kubelet_args_regexp: '^KUBELET_EXTRA_ARGS='
when: kubelet_environment_file.stat.exists
- name: Set facts for KUBELET_EXTRA_ARGS task if environment file doesn't exist. (deprecated)
set_fact:
kubelet_args_path: '/etc/systemd/system/kubelet.service.d/10-kubeadm.conf'
kubelet_args_line: "{{ 'Environment=\"KUBELET_EXTRA_ARGS=' + kubernetes_kubelet_extra_args + '\"' }}"
kubelet_args_regexp: '^Environment="KUBELET_EXTRA_ARGS='
when: not kubelet_environment_file.stat.exists
- name: Configure KUBELET_EXTRA_ARGS. (deprecated)
lineinfile:
path: '{{ kubelet_args_path }}'
line: '{{ kubelet_args_line }}'
regexp: '{{ kubelet_args_regexp }}'
state: present
mode: 0644
register: kubelet_extra_args
when: kubernetes_kubelet_extra_args|length > 0
- name: Reload systemd unit if args were changed. (deprecated)
systemd:
state: restarted
daemon_reload: true
name: kubelet
when: kubelet_extra_args is changed

@ -0,0 +1,59 @@
---
- name: Include OS-specific variables.
include_vars: "{{ ansible_os_family }}.yml"
- include_tasks: setup-RedHat.yml
when: ansible_os_family == 'RedHat'
- include_tasks: setup-Debian.yml
when: ansible_os_family == 'Debian'
- name: Ensure dependencies are installed.
package: name=curl state=present
- name: Install Kubernetes packages.
package:
name: "{{ item.name | default(item) }}"
state: "{{ item.state | default('present') }}"
notify: restart kubelet
with_items: "{{ kubernetes_packages }}"
- include_tasks: sysctl-setup.yml
- include_tasks: kubelet-setup.yml # deprecated
when: kubernetes_kubelet_extra_args|length > 0
- name: Ensure kubelet is started and enabled at boot.
service:
name: kubelet
state: started
enabled: true
- name: Check if Kubernetes has already been initialized.
stat:
path: /etc/kubernetes/admin.conf
register: kubernetes_init_stat
# Set up master.
- include_tasks: master-setup.yml
when: kubernetes_role == 'master'
# Set up nodes.
- name: Get the kubeadm join command from the Kubernetes master.
command: kubeadm token create --print-join-command
changed_when: false
when: kubernetes_role == 'master'
register: kubernetes_join_command_result
- name: Set the kubeadm join command globally.
set_fact:
kubernetes_join_command: >
{{ kubernetes_join_command_result.stdout }}
{{ kubernetes_join_command_extra_opts }}
when: kubernetes_join_command_result.stdout is defined
delegate_to: "{{ item }}"
delegate_facts: true
with_items: "{{ groups['all'] }}"
- include_tasks: node-setup.yml
when: kubernetes_role == 'node'

@ -0,0 +1,98 @@
---
- name: Create the directory for the kubernetes_config_file
file:
path: "{{ kubernetes_kubeadm_kubelet_config_file_path | dirname }}"
state: directory
- name: Deploy the config-file for kubeadm and kubelet
template:
src: "kubeadm-kubelet-config.j2"
dest: "{{ kubernetes_kubeadm_kubelet_config_file_path }}"
- name: Initialize Kubernetes master with kubeadm init
command: >
kubeadm init
--config {{ kubernetes_kubeadm_kubelet_config_file_path }}
{{ kubernetes_kubeadm_init_extra_opts }}
register: kubeadmin_init
when: (not kubernetes_init_stat.stat.exists) and (kubernetes_ignore_preflight_errors is not defined)
- name: Initialize Kubernetes master with kubeadm init and ignore_preflight_errors
command: >
kubeadm init
--config {{ kubernetes_kubeadm_kubelet_config_file_path }}
--ignore-preflight-errors={{ kubernetes_ignore_preflight_errors }}
{{ kubernetes_kubeadm_init_extra_opts }}
register: kubeadmin_init
when: (not kubernetes_init_stat.stat.exists) and (kubernetes_ignore_preflight_errors is defined)
- name: Print the init output to screen.
debug:
var: kubeadmin_init.stdout
verbosity: 2
when: not kubernetes_init_stat.stat.exists
- name: Ensure .kube directory exists.
file:
path: ~/.kube
state: directory
mode: 0755
- name: Symlink the kubectl admin.conf to ~/.kube/conf.
file:
src: /etc/kubernetes/admin.conf
dest: ~/.kube/config
state: link
mode: 0644
- name: Configure Flannel networking.
command: "{{ item }}"
with_items:
- kubectl apply -f {{ kubernetes_flannel_manifest_file_rbac }}
- kubectl apply -f {{ kubernetes_flannel_manifest_file }}
register: flannel_result
changed_when: "'created' in flannel_result.stdout"
when: kubernetes_pod_network.cni == 'flannel'
- name: Configure Calico networking.
command: "{{ item }}"
with_items:
- kubectl apply -f {{ kubernetes_calico_manifest_file }}
register: calico_result
changed_when: "'created' in calico_result.stdout"
when: kubernetes_pod_network.cni == 'calico'
- name: Get Kubernetes version for Weave installation.
shell: kubectl version | base64 | tr -d '\n'
changed_when: false
register: kubectl_version
when: kubernetes_pod_network.cni == 'weave'
- name: Configure Weave networking.
command: "{{ item }}"
with_items:
- "kubectl apply -f https://cloud.weave.works/k8s/net?k8s-version={{ kubectl_version.stdout_lines[0] }}"
register: weave_result
changed_when: "'created' in weave_result.stdout"
when: kubernetes_pod_network.cni == 'weave'
# TODO: Check if taint exists with something like `kubectl describe nodes`
# instead of using kubernetes_init_stat.stat.exists check.
- name: Allow pods on master node (if configured).
command: "kubectl taint nodes --all node-role.kubernetes.io/master-"
when:
- kubernetes_allow_pods_on_master | bool
- not kubernetes_init_stat.stat.exists
- name: Check if Kubernetes Dashboard UI service already exists.
shell: kubectl get services --namespace kubernetes-dashboard | grep -q kubernetes-dashboard
changed_when: false
failed_when: false
register: kubernetes_dashboard_service
when: kubernetes_enable_web_ui | bool
- name: Enable the Kubernetes Web Dashboard UI (if configured).
command: "kubectl create -f {{ kubernetes_web_ui_manifest_file }}"
when:
- kubernetes_enable_web_ui | bool
- kubernetes_dashboard_service.rc != 0

@ -0,0 +1,6 @@
---
- name: Join node to Kubernetes master
shell: >
{{ kubernetes_join_command }}
creates=/etc/kubernetes/kubelet.conf
tags: ['skip_ansible_lint']

@ -0,0 +1,26 @@
---
- name: Ensure dependencies are installed.
apt:
name:
- apt-transport-https
- ca-certificates
state: present
- name: Add Kubernetes apt key.
apt_key:
url: https://packages.cloud.google.com/apt/doc/apt-key.gpg
state: present
register: add_repository_key
ignore_errors: "{{ kubernetes_apt_ignore_key_error }}"
- name: Add Kubernetes repository.
apt_repository:
repo: "{{ kubernetes_apt_repository }}"
state: present
update_cache: true
- name: Add Kubernetes apt preferences file to pin a version.
template:
src: apt-preferences-kubernetes.j2
dest: /etc/apt/preferences.d/kubernetes
mode: 0644

@ -0,0 +1,23 @@
---
- name: Ensure Kubernetes repository exists.
yum_repository:
name: kubernetes
description: Kubernetes
enabled: true
gpgcheck: true
repo_gpgcheck: true
baseurl: "{{ kubernetes_yum_base_url }}"
gpgkey: "{{ kubernetes_yum_gpg_key }}"
- name: Add Kubernetes GPG keys.
rpm_key:
key: "{{ item }}"
state: present
register: kubernetes_rpm_key
with_items: "{{ kubernetes_yum_gpg_key }}"
- name: Make cache if Kubernetes GPG key changed.
command: "yum -q makecache -y --disablerepo='*' --enablerepo='kubernetes'"
when: kubernetes_rpm_key is changed
args:
warn: false

@ -0,0 +1,21 @@
---
- name: Ensure procps is installed.
package:
name: "{{ procps_package }}"
state: present
when: >
ansible_distribution != 'Debian'
or ansible_distribution_major_version | int < 10
# See: https://kubernetes.io/docs/setup/production-environment/tools/kubeadm/install-kubeadm/#letting-iptables-see-bridged-traffic
- name: Let iptables see bridged traffic.
sysctl:
name: "{{ item }}"
value: '1'
state: present
loop:
- net.bridge.bridge-nf-call-iptables
- net.bridge.bridge-nf-call-ip6tables
when: >
ansible_distribution != 'Debian'
or ansible_distribution_major_version | int < 10

@ -0,0 +1,11 @@
Package: kubectl
Pin: version {{ kubernetes_version }}.*
Pin-Priority: 1000
Package: kubeadm
Pin: version {{ kubernetes_version }}.*
Pin-Priority: 1000
Package: kubelet
Pin: version {{ kubernetes_version }}.*
Pin-Priority: 1000

@ -0,0 +1,14 @@
---
apiVersion: kubeadm.k8s.io/v1beta2
kind: InitConfiguration
{{ kubernetes_config_init_configuration | to_nice_yaml }}
---
kind: ClusterConfiguration
apiVersion: kubeadm.k8s.io/v1beta2
{{ kubernetes_config_cluster_configuration | to_nice_yaml }}
---
{% if kubernetes_config_kubelet_configuration|length > 0 %}
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
{{ kubernetes_config_kubelet_configuration | to_nice_yaml }}
{% endif %}

@ -0,0 +1,3 @@
---
procps_package: procps
kubelet_environment_file_path: /etc/default/kubelet

@ -0,0 +1,12 @@
---
procps_package: procps-ng
kubelet_environment_file_path: /etc/sysconfig/kubelet
kubernetes_packages:
- name: kubelet-{{ kubernetes_version_rhel_package }}-0
state: present
- name: kubectl-{{ kubernetes_version_rhel_package }}-0
state: present
- name: kubeadm-{{ kubernetes_version_rhel_package }}-0
state: present
- name: kubernetes-cni
state: present

@ -1,18 +1,25 @@
--- ---
awx_kubernetes_version: "1.20"
awx_operator_version: "0.12.0" awx_operator_version: "0.12.0"
awx_operator_url: "https://raw.githubusercontent.com/ansible/awx-operator/{{ awx_operator_version }}/deploy/awx-operator.yaml" awx_operator_url: "https://raw.githubusercontent.com/ansible/awx-operator/{{ awx_operator_version }}/deploy/awx-operator.yaml"
kubernetes_awx_namespace: "awx-test" kubernetes_awx_namespace: "awx-test"
kubernetes_awx_postgres_volume_size: "50Gi" kubernetes_awx_postgres_volume_size: "50Gi"
kubernetes_awx_postgres_volume_accessMode: "ReadWriteOnce" kubernetes_awx_postgres_volume_accessMode: "ReadWriteOnce"
kubernetes_awx_postgres_volume_path: "/mnt/data/postgres" kubernetes_awx_postgres_volume_path: "/mnt/{{ kubernetes_awx_namespace }}/data/postgres"
kubernetes_awx_postgres_pvc_size: "50Gi" kubernetes_awx_postgres_pvc_size: "50Gi"
kubernetes_awx_postgres_pvc_accessMode: "ReadWriteOnce" kubernetes_awx_postgres_pvc_accessMode: "ReadWriteOnce"
kubernetes_awx_project_volume_size: "10Gi" kubernetes_awx_project_volume_size: "10Gi"
kubernetes_awx_project_volume_accessMode: "ReadWriteOnce" kubernetes_awx_project_volume_accessMode: "ReadWriteOnce"
kubernetes_awx_project_volume_path: "/mnt/data/project" kubernetes_awx_project_volume_path: "/mnt/{{ kubernetes_awx_namespace }}/data/project"
kubernetes_awx_project_pvc_size: "10Gi" kubernetes_awx_project_pvc_size: "10Gi"
kubernetes_awx_project_pvc_accessMode: "ReadWriteOnce" kubernetes_awx_project_pvc_accessMode: "ReadWriteOnce"
kubernetes_awx_service_port: "80" kubernetes_awx_service_port: "80"
kubernetes_awx_service_targetPort: "80" kubernetes_awx_service_targetPort: "80"
awx_admin_username: "awx-admin"
awx_admin_password: "awx-admin" awx_admin_password: "awx-admin"

@ -1,7 +1,6 @@
--- ---
- set_fact: - set_fact:
found_credential_id: "" found_credential_id: ""
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -15,7 +14,6 @@
validate_certs: false validate_certs: false
force_basic_auth: yes force_basic_auth: yes
status_code: 200 status_code: 200
no_log: true
register: awx_job_template_info register: awx_job_template_info
when: (awx_job_template_id | default("") | length > 0) when: (awx_job_template_id | default("") | length > 0)
tags: tags:
@ -31,7 +29,6 @@
(item.results | json_query(query) | length > 0) (item.results | json_query(query) | length > 0)
loop: loop:
- "{{ awx_job_template_info['content'] }}" - "{{ awx_job_template_info['content'] }}"
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -53,7 +50,6 @@
force_basic_auth: true force_basic_auth: true
validate_certs: false validate_certs: false
status_code: 204 status_code: 204
no_log: true
tags: tags:
- awx_communication - awx_communication
when: > when: >

@ -11,7 +11,6 @@
validate_certs: false validate_certs: false
force_basic_auth: yes force_basic_auth: yes
status_code: 200 status_code: 200
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -30,7 +29,6 @@
ansible_awx_user_id: "{{ awx_type_id }}" ansible_awx_user_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -51,7 +49,6 @@
force_basic_auth: true force_basic_auth: true
validate_certs: false validate_certs: false
status_code: 200, 201 status_code: 200, 201
no_log: true
when: (ansible_awx_user_id is not defined) and (ansible_awx_user_id | length > 0) when: (ansible_awx_user_id is not defined) and (ansible_awx_user_id | length > 0)
tags: tags:
- awx_communication - awx_communication
@ -75,7 +72,6 @@
(ansible_awx_user_id is not defined) and (ansible_awx_user_id is not defined) and
(awx_type_id is defined) and (awx_type_id is defined) and
(awx_type_id | length > 0) (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -94,7 +90,6 @@
awx_credential_type_machine_id: "{{ awx_type_id }}" awx_credential_type_machine_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -113,7 +108,6 @@
awx_credential_hetzner_ansible_id: "{{ awx_type_id }}" awx_credential_hetzner_ansible_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -139,7 +133,6 @@
force_basic_auth: true force_basic_auth: true
validate_certs: false validate_certs: false
status_code: 200, 201 status_code: 200, 201
no_log: true
tags: tags:
- awx_communication - awx_communication
when: > when: >
@ -168,7 +161,6 @@
(awx_credential_hetzner_ansible_id is not defined) and (awx_credential_hetzner_ansible_id is not defined) and
(awx_type_id is defined) and (awx_type_id is defined) and
(awx_type_id | length > 0) (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -187,7 +179,6 @@
awx_credential_type_vault_id: "{{ awx_type_id }}" awx_credential_type_vault_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -206,7 +197,6 @@
awx_credential_hetzner_ansible_vault_id: "{{ awx_type_id }}" awx_credential_hetzner_ansible_vault_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -231,7 +221,6 @@
force_basic_auth: true force_basic_auth: true
validate_certs: false validate_certs: false
status_code: 200, 201 status_code: 200, 201
no_log: true
tags: tags:
- awx_communication - awx_communication
when: > when: >
@ -260,7 +249,6 @@
(awx_credential_hetzner_ansible_vault_id is not defined) and (awx_credential_hetzner_ansible_vault_id is not defined) and
(awx_type_id is defined) and (awx_type_id is defined) and
(awx_type_id | length > 0) (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -279,7 +267,6 @@
awx_credential_type_container_registry_id: "{{ awx_type_id }}" awx_credential_type_container_registry_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -298,7 +285,6 @@
awx_credential_docker_registry_id: "{{ awx_type_id }}" awx_credential_docker_registry_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -325,7 +311,6 @@
force_basic_auth: true force_basic_auth: true
validate_certs: false validate_certs: false
status_code: 200, 201 status_code: 200, 201
no_log: true
tags: tags:
- awx_communication - awx_communication
when: > when: >
@ -354,7 +339,6 @@
(awx_credential_docker_registry_id is not defined) and (awx_credential_docker_registry_id is not defined) and
(awx_type_id is defined) and (awx_type_id is defined) and
(awx_type_id | length > 0) (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -373,7 +357,6 @@
awx_ee_hetzner_ansible_id: "{{ awx_type_id }}" awx_ee_hetzner_ansible_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -397,7 +380,6 @@
force_basic_auth: true force_basic_auth: true
validate_certs: false validate_certs: false
status_code: 200, 201 status_code: 200, 201
no_log: true
tags: tags:
- awx_communication - awx_communication
when: > when: >
@ -424,7 +406,6 @@
(awx_ee_hetzner_ansible_id is not defined) and (awx_ee_hetzner_ansible_id is not defined) and
(awx_type_id is defined) and (awx_type_id is defined) and
(awx_type_id | length > 0) (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -443,7 +424,6 @@
awx_localhost_inventory_id: "{{ awx_type_id }}" awx_localhost_inventory_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -464,7 +444,6 @@
force_basic_auth: true force_basic_auth: true
validate_certs: false validate_certs: false
status_code: 200, 201 status_code: 200, 201
no_log: true
tags: tags:
- awx_communication - awx_communication
when: (awx_localhost_inventory_id is not defined) when: (awx_localhost_inventory_id is not defined)
@ -488,12 +467,11 @@
(awx_localhost_inventory_id is not defined) and (awx_localhost_inventory_id is not defined) and
(awx_type_id is defined) and (awx_type_id is defined) and
(awx_type_id | length > 0) (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
- name: "Tar hetzner-ansible repository" - name: "Tar hetzner-ansible repository"
shell: cd {{ playbook_dir }} && tar --exclude-vcs -zcvf /tmp/hetzner-ansible.tar.gz . shell: cd {{ playbook_dir }} && git archive --format tar.gz -o /tmp/hetzner-ansible.tar.gz HEAD
delegate_to: localhost delegate_to: localhost
become: false become: false
tags: tags:
@ -512,7 +490,7 @@
state: directory state: directory
owner: root owner: root
group: root group: root
mode: '0665' mode: '0555'
tags: tags:
- awx_communication - awx_communication
@ -545,7 +523,6 @@
awx_hetzner_ansible_project_id: "{{ awx_type_id }}" awx_hetzner_ansible_project_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -568,7 +545,6 @@
force_basic_auth: true force_basic_auth: true
validate_certs: false validate_certs: false
status_code: 200, 201 status_code: 200, 201
no_log: true
tags: tags:
- awx_communication - awx_communication
when: > when: >
@ -594,7 +570,6 @@
(awx_hetzner_ansible_project_id is not defined) and (awx_hetzner_ansible_project_id is not defined) and
(awx_type_id is defined) and (awx_type_id is defined) and
(awx_type_id | length > 0) (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication

@ -20,7 +20,6 @@
awx_job_template_id: "{{ awx_type_id }}" awx_job_template_id: "{{ awx_type_id }}"
awx_type_id: "" awx_type_id: ""
when: (awx_type_id is defined) and (awx_type_id | length > 0) when: (awx_type_id is defined) and (awx_type_id | length > 0)
no_log: true
tags: tags:
- awx_communication - awx_communication
@ -46,7 +45,6 @@
force_basic_auth: true force_basic_auth: true
validate_certs: false validate_certs: false
status_code: 200, 201 status_code: 200, 201
no_log: true
tags: tags:
- awx_communication - awx_communication
when: > when: >
@ -72,7 +70,7 @@
when: > when: >
(awx_type_id is defined) and (awx_type_id is defined) and
(awx_type_id | length > 0) (awx_type_id | length > 0)
no_log: true # no_log: true
tags: tags:
- awx_communication - awx_communication

@ -1,5 +1,10 @@
--- ---
### tags:
### kube_apply
### kube_install
### awx_communication
- name: "Install pip3 for {{ service_name }}" - name: "Install pip3 for {{ service_name }}"
apt: apt:
name: python3-pip name: python3-pip
@ -18,8 +23,9 @@
- name: "Install and setup kubernetes (single node, master-only cluster) for {{ service_name }}" - name: "Install and setup kubernetes (single node, master-only cluster) for {{ service_name }}"
include_role: include_role:
name: geerlingguy.kubernetes name: ansible-role-kubernetes
vars: vars:
kubernetes_version: "{{ awx_kubernetes_version }}"
kubernetes_allow_pods_on_master: true kubernetes_allow_pods_on_master: true
tags: tags:
- kube_install - kube_install
@ -33,7 +39,7 @@
- kube_apply - kube_apply
- name: "Apply awx {{ awx_operator_version }} to kubernetes {{ service_name }}" - name: "Apply awx {{ awx_operator_version }} to kubernetes {{ service_name }}"
k8s: kubernetes.core.k8s:
state: present state: present
src: /tmp/awx-operator.yaml src: /tmp/awx-operator.yaml
namespace: default namespace: default
@ -65,7 +71,7 @@
- kube_apply - kube_apply
- name: "Create a awx k8s namespace for {{ service_name }}" - name: "Create a awx k8s namespace for {{ service_name }}"
k8s: kubernetes.core.k8s:
name: "{{ kubernetes_awx_namespace }}" name: "{{ kubernetes_awx_namespace }}"
api_version: v1 api_version: v1
kind: Namespace kind: Namespace
@ -74,7 +80,7 @@
- kube_apply - kube_apply
- name: "Apply awx deployment for {{ service_name }}" - name: "Apply awx deployment for {{ service_name }}"
k8s: kubernetes.core.k8s:
state: present state: present
src: /tmp/awx-deployment.yml src: /tmp/awx-deployment.yml
namespace: "{{ kubernetes_awx_namespace }}" namespace: "{{ kubernetes_awx_namespace }}"
@ -106,7 +112,7 @@
- kube_apply - kube_apply
- name: "Search for all pods labeled app.kubernetes.io/name=awx {{ service_name }}" - name: "Search for all pods labeled app.kubernetes.io/name=awx {{ service_name }}"
k8s_info: kubernetes.core.k8s_info:
kind: Pod kind: Pod
namespace: "{{ kubernetes_awx_namespace }}" namespace: "{{ kubernetes_awx_namespace }}"
label_selectors: label_selectors:
@ -127,7 +133,7 @@
- include_tasks: awx-configurator.yml - include_tasks: awx-configurator.yml
vars: vars:
awx_base_url: "http://{{ stage_server_ip }}" awx_base_url: "http://{{ stage_server_ip }}"
awx_rest_api_access_user: "admin" awx_rest_api_access_user: "{{ awx_admin_username }}"
awx_rest_api_access_pw: "{{ awx_admin_password }}" awx_rest_api_access_pw: "{{ awx_admin_password }}"
awx_project_path: "{{ kubernetes_awx_project_volume_path }}" awx_project_path: "{{ kubernetes_awx_project_volume_path }}"
tags: tags:

@ -67,6 +67,7 @@ metadata:
name: awx name: awx
namespace: {{ kubernetes_awx_namespace }} namespace: {{ kubernetes_awx_namespace }}
spec: spec:
admin_user: {{ awx_admin_username }}
projects_persistence: true projects_persistence: true
projects_existing_claim: awx-project-claim-0 projects_existing_claim: awx-project-claim-0
projects_storage_access_mode: {{ kubernetes_awx_project_pvc_accessMode }} projects_storage_access_mode: {{ kubernetes_awx_project_pvc_accessMode }}

@ -65,7 +65,6 @@
with_items: with_items:
- 'awx' - 'awx'
- 'default' - 'default'
- 'docker'
- 'kibana' - 'kibana'
- 'monitoring' - 'monitoring'
loop_control: loop_control:

@ -22,6 +22,7 @@
become: false become: false
tags: tags:
- update_networks - update_networks
- awx_communication
- name: "Set current server infos as fact: hetzner_server_infos_json" - name: "Set current server infos as fact: hetzner_server_infos_json"
set_fact: set_fact:
@ -30,6 +31,7 @@
become: false become: false
tags: tags:
- update_networks - update_networks
- awx_communication
- name: "Read ip address for {{ inventory_hostname }}" - name: "Read ip address for {{ inventory_hostname }}"
set_fact: set_fact:
@ -40,6 +42,7 @@
become: false become: false
tags: tags:
- update_networks - update_networks
- awx_communication
- name: Print the gathered infos - name: Print the gathered infos
debug: debug:
@ -48,6 +51,7 @@
become: false become: false
tags: tags:
- update_networks - update_networks
- awx_communication
roles: roles:
- role: postfix - role: postfix

@ -25,9 +25,6 @@ dev-mail-01
[prometheus] [prometheus]
dev-prometheus-01 dev-prometheus-01
[awx]
dev-awx-02
[stage_dev:children] [stage_dev:children]
awx awx
connect connect
@ -37,7 +34,6 @@ iam
keycloak keycloak
postfix postfix
prometheus prometheus
awx
[all:children] [all:children]
stage_dev stage_dev

Loading…
Cancel
Save