diff --git a/.ansible-lint b/.ansible-lint new file mode 100644 index 0000000..9337aa9 --- /dev/null +++ b/.ansible-lint @@ -0,0 +1,2 @@ +skip_list: + - package-latest diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d33f855 --- /dev/null +++ b/.gitignore @@ -0,0 +1,37 @@ +__pycache__/ +*.py[cod] +*$py.class +dist/ +lib/ +*.egg-info/ +.cache +pytestdebug.log +source-contexts.json +source-context.json +client_secrets.json +\#*\# +.\#* +*_flymake.py +.DS_Store +.eggs/ +.python-version +.idea +node_modules/ +*.code-workspace +.envrc +.coverage +htmlcov/ +*.iml + +# Terraform +# See: https://github.com/github/gitignore/blob/master/Terraform.gitignore +**/.terraform/* +*.tfstate +*.tfstate.* +override.tf +override.tf.json +*_override.tf +*_override.tf.json +.terraformrc +terraform.rc +/cloudbuild/.terraform.lock.hcl diff --git a/README.md b/README.md new file mode 100644 index 0000000..cb841bb --- /dev/null +++ b/README.md @@ -0,0 +1,25 @@ +# Example Ansible Automation for Installing Anthos Bare Metal + + +## Setup Remote User +Make sure that the remote user account is configured to allow for the execution of sudo without the need to enter a password. An example of how this can be achieved can be found below: + +``` +# Setup sudoers for remote user account e.g "ansible-runner" +sudo rm -f /etc/sudoers.d/* +cat < 0) + with_items: + - "{{ copy_service_account_key }}" diff --git a/roles/copy-service-account-keys/tasks/main.yml b/roles/copy-service-account-keys/tasks/main.yml new file mode 100644 index 0000000..cfd1bbe --- /dev/null +++ b/roles/copy-service-account-keys/tasks/main.yml @@ -0,0 +1,35 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Create Directory for Service Account Keys + ansible.builtin.file: + path: "{{ gcp_keys_dir }}" + owner: "{{ login_user }}" + group: "{{ login_user }}" + state: directory + mode: u=rwx,g=,o= + +- name: Retrieve and Copy Service Account Key + ansible.builtin.include_tasks: copy-service-account-key.yml + with_items: + - "{{ ansible_service_account }}" + - "{{ anthos_container_registry_service_account }}" + - "{{ anthos_connect_agent_service_account }}" + - "{{ anthos_connect_register_service_account }}" + - "{{ anthos_logging_monitoring_service_account }}" + loop_control: + loop_var: copy_service_account_key \ No newline at end of file diff --git a/roles/copy-workstation-ssh/tasks/main.yml b/roles/copy-workstation-ssh/tasks/main.yml new file mode 100644 index 0000000..484650e --- /dev/null +++ b/roles/copy-workstation-ssh/tasks/main.yml @@ -0,0 +1,32 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Retrieve Workstation SSH Public Key + ansible.builtin.slurp: + src: "{{ ansible_user_dir }}/../{{ login_user }}/.ssh/id_rsa.pub" + register: out + become: true + delegate_to: "{{ target_workstation }}" + +- name: Write to SSH Authorized Keys + vars: + pubkey: "{{ out.content | b64decode }}" + ansible.builtin.lineinfile: + destfile: "{{ ansible_user_dir }}/../{{ login_user }}/.ssh/authorized_keys" + regexp: "{{ pubkey.split()[2] }}$" + line: "{{ pubkey }}" + become: true diff --git a/roles/create-ansible-service-accounts/tasks/main.yml b/roles/create-ansible-service-accounts/tasks/main.yml new file mode 100644 index 0000000..ec1f7b7 --- /dev/null +++ b/roles/create-ansible-service-accounts/tasks/main.yml @@ -0,0 +1,73 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Create Ansible Google Cloud Service Account + google.cloud.gcp_iam_service_account: + name: "{{ item }}@{{ gcp_project_id }}.iam.gserviceaccount.com" + display_name: "Ansible Service Account [{{ item }}]" + project: "{{ gcp_project_id }}" + auth_kind: application + state: present + with_items: + - "{{ ansible_service_account }}" + +- name: Grant Roles Required for the Ansible Google Cloud Service Account + ansible.builtin.shell: + cmd: | + set -o pipefail + gcloud projects add-iam-policy-binding "{{ gcp_project_id }}" --member="serviceAccount:{{ ansible_service_account }}@{{ gcp_project_id }}.iam.gserviceaccount.com" --role="{{ item }}" + args: + executable: /bin/bash + changed_when: false + with_items: + - "roles/compute.viewer" + - "roles/iam.serviceAccountKeyAdmin" + - "roles/secretmanager.admin" + - "roles/gkehub.admin" + +- name: Create Temp Directory + ansible.builtin.tempfile: + state: directory + suffix: .keys + register: tmpdir + changed_when: false + +- name: Create an Ansible Service Account Key and Add to Secret Manager + ansible.builtin.shell: + cmd: | + set -o pipefail + if ! $(gcloud secrets versions describe latest --secret="{{ item }}" >/dev/null 2>&1) ; then + gcloud iam service-accounts keys create "{{ item }}.json" --iam-account "{{ item }}@{{ gcp_project_id }}.iam.gserviceaccount.com" + if $(gcloud secrets describe "{{ item }}" >/dev/null 2>&1) ; then + gcloud secrets versions add "{{ item }}" --data-file="{{ item }}.json" + else + gcloud secrets create "{{ item }}" --data-file="{{ item }}.json" --replication-policy=user-managed --locations="{{ secret_manager_locations }}" + fi + rm -f "{{ item }}.json" + fi + chdir: "{{ tmpdir.path }}" + args: + executable: /bin/bash + changed_when: false + with_items: + - "{{ ansible_service_account }}" + +- name: Cleanup Temp Directory + ansible.builtin.file: + path: "{{ tmpdir.path }}" + state: absent + changed_when: false diff --git a/roles/create-anthos-service-accounts/tasks/main.yml b/roles/create-anthos-service-accounts/tasks/main.yml new file mode 100644 index 0000000..768f64c --- /dev/null +++ b/roles/create-anthos-service-accounts/tasks/main.yml @@ -0,0 +1,102 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Create Anthos Google Cloud Service Accounts + google.cloud.gcp_iam_service_account: + name: "{{ item }}@{{ gcp_project_id }}.iam.gserviceaccount.com" + display_name: "Anthos Service Account [{{ item }}]" + project: "{{ gcp_project_id }}" + auth_kind: application + state: present + with_items: + - "{{ anthos_container_registry_service_account }}" + - "{{ anthos_connect_agent_service_account }}" + - "{{ anthos_connect_register_service_account }}" + - "{{ anthos_logging_monitoring_service_account }}" + +- name: Grant Roles Required for the Anthos Connect Agent Service Account + ansible.builtin.shell: + cmd: | + set -o pipefail + gcloud projects add-iam-policy-binding "{{ gcp_project_id }}" --member="serviceAccount:{{ anthos_connect_agent_service_account }}@{{ gcp_project_id }}.iam.gserviceaccount.com" --role="{{ item }}" + args: + executable: /bin/bash + changed_when: false + with_items: + - "roles/gkehub.connect" + +- name: Grant Roles Required for the Anthos Connect Register Service Account + ansible.builtin.shell: + cmd: | + set -o pipefail + gcloud projects add-iam-policy-binding "{{ gcp_project_id }}" --member="serviceAccount:{{ anthos_connect_register_service_account }}@{{ gcp_project_id }}.iam.gserviceaccount.com" --role="{{ item }}" + args: + executable: /bin/bash + changed_when: false + with_items: + - "roles/gkehub.admin" + +- name: Grant Roles Required for the Anthos Logging Monitoring Service Account + ansible.builtin.shell: + cmd: | + set -o pipefail + gcloud projects add-iam-policy-binding "{{ gcp_project_id }}" --member="serviceAccount:{{ anthos_logging_monitoring_service_account }}@{{ gcp_project_id }}.iam.gserviceaccount.com" --role="{{ item }}" + args: + executable: /bin/bash + changed_when: false + with_items: + - "roles/logging.logWriter" + - "roles/monitoring.metricWriter" + - "roles/stackdriver.resourceMetadata.writer" + - "roles/monitoring.dashboardEditor" + - "roles/opsconfigmonitoring.resourceMetadata.writer" + +- name: Create Temp Directory + ansible.builtin.tempfile: + state: directory + suffix: .keys + register: tmpdir + changed_when: false + +- name: Create an Ansible Service Account Key and Add to Secret Manager + ansible.builtin.shell: + cmd: | + set -o pipefail + if ! $(gcloud secrets versions describe latest --secret="{{ item }}" >/dev/null 2>&1) ; then + gcloud iam service-accounts keys create "{{ item }}.json" --iam-account "{{ item }}@{{ gcp_project_id }}.iam.gserviceaccount.com" + if $(gcloud secrets describe "{{ item }}" >/dev/null 2>&1) ; then + gcloud secrets versions add "{{ item }}" --data-file="{{ item }}.json" + else + gcloud secrets create "{{ item }}" --data-file="{{ item }}.json" --replication-policy=user-managed --locations="{{ secret_manager_locations }}" + fi + rm -f "{{ item }}.json" + fi + chdir: "{{ tmpdir.path }}" + args: + executable: /bin/bash + changed_when: false + with_items: + - "{{ anthos_container_registry_service_account }}" + - "{{ anthos_connect_agent_service_account }}" + - "{{ anthos_connect_register_service_account }}" + - "{{ anthos_logging_monitoring_service_account }}" + +- name: Cleanup Temp Directory + ansible.builtin.file: + path: "{{ tmpdir.path }}" + state: absent + changed_when: false diff --git a/roles/disable-firewall/tasks/disable-firewall-debian.yml b/roles/disable-firewall/tasks/disable-firewall-debian.yml new file mode 100644 index 0000000..4f6d3ea --- /dev/null +++ b/roles/disable-firewall/tasks/disable-firewall-debian.yml @@ -0,0 +1,22 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Stop & Disable UFW Service [Debian / Ubuntu] + ansible.builtin.systemd: + name: ufw + enabled: no + state: stopped diff --git a/roles/disable-firewall/tasks/disable-firewall-redhat.yml b/roles/disable-firewall/tasks/disable-firewall-redhat.yml new file mode 100644 index 0000000..da15900 --- /dev/null +++ b/roles/disable-firewall/tasks/disable-firewall-redhat.yml @@ -0,0 +1,22 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Stop & Disable Firewalld Service [RedHat / CentOS] + ansible.builtin.systemd: + name: firewalld + enabled: no + state: stopped diff --git a/roles/disable-firewall/tasks/main.yml b/roles/disable-firewall/tasks/main.yml new file mode 100644 index 0000000..2d3467a --- /dev/null +++ b/roles/disable-firewall/tasks/main.yml @@ -0,0 +1,22 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Disable Firewall for OS Family + ansible.builtin.include_tasks: + file: 'disable-firewall-{{ ansible_os_family | lower }}.yml' + apply: + become: true diff --git a/roles/enable-ansible-services/tasks/main.yml b/roles/enable-ansible-services/tasks/main.yml new file mode 100644 index 0000000..0cbbe0f --- /dev/null +++ b/roles/enable-ansible-services/tasks/main.yml @@ -0,0 +1,28 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Enable Google Cloud Services + google.cloud.gcp_serviceusage_service: + name: "{{ item }}" + project: "{{ gcp_project_id }}" + auth_kind: application + state: present + with_items: + - servicecontrol.googleapis.com + - servicemanagement.googleapis.com + - serviceusage.googleapis.com + - secretmanager.googleapis.com diff --git a/roles/enable-anthos-services/tasks/main.yml b/roles/enable-anthos-services/tasks/main.yml new file mode 100644 index 0000000..800ae58 --- /dev/null +++ b/roles/enable-anthos-services/tasks/main.yml @@ -0,0 +1,40 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Enable Google Cloud Services + google.cloud.gcp_serviceusage_service: + name: "{{ item }}" + project: "{{ gcp_project_id }}" + auth_kind: application + state: present + with_items: + - servicemanagement.googleapis.com + - servicecontrol.googleapis.com + - anthos.googleapis.com + - anthosaudit.googleapis.com + - anthosgke.googleapis.com + - cloudresourcemanager.googleapis.com + - container.googleapis.com + - gkeconnect.googleapis.com + - gkehub.googleapis.com + - iam.googleapis.com + - logging.googleapis.com + - monitoring.googleapis.com + - opsconfigmonitoring.googleapis.com + - stackdriver.googleapis.com + - serviceusage.googleapis.com + - secretmanager.googleapis.com diff --git a/roles/remove-docker/tasks/main.yml b/roles/remove-docker/tasks/main.yml new file mode 100644 index 0000000..003c833 --- /dev/null +++ b/roles/remove-docker/tasks/main.yml @@ -0,0 +1,22 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Remove Docker for OS Family + ansible.builtin.include_tasks: + file: 'remove-docker-{{ ansible_os_family | lower }}.yml' + apply: + become: true diff --git a/roles/remove-docker/tasks/remove-docker-debian.yml b/roles/remove-docker/tasks/remove-docker-debian.yml new file mode 100644 index 0000000..1942d7b --- /dev/null +++ b/roles/remove-docker/tasks/remove-docker-debian.yml @@ -0,0 +1,44 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Remove Docker Packages [Debian / Ubuntu] + ansible.builtin.apt: + name: "{{ item }}" + state: absent + with_items: + - docker + - docker-engine + - docker.io + - containerd + - runc + - docker-ce + - docker-ce-cli + - containerd.io + - docker-ce-rootless-extras + - docker-scan-plugin + +- name: Remove Package Dependencies No Longer Required [Debian / Ubuntu] + ansible.builtin.apt: + autoremove: yes + +- name: Remove Docker Package Repository [Debian / Ubuntu] + ansible.builtin.file: + path: "{{ item }}" + state: absent + with_items: + - "/etc/apt/sources.list.d/docker.list" + - "/usr/share/keyrings/docker-archive-keyring.gpg" diff --git a/roles/remove-docker/tasks/remove-docker-redhat.yml b/roles/remove-docker/tasks/remove-docker-redhat.yml new file mode 100644 index 0000000..7640b31 --- /dev/null +++ b/roles/remove-docker/tasks/remove-docker-redhat.yml @@ -0,0 +1,47 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Remove Docker Packages [RedHat / CentOS] + ansible.builtin.dnf: + name: "{{ item }}" + state: absent + with_items: + - docker + - docker-client + - docker-client-latest + - docker-common + - docker-latest + - docker-latest-logrotate + - docker-logrotate + - docker-engine + - podman-manpages + - docker-ce + - docker-ce-cli + - containerd.io + - docker-ce-rootless-extras + - docker-scan-plugin + +- name: Remove Package Dependencies No Longer Required [RedHat / CentOS] + ansible.builtin.dnf: + autoremove: yes + +- name: Remove "docker-ce" Package Repository [RedHat / CentOS] + ansible.builtin.file: + path: "{{ item }}" + state: absent + with_items: + - "/etc/yum.repos.d/docker-ce.repo" diff --git a/roles/setup-bmctl/tasks/main.yml b/roles/setup-bmctl/tasks/main.yml new file mode 100644 index 0000000..4645f45 --- /dev/null +++ b/roles/setup-bmctl/tasks/main.yml @@ -0,0 +1,42 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Create Temp Directory + ansible.builtin.tempfile: + state: directory + suffix: .bmctl + register: tmpdir + changed_when: false + +- name: Download bmctl to Temp Directory, Make Executable and Move to "/usr/sbin" + ansible.builtin.shell: + cmd: | + set -o pipefail + gsutil cp gs://anthos-baremetal-release/bmctl/{{ bmctl_version }}/linux-amd64/bmctl . + chmod a+x bmctl + mv -f bmctl /usr/sbin/ + chdir: "{{ tmpdir.path }}" + args: + creates: /usr/sbin/bmctl + executable: /bin/bash + become: true + +- name: Cleanup Temp Directory + ansible.builtin.file: + path: "{{ tmpdir.path }}" + state: absent + changed_when: false diff --git a/roles/setup-docker/tasks/main.yml b/roles/setup-docker/tasks/main.yml new file mode 100644 index 0000000..ae6183b --- /dev/null +++ b/roles/setup-docker/tasks/main.yml @@ -0,0 +1,45 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Setup Docker for OS Family + ansible.builtin.include_tasks: + file: 'setup-docker-{{ ansible_os_family | lower }}.yml' + apply: + become: true + +- name: Start Docker Service + ansible.builtin.systemd: + name: docker + enabled: yes + state: started + become: true + +- name: Ensure "docker" User Group Exists + ansible.builtin.group: + name: docker + state: present + become: true + +- name: Add the "login_user" to the Docker Group + ansible.builtin.user: + name: "{{ login_user }}" + groups: docker + append: yes + become: true + +- name: Reset SSH Connection to Pickup Docker Group Changes + ansible.builtin.meta: reset_connection diff --git a/roles/setup-docker/tasks/setup-docker-debian.yml b/roles/setup-docker/tasks/setup-docker-debian.yml new file mode 100644 index 0000000..3c72aa2 --- /dev/null +++ b/roles/setup-docker/tasks/setup-docker-debian.yml @@ -0,0 +1,72 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Remove Previous Docker Versions [Debian / Ubuntu] + ansible.builtin.apt: + name: "{{ item }}" + state: absent + with_items: + - docker + - docker-engine + - docker.io + - containerd + - runc + +- name: Remove Package Dependencies No Longer Required [Debian / Ubuntu] + ansible.builtin.apt: + autoremove: yes + +- name: Install Docker [Debian / Ubuntu] + ansible.builtin.apt: + name: "{{ item }}" + state: present + with_items: + - apt-transport-https + - ca-certificates + - curl + - gnupg + - lsb-release + +- name: Add Docker Package Repository Source [Debian / Ubuntu] + ansible.builtin.template: + src: docker.list.j2 + dest: /etc/apt/sources.list.d/docker.list + owner: root + group: root + mode: u=rw,g=r,o=r + +- name: Import the Docker Repository GPG Key [Debian / Ubuntu] + ansible.builtin.shell: + cmd: | + set -o pipefail + curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --batch --yes --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + warn: no + args: + executable: /bin/bash + changed_when: false + +- name: Install Docker Engine [Debian / Ubuntu] + ansible.builtin.apt: + name: "{{ item }}" + state: present + update_cache: yes + with_items: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-ce-rootless-extras + - docker-scan-plugin diff --git a/roles/setup-docker/tasks/setup-docker-redhat.yml b/roles/setup-docker/tasks/setup-docker-redhat.yml new file mode 100644 index 0000000..8c8f7c0 --- /dev/null +++ b/roles/setup-docker/tasks/setup-docker-redhat.yml @@ -0,0 +1,52 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Remove Previous Docker Versions [RedHat / CentOS] + ansible.builtin.dnf: + name: "{{ item }}" + state: absent + with_items: + - docker + - docker-client + - docker-client-latest + - docker-common + - docker-latest + - docker-latest-logrotate + - docker-logrotate + - docker-engine + - podman-manpages + +- name: Remove Package Dependencies No Longer Required [RedHat / CentOS] + ansible.builtin.dnf: + autoremove: yes + +- name: Add "docker-ce" Package Repository [RedHat / CentOS] + ansible.builtin.command: + cmd: 'dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo' + warn: no + changed_when: false + +- name: Install Docker Engine [RedHat / CentOS] + ansible.builtin.dnf: + name: "{{ item }}" + state: present + with_items: + - docker-ce + - docker-ce-cli + - containerd.io + - docker-ce-rootless-extras + - docker-scan-plugin diff --git a/roles/setup-docker/templates/docker.list.j2 b/roles/setup-docker/templates/docker.list.j2 new file mode 100644 index 0000000..bbd0112 --- /dev/null +++ b/roles/setup-docker/templates/docker.list.j2 @@ -0,0 +1,2 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +deb [arch=amd64 signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu {{ ansible_distribution_release }} stable \ No newline at end of file diff --git a/roles/setup-gcloud-sdk/tasks/main.yml b/roles/setup-gcloud-sdk/tasks/main.yml new file mode 100644 index 0000000..7713f30 --- /dev/null +++ b/roles/setup-gcloud-sdk/tasks/main.yml @@ -0,0 +1,22 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Setup Google Cloud SDK for OS Family + ansible.builtin.include_tasks: + file: 'setup-gcloud-sdk-{{ ansible_os_family | lower }}.yml' + apply: + become: true diff --git a/roles/setup-gcloud-sdk/tasks/setup-gcloud-sdk-debian.yml b/roles/setup-gcloud-sdk/tasks/setup-gcloud-sdk-debian.yml new file mode 100644 index 0000000..48cc5d9 --- /dev/null +++ b/roles/setup-gcloud-sdk/tasks/setup-gcloud-sdk-debian.yml @@ -0,0 +1,52 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Install Dependencies [Debian / Ubuntu] + ansible.builtin.apt: + name: "{{ item }}" + state: present + with_items: + - apt-transport-https + - ca-certificates + - curl + - gnupg + +- name: Add Google Cloud SDK Package Repository Source [Debian / Ubuntu] + ansible.builtin.template: + src: google-cloud-sdk.list.j2 + dest: /etc/apt/sources.list.d/google-cloud-sdk.list + owner: root + group: root + mode: u=rw,g=r,o=r + +- name: Import the Google Cloud Package Repository GPG Key [Debian / Ubuntu] + ansible.builtin.shell: + cmd: | + set -o pipefail + curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key --keyring /usr/share/keyrings/cloud.google.gpg add - + warn: no + args: + executable: /bin/bash + changed_when: false + +- name: Install Google Cloud SDK [Debian / Ubuntu] + ansible.builtin.apt: + name: "{{ item }}" + state: present + update_cache: yes + with_items: + - google-cloud-sdk diff --git a/roles/setup-gcloud-sdk/tasks/setup-gcloud-sdk-redhat.yml b/roles/setup-gcloud-sdk/tasks/setup-gcloud-sdk-redhat.yml new file mode 100644 index 0000000..868956f --- /dev/null +++ b/roles/setup-gcloud-sdk/tasks/setup-gcloud-sdk-redhat.yml @@ -0,0 +1,32 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Add Google Cloud SDK Package Repository [RedHat / CentOS] + ansible.builtin.template: + src: google-cloud-sdk.repo.j2 + dest: /etc/yum.repos.d/google-cloud-sdk.repo + owner: root + group: root + mode: u=rw,g=r,o=r + +- name: Install Google Cloud SDK [RedHat / CentOS] + ansible.builtin.dnf: + name: "{{ item }}" + state: present + update_cache: yes + with_items: + - google-cloud-sdk diff --git a/roles/setup-gcloud-sdk/templates/google-cloud-sdk.list.j2 b/roles/setup-gcloud-sdk/templates/google-cloud-sdk.list.j2 new file mode 100644 index 0000000..0d631b7 --- /dev/null +++ b/roles/setup-gcloud-sdk/templates/google-cloud-sdk.list.j2 @@ -0,0 +1,2 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +deb [signed-by=/usr/share/keyrings/cloud.google.gpg] https://packages.cloud.google.com/apt cloud-sdk main \ No newline at end of file diff --git a/roles/setup-gcloud-sdk/templates/google-cloud-sdk.repo.j2 b/roles/setup-gcloud-sdk/templates/google-cloud-sdk.repo.j2 new file mode 100644 index 0000000..3b05abb --- /dev/null +++ b/roles/setup-gcloud-sdk/templates/google-cloud-sdk.repo.j2 @@ -0,0 +1,9 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +[google-cloud-sdk] +name=Google Cloud SDK +baseurl=https://packages.cloud.google.com/yum/repos/cloud-sdk-el8-x86_64 +enabled=1 +gpgcheck=1 +repo_gpgcheck=0 +gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg + https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg \ No newline at end of file diff --git a/roles/setup-kubectl/tasks/main.yml b/roles/setup-kubectl/tasks/main.yml new file mode 100644 index 0000000..2de96fd --- /dev/null +++ b/roles/setup-kubectl/tasks/main.yml @@ -0,0 +1,22 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Setup "kubectl" for OS Family + ansible.builtin.include_tasks: + file: 'setup-kubectl-{{ ansible_os_family | lower }}.yml' + apply: + become: true diff --git a/roles/setup-kubectl/tasks/setup-kubectl-debian.yml b/roles/setup-kubectl/tasks/setup-kubectl-debian.yml new file mode 100644 index 0000000..de336f8 --- /dev/null +++ b/roles/setup-kubectl/tasks/setup-kubectl-debian.yml @@ -0,0 +1,23 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Install "kubectl" [Debian / Ubuntu] + ansible.builtin.apt: + name: "{{ item }}" + state: present + with_items: + - kubectl diff --git a/roles/setup-kubectl/tasks/setup-kubectl-redhat.yml b/roles/setup-kubectl/tasks/setup-kubectl-redhat.yml new file mode 100644 index 0000000..d9686eb --- /dev/null +++ b/roles/setup-kubectl/tasks/setup-kubectl-redhat.yml @@ -0,0 +1,23 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Install "kubectl" [RedHat / CentOS] + ansible.builtin.dnf: + name: "{{ item }}" + state: present + with_items: + - kubectl diff --git a/roles/setup-login-user/tasks/main.yml b/roles/setup-login-user/tasks/main.yml new file mode 100644 index 0000000..d1e43e9 --- /dev/null +++ b/roles/setup-login-user/tasks/main.yml @@ -0,0 +1,43 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Create the "login_user" for OS Family + ansible.builtin.include_tasks: + file: 'setup-login-user-{{ ansible_os_family | lower }}.yml' + apply: + become: true + +- name: Configure the "login_user" for Passwordless "sudo" + ansible.builtin.template: + src: sudoers.j2 + dest: '/etc/sudoers.d/00-{{ login_user }}' + owner: root + group: root + mode: u=rw,g=r,o=r + become: true + +- name: Create "authorized_keys" for the "login_user" + ansible.builtin.shell: + cmd: | + set -o pipefail + cp {{ ansible_user_dir }}/.ssh/authorized_keys {{ ansible_user_dir }}/../{{ login_user }}/.ssh/authorized_keys + chown {{ login_user }}: {{ ansible_user_dir }}/../{{ login_user }}/.ssh/authorized_keys + chmod 600 {{ ansible_user_dir }}/../{{ login_user }}/.ssh/authorized_keys + args: + executable: /bin/bash + become: true + changed_when: false diff --git a/roles/setup-login-user/tasks/setup-login-user-debian.yml b/roles/setup-login-user/tasks/setup-login-user-debian.yml new file mode 100644 index 0000000..89ee025 --- /dev/null +++ b/roles/setup-login-user/tasks/setup-login-user-debian.yml @@ -0,0 +1,27 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Create the "login_user" account [Debian / Ubuntu] + ansible.builtin.user: + name: "{{ login_user }}" + comment: "Anthos Login User" + shell: /bin/bash + groups: sudo + append: yes + generate_ssh_key: yes + ssh_key_file: ".ssh/id_rsa" + ssh_key_comment: "{{ login_user }}@{{ ansible_hostname }}" diff --git a/roles/setup-login-user/tasks/setup-login-user-redhat.yml b/roles/setup-login-user/tasks/setup-login-user-redhat.yml new file mode 100644 index 0000000..83e1d63 --- /dev/null +++ b/roles/setup-login-user/tasks/setup-login-user-redhat.yml @@ -0,0 +1,27 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Create the "login_user" account [RedHat / CentOS] + ansible.builtin.user: + name: "{{ login_user }}" + comment: "Anthos Login User" + shell: /bin/bash + groups: wheel + append: yes + generate_ssh_key: yes + ssh_key_file: ".ssh/id_rsa" + ssh_key_comment: "{{ login_user }}@{{ ansible_hostname }}" diff --git a/roles/setup-login-user/templates/sudoers.j2 b/roles/setup-login-user/templates/sudoers.j2 new file mode 100644 index 0000000..95ec42b --- /dev/null +++ b/roles/setup-login-user/templates/sudoers.j2 @@ -0,0 +1,2 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +{{ login_user}} ALL=(ALL) NOPASSWD:ALL \ No newline at end of file diff --git a/roles/setup-timesync/tasks/main.yml b/roles/setup-timesync/tasks/main.yml new file mode 100644 index 0000000..a9fd4ed --- /dev/null +++ b/roles/setup-timesync/tasks/main.yml @@ -0,0 +1,34 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Setup Time Synchronisation for OS Family + ansible.builtin.include_tasks: + file: 'setup-timesync-{{ ansible_os_family | lower }}.yml' + apply: + become: true + +- name: Configure the System Timezone + ansible.builtin.command: + cmd: 'timedatectl set-timezone "{{ timezone }}"' + become: true + changed_when: false + +- name: Enable the Network Time Synchronisation + ansible.builtin.command: + cmd: 'timedatectl set-ntp true' + become: true + changed_when: false diff --git a/roles/setup-timesync/tasks/setup-timesync-debian.yml b/roles/setup-timesync/tasks/setup-timesync-debian.yml new file mode 100644 index 0000000..7938d90 --- /dev/null +++ b/roles/setup-timesync/tasks/setup-timesync-debian.yml @@ -0,0 +1,56 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Remove Unwanted Time Synchronisation Packages [Debian / Ubuntu] + ansible.builtin.apt: + name: "{{ item }}" + state: absent + with_items: + - ntp + - chrony + +- name: Remove Package Dependencies No Longer Required [Debian / Ubuntu] + ansible.builtin.apt: + autoremove: yes + +- name: Install Time Synchronisation Packages [Debian / Ubuntu] + ansible.builtin.apt: + name: "{{ item }}" + state: present + with_items: + - systemd-timesyncd + +- name: Enable Time Synchronisation Service [Debian / Ubuntu] + ansible.builtin.systemd: + name: systemd-timesyncd + enabled: yes + +- name: Configure Time Synchronisation Service [Debian / Ubuntu] + ansible.builtin.template: + src: timesyncd.conf.j2 + dest: /etc/systemd/timesyncd.conf + owner: root + group: root + mode: u=rw,g=r,o=r + register: configuration + +- name: Restart Time Synchronisation Service [Debian / Ubuntu] + ansible.builtin.systemd: + name: systemd-timesyncd + state: restarted + when: configuration.changed + tags: ['skip_ansible_lint'] diff --git a/roles/setup-timesync/tasks/setup-timesync-redhat.yml b/roles/setup-timesync/tasks/setup-timesync-redhat.yml new file mode 100644 index 0000000..0a773c3 --- /dev/null +++ b/roles/setup-timesync/tasks/setup-timesync-redhat.yml @@ -0,0 +1,56 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Remove Unwanted Time Synchronisation Packages [RedHat / CentOS] + ansible.builtin.dnf: + name: "{{ item }}" + state: absent + with_items: + - ntp + - systemd-timesyncd + +- name: Remove Packages Dependencies No Longer Required [RedHat / CentOS] + ansible.builtin.dnf: + autoremove: yes + +- name: Install Time Synchronisation Packages [RedHat / CentOS] + ansible.builtin.dnf: + name: "{{ item }}" + state: present + with_items: + - chrony + +- name: Enable Time Synchronisation Service [RedHat / CentOS] + ansible.builtin.systemd: + name: chronyd + enabled: yes + +- name: Configure Time Synchronisation Service [RedHat / CentOS] + ansible.builtin.template: + src: chrony.conf.j2 + dest: /etc/chrony.conf + owner: root + group: root + mode: u=rw,g=r,o=r + register: configuration + +- name: Restart Time Synchronisation Service [RedHat / CentOS] + ansible.builtin.systemd: + name: chronyd + state: restarted + when: configuration.changed + tags: ['skip_ansible_lint'] diff --git a/roles/setup-timesync/templates/chrony.conf.j2 b/roles/setup-timesync/templates/chrony.conf.j2 new file mode 100644 index 0000000..f002b5d --- /dev/null +++ b/roles/setup-timesync/templates/chrony.conf.j2 @@ -0,0 +1,39 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +# NTP Servers Configured by Ansible +{% for server in ntp_servers %}server {{ server }} iburst +{% endfor %} + +# Record the rate at which the system clock gains/losses time. +driftfile /var/lib/chrony/drift + +# Allow the system clock to be stepped in the first three updates +# if its offset is larger than 1 second. +makestep 1.0 3 + +# Enable kernel synchronization of the real-time clock (RTC). +rtcsync + +# Enable hardware timestamping on all interfaces that support it. +#hwtimestamp * + +# Increase the minimum number of selectable sources required to adjust +# the system clock. +#minsources 2 + +# Allow NTP client access from local network. +#allow 192.168.0.0/16 + +# Serve time even if not synchronized to a time source. +#local stratum 10 + +# Specify file containing keys for NTP authentication. +keyfile /etc/chrony.keys + +# Get TAI-UTC offset and leap seconds from the system tz database. +leapsectz right/UTC + +# Specify directory for log files. +logdir /var/log/chrony + +# Select which information is logged. +#log measurements statistics tracking \ No newline at end of file diff --git a/roles/setup-timesync/templates/timesyncd.conf.j2 b/roles/setup-timesync/templates/timesyncd.conf.j2 new file mode 100644 index 0000000..c87facd --- /dev/null +++ b/roles/setup-timesync/templates/timesyncd.conf.j2 @@ -0,0 +1,22 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# Entries in this file show the compile time defaults. +# You can change settings by editing this file. +# Defaults can be restored by simply deleting this file. +# +# See timesyncd.conf(5) for details. + +[Time] +NTP={% for server in ntp_servers %}{{ server}} {% endfor %} + +FallbackNTP={% for server in fallback_ntp_servers %}{{ server}} {% endfor %} + +RootDistanceMaxSec=5 +PollIntervalMinSec=32 +PollIntervalMaxSec=2048 \ No newline at end of file diff --git a/roles/system-package-update/tasks/main.yml b/roles/system-package-update/tasks/main.yml new file mode 100644 index 0000000..2d0854a --- /dev/null +++ b/roles/system-package-update/tasks/main.yml @@ -0,0 +1,22 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: System Package Update for OS Family + ansible.builtin.include_tasks: + file: 'system-package-update-{{ ansible_os_family | lower }}.yml' + apply: + become: true diff --git a/roles/system-package-update/tasks/system-package-update-debian.yml b/roles/system-package-update/tasks/system-package-update-debian.yml new file mode 100644 index 0000000..70614b7 --- /dev/null +++ b/roles/system-package-update/tasks/system-package-update-debian.yml @@ -0,0 +1,39 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Update All Packages to the Latest Version [Debian / Ubuntu] + ansible.builtin.apt: + update_cache: yes + upgrade: dist + state: latest + register: update_packages + +- name: Remove Packages Dependencies No Longer Required [Debian / Ubuntu] + ansible.builtin.apt: + autoremove: yes + +- name: Reboot and Wait [Debian / Ubuntu] + ansible.builtin.reboot: + msg: "Reboot Initiated by Ansible" + connect_timeout: 5 + reboot_timeout: 600 + pre_reboot_delay: 0 + post_reboot_delay: 30 + test_command: whoami + become: true + when: update_packages.changed + tags: ['skip_ansible_lint'] diff --git a/roles/system-package-update/tasks/system-package-update-redhat.yml b/roles/system-package-update/tasks/system-package-update-redhat.yml new file mode 100644 index 0000000..370f3d0 --- /dev/null +++ b/roles/system-package-update/tasks/system-package-update-redhat.yml @@ -0,0 +1,39 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +--- + +- name: Update All Packages to the Latest Version [RedHat / CentOS] + ansible.builtin.dnf: + update_cache: yes + name: "*" + state: latest + register: update_packages + +- name: Remove Packages Dependencies No Longer Required [RedHat / CentOS] + ansible.builtin.dnf: + autoremove: yes + +- name: Reboot and Wait [RedHat / CentOS] + ansible.builtin.reboot: + msg: "Reboot Initiated by Ansible" + connect_timeout: 5 + reboot_timeout: 600 + pre_reboot_delay: 0 + post_reboot_delay: 30 + test_command: whoami + become: true + when: update_packages.changed + tags: ['skip_ansible_lint'] diff --git a/run b/run new file mode 100755 index 0000000..a936c31 --- /dev/null +++ b/run @@ -0,0 +1,38 @@ +#!/usr/bin/env bash + +COLUMNS=10 + +echo "Ansible Playbook Runner" +echo "" + +OPTIONS=( + "Initialise - Ansible Galaxy Install" + "Install - Create Anthos Workstation" + "Install - Create Anthos Cluster" +) + +PS3='Select an operation: ' +select OPT in "${OPTIONS[@]}" +do + case $OPT in + + "Initialise - Ansible Galaxy Install") + pip install requests google-auth + ansible-galaxy collection install --force-with-deps -r vars/galaxy-requirements.yml + ;; + + "Install - Create Anthos Workstation") + ansible-playbook create-anthos-workstation.yml + ;; + + "Install - Create Anthos Cluster") + ansible-playbook create-anthos-cluster.yml + ;; + + *) + echo "Invalid option '${OPT}'" + ;; + + esac + break +done diff --git a/templates/bmctl-config-template.yaml.j2 b/templates/bmctl-config-template.yaml.j2 new file mode 100644 index 0000000..7b65202 --- /dev/null +++ b/templates/bmctl-config-template.yaml.j2 @@ -0,0 +1,209 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +# bmctl configuration variables. Because this section is valid YAML but not a valid Kubernetes +# resource, this section can only be included when using bmctl to +# create the initial admin/hybrid cluster. Afterwards, when creating user clusters by directly +# applying the cluster and node pool resources to the existing cluster, you must remove this +# section. +gcrKeyPath: "{{ gcp_keys_dir }}/{{ anthos_container_registry_service_account }}.json" +sshPrivateKeyPath: "{{ ansible_user_dir }}/.ssh/id_rsa" +gkeConnectAgentServiceAccountKeyPath: "{{ gcp_keys_dir }}/{{ anthos_connect_agent_service_account }}.json" +gkeConnectRegisterServiceAccountKeyPath: "{{ gcp_keys_dir }}/{{ anthos_connect_register_service_account }}.json" +cloudOperationsServiceAccountKeyPath: "{{ gcp_keys_dir }}/{{ anthos_logging_monitoring_service_account }}.json" +--- +apiVersion: v1 +kind: Namespace +metadata: + name: cluster-{{ cluster_name }} +--- +apiVersion: baremetal.cluster.gke.io/v1 +kind: Cluster +metadata: + name: {{ cluster_name }} + namespace: cluster-{{ cluster_name }} +spec: + # Cluster type. This can be: + # 1) admin: to create an admin cluster. This can later be used to create user clusters. + # 2) user: to create a user cluster. Requires an existing admin cluster. + # 3) hybrid: to create a hybrid cluster that runs admin cluster components and user workloads. + # 4) standalone: to create a cluster that manages itself, runs user workloads, but does not manage other clusters. + type: {{ cluster_type }} + # Cluster profile. This can be: + # 1) default: The default profile has limited resource requirements. + # 2) edge: The edge profile minimizes the resource consumption of Anthos clusters on bare metal. It is only available for standalone clusters. + profile: {{ cluster_profile }} + # Anthos cluster version. + anthosBareMetalVersion: {{ bmctl_version }} + # GKE connect configuration + gkeConnect: + projectID: {{ gcp_project_id }} + # Control plane configuration + controlPlane: + nodePoolSpec: + nodes: + # Control plane node pools. Typically, this is either a single machine + # or 3 machines if using a high availability deployment. + - address: + # Cluster networking configuration + clusterNetwork: + # Pods specify the IP ranges from which pod networks are allocated. + pods: + cidrBlocks: + - 192.168.0.0/16 + # Services specify the network ranges from which service virtual IPs are allocated. + # This can be any RFC1918 range that does not conflict with any other IP range + # in the cluster and node pool resources. + services: + cidrBlocks: + - 10.96.0.0/20 + # Load balancer configuration + loadBalancer: + # Load balancer mode can be either 'bundled' or 'manual'. + # In 'bundled' mode a load balancer will be installed on load balancer nodes during cluster creation. + # In 'manual' mode the cluster relies on a manually-configured external load balancer. + mode: bundled + # Load balancer port configuration + ports: + # Specifies the port the load balancer serves the Kubernetes control plane on. + # In 'manual' mode the external load balancer must be listening on this port. + controlPlaneLBPort: 443 + # There are two load balancer virtual IP (VIP) addresses: one for the control plane + # and one for the L7 Ingress service. The VIPs must be in the same subnet as the load balancer nodes. + # These IP addresses do not correspond to physical network interfaces. + vips: + # ControlPlaneVIP specifies the VIP to connect to the Kubernetes API server. + # This address must not be in the address pools below. + controlPlaneVIP: 10.0.0.8 + # IngressVIP specifies the VIP shared by all services for ingress traffic. + # Allowed only in non-admin clusters. + # This address must be in the address pools below. + # ingressVIP: 10.0.0.2 + # AddressPools is a list of non-overlapping IP ranges for the data plane load balancer. + # All addresses must be in the same subnet as the load balancer nodes. + # Address pool configuration is only valid for 'bundled' LB mode in non-admin clusters. + # addressPools: + # - name: pool1 + # addresses: + # # Each address must be either in the CIDR form (1.2.3.0/24) + # # or range form (1.2.3.1-1.2.3.5). + # - 10.0.0.1-10.0.0.4 + # A load balancer node pool can be configured to specify nodes used for load balancing. + # These nodes are part of the Kubernetes cluster and run regular workloads as well as load balancers. + # If the node pool config is absent then the control plane nodes are used. + # Node pool configuration is only valid for 'bundled' LB mode. + # nodePoolSpec: + # nodes: + # - address: + # Proxy configuration + # proxy: + # url: http://[username:password@]domain + # # A list of IPs, hostnames or domains that should not be proxied. + # noProxy: + # - 127.0.0.1 + # - localhost + # Logging and Monitoring + clusterOperations: + # Cloud project for logs and metrics. + projectID: {{ gcp_project_id }} + # Cloud location for logs and metrics. + location: {{ cluster_location }} + # Enable Cloud Audit Logging if uncommented and set to false. + disableCloudAuditLogging: false + # Whether collection of application logs/metrics should be enabled (in addition to + # collection of system logs/metrics which correspond to system components such as + # Kubernetes control plane or cluster management agents). + enableApplication: false + # Storage configuration + storage: + # lvpNodeMounts specifies the config for local PersistentVolumes backed by mounted disks. + # These disks need to be formatted and mounted by the user, which can be done before or after + # cluster creation. + lvpNodeMounts: + # path specifies the host machine path where mounted disks will be discovered and a local PV + # will be created for each mount. + path: /mnt/localpv-disk + # storageClassName specifies the StorageClass that PVs will be created with. The StorageClass + # is created during cluster creation. + storageClassName: local-disks + # lvpShare specifies the config for local PersistentVolumes backed by subdirectories in a shared filesystem. + # These subdirectories are automatically created during cluster creation. + lvpShare: + # path specifies the host machine path where subdirectories will be created on each host. A local PV + # will be created for each subdirectory. + path: /mnt/localpv-share + # storageClassName specifies the StorageClass that PVs will be created with. The StorageClass + # is created during cluster creation. + storageClassName: local-shared + # numPVUnderSharedPath specifies the number of subdirectories to create under path. + numPVUnderSharedPath: 5 + # NodeConfig specifies the configuration that applies to all nodes in the cluster. + nodeConfig: + # podDensity specifies the pod density configuration. + podDensity: + # maxPodsPerNode specifies at most how many pods can be run on a single node. + maxPodsPerNode: 250 + # containerRuntime specifies which container runtime to use for scheduling containers on nodes. + # containerd and docker are supported. + containerRuntime: {{ container_runtime }} + # KubeVirt configuration, uncomment this section if you want to install kubevirt to the cluster + # kubevirt: + # # if useEmulation is enabled, hardware accelerator (i.e relies on cpu feature like vmx or svm) + # # will not be attempted. QEMU will be used for software emulation. + # # useEmulation must be specified for KubeVirt installation + # useEmulation: false + # Authentication; uncomment this section if you wish to enable authentication to the cluster with OpenID Connect. + # authentication: + # oidc: + # # issuerURL specifies the URL of your OpenID provider, such as "https://accounts.google.com". The Kubernetes API + # # server uses this URL to discover public keys for verifying tokens. Must use HTTPS. + # issuerURL: + # # clientID specifies the ID for the client application that makes authentication requests to the OpenID + # # provider. + # clientID: + # # clientSecret specifies the secret for the client application. + # clientSecret: + # # kubectlRedirectURL specifies the redirect URL (required) for the gcloud CLI, such as + # # "http://localhost:[PORT]/callback". + # kubectlRedirectURL: + # # username specifies the JWT claim to use as the username. The default is "sub", which is expected to be a + # # unique identifier of the end user. + # username: + # # usernamePrefix specifies the prefix prepended to username claims to prevent clashes with existing names. + # usernamePrefix: + # # group specifies the JWT claim that the provider will use to return your security groups. + # group: + # # groupPrefix specifies the prefix prepended to group claims to prevent clashes with existing names. + # groupPrefix: + # # scopes specifies additional scopes to send to the OpenID provider as a comma-delimited list. + # scopes: + # # extraParams specifies additional key-value parameters to send to the OpenID provider as a comma-delimited + # # list. + # extraParams: + # # proxy specifies the proxy server to use for the cluster to connect to your OIDC provider, if applicable. + # # Example: https://user:password@10.10.10.10:8888. If left blank, this defaults to no proxy. + # proxy: + # # deployCloudConsoleProxy specifies whether to deploy a reverse proxy in the cluster to allow Google Cloud + # # Console access to the on-premises OIDC provider for authenticating users. If your identity provider is not + # # reachable over the public internet, and you wish to authenticate using Google Cloud Console, then this field + # # must be set to true. If left blank, this field defaults to false. + # deployCloudConsoleProxy: + # # certificateAuthorityData specifies a Base64 PEM-encoded certificate authority certificate of your identity + # # provider. It's not needed if your identity provider's certificate was issued by a well-known public CA. + # # However, if deployCloudConsoleProxy is true, then this value must be provided, even for a well-known public + # # CA. + # certificateAuthorityData: + # Node access configuration; uncomment this section if you wish to use a non-root user + # with passwordless sudo capability for machine login. + nodeAccess: + loginUser: {{ login_user }} +--- +# Node pools for worker nodes +apiVersion: baremetal.cluster.gke.io/v1 +kind: NodePool +metadata: + name: node-pool-1 + namespace: cluster-{{ cluster_name }} +spec: + clusterName: {{ cluster_name }} + nodes: + - address: + - address: \ No newline at end of file diff --git a/templates/bmctl-config-test-anthos-edge.yaml.j2 b/templates/bmctl-config-test-anthos-edge.yaml.j2 new file mode 100644 index 0000000..4bfda90 --- /dev/null +++ b/templates/bmctl-config-test-anthos-edge.yaml.j2 @@ -0,0 +1,66 @@ +#jinja2: trim_blocks: "true", lstrip_blocks: "false" +gcrKeyPath: "{{ gcp_keys_dir }}/{{ anthos_container_registry_service_account }}.json" +sshPrivateKeyPath: "{{ ansible_user_dir }}/.ssh/id_rsa" +gkeConnectAgentServiceAccountKeyPath: "{{ gcp_keys_dir }}/{{ anthos_connect_agent_service_account }}.json" +gkeConnectRegisterServiceAccountKeyPath: "{{ gcp_keys_dir }}/{{ anthos_connect_register_service_account }}.json" +cloudOperationsServiceAccountKeyPath: "{{ gcp_keys_dir }}/{{ anthos_logging_monitoring_service_account }}.json" +--- +apiVersion: v1 +kind: Namespace +metadata: + name: cluster-{{ cluster_name }} +--- +apiVersion: baremetal.cluster.gke.io/v1 +kind: Cluster +metadata: + name: {{ cluster_name }} + namespace: cluster-{{ cluster_name }} +spec: + type: {{ cluster_type }} + profile: {{ cluster_profile }} + anthosBareMetalVersion: {{ bmctl_version }} + gkeConnect: + projectID: {{ gcp_project_id }} + controlPlane: + nodePoolSpec: + nodes: + - address: 10.0.200.2 + clusterNetwork: + pods: + cidrBlocks: + - 192.168.0.0/16 + services: + cidrBlocks: + - 10.96.0.0/12 + loadBalancer: + mode: bundled + ports: + controlPlaneLBPort: 443 + vips: + controlPlaneVIP: 10.0.200.3 + ingressVIP: 10.0.200.4 + addressPools: + - name: ingressPool + addresses: + - 10.0.200.4-10.0.200.4 + clusterOperations: + projectID: {{ gcp_project_id }} + location: {{ cluster_location }} + disableCloudAuditLogging: false + enableApplication: true + storage: + lvpNodeMounts: + path: /mnt/localpv-disk + storageClassName: local-disks + lvpShare: + path: /mnt/localpv-share + storageClassName: local-shared + numPVUnderSharedPath: 5 + nodeConfig: + podDensity: + maxPodsPerNode: 250 + containerRuntime: {{ container_runtime }} + kubevirt: + useEmulation: false + nodeAccess: + loginUser: {{ login_user }} diff --git a/vars/anthos.yml b/vars/anthos.yml new file mode 100644 index 0000000..0c3528d --- /dev/null +++ b/vars/anthos.yml @@ -0,0 +1,62 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +#-------------------------------------------------------------------- +# Target Hosts +#-------------------------------------------------------------------- +target_workstation: anthos-workstation +target_nodes: anthos_cluster + +#-------------------------------------------------------------------- +# Google Cloud Project Configuration +#-------------------------------------------------------------------- +gcp_project_id: "test-anthos-edge-project" + +ansible_service_account: "ansible-runner" + +anthos_container_registry_service_account: "anthos-container-registry" +anthos_connect_agent_service_account: "anthos-connect-agent" +anthos_connect_register_service_account: "anthos-connect-register" +anthos_logging_monitoring_service_account: "anthos-logging-monitoring" + +secret_manager_locations: "australia-southeast1,australia-southeast2" + +#-------------------------------------------------------------------- +# "bmctl" Configuration +#-------------------------------------------------------------------- +bmctl_version: "1.8.3" + +login_user: "anthos" + +gcp_keys_dir: "{{ ansible_user_dir }}/.gcp_keys" +bmctl_workspace_dir: "{{ ansible_user_dir }}/bmctl-workspace" + +# Cluster name: The name the Anthos Cluster will be registered with on GCP +# Cluster type. This can be: +# 1) admin: to create an admin cluster. This can later be used to create user clusters. +# 2) user: to create a user cluster. Requires an existing admin cluster. +# 3) hybrid: to create a hybrid cluster that runs admin cluster components and user workloads. +# 4) standalone: to create a cluster that manages itself, runs user workloads, but does not manage other clusters. +# Cluster profile. This can be: +# 1) default: The default profile has limited resource requirements. +# 2) edge: The edge profile minimizes the resource consumption of Anthos clusters on bare metal. It is only available for standalone clusters. +cluster_name: "test-anthos-edge" +cluster_type: "standalone" +cluster_profile: "edge" +cluster_location: "australia-southeast1" + +# Container Runtime specifies which container runtime to use for scheduling containers on nodes. +# containerd and docker are supported. +container_runtime: "containerd" diff --git a/vars/galaxy-requirements.yml b/vars/galaxy-requirements.yml new file mode 100644 index 0000000..bc6a6b3 --- /dev/null +++ b/vars/galaxy-requirements.yml @@ -0,0 +1,23 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +#-------------------------------------------------------------------- +# Ansible Galaxy Requirements List +#-------------------------------------------------------------------- + +--- +collections: + - community.general + - google.cloud diff --git a/vars/timesync.yml b/vars/timesync.yml new file mode 100644 index 0000000..9eb0c39 --- /dev/null +++ b/vars/timesync.yml @@ -0,0 +1,20 @@ +# Copyright 2021, Matthew Winter +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +ntp_servers: + - time.google.com +fallback_ntp_servers: + - time.cloudflare.com +timezone: UTC