From 6f82f49a0da58f6357e878d81de2fa4974b75170 Mon Sep 17 00:00:00 2001 From: MarcTM01 Date: Thu, 17 Oct 2024 17:04:17 +0200 Subject: [PATCH] Add ansible notebook for configuring QALab Servers --- .gitignore | 3 ++ infra/playbook.yml | 26 ++++++++++ infra/requirements.yml | 4 ++ infra/roles/configuressh/handlers/main.yml | 6 +++ infra/roles/configuressh/meta/main.yml | 2 + infra/roles/configuressh/tasks/main.yml | 26 ++++++++++ infra/roles/systemupdate/meta/main.yml | 2 + infra/roles/systemupdate/tasks/main.yml | 30 +++++++++++ pdm.lock | 60 ++++++++++++++++++---- pyproject.toml | 3 ++ 10 files changed, 153 insertions(+), 9 deletions(-) create mode 100644 infra/playbook.yml create mode 100644 infra/requirements.yml create mode 100644 infra/roles/configuressh/handlers/main.yml create mode 100644 infra/roles/configuressh/meta/main.yml create mode 100644 infra/roles/configuressh/tasks/main.yml create mode 100644 infra/roles/systemupdate/meta/main.yml create mode 100644 infra/roles/systemupdate/tasks/main.yml diff --git a/.gitignore b/.gitignore index 9773deb..d509af3 100644 --- a/.gitignore +++ b/.gitignore @@ -164,3 +164,6 @@ cython_debug/ # Automatically generated API clients clients/ + +# Ansible Inventory +inventory.yml \ No newline at end of file diff --git a/infra/playbook.yml b/infra/playbook.yml new file mode 100644 index 0000000..98ebbd2 --- /dev/null +++ b/infra/playbook.yml @@ -0,0 +1,26 @@ +--- +- name: Configure an OTC ubuntu server for a Dataland QALab Deployment + hosts: all + become: true + tasks: + - name: Update packages on the system + ansible.builtin.include_role: + name: systemupdate + + - name: Configure SSH Server + ansible.builtin.include_role: + name: configuressh + + - name: Install docker + ansible.builtin.include_role: + name: geerlingguy.docker + vars: + docker_install_compose: false + docker_users: + - 'ubuntu' + + - name: Configure authoirzed SSH Keys + ansible.posix.authorized_key: + user: ubuntu + state: present + key: "{{ authorized_ssh_keys }}" diff --git a/infra/requirements.yml b/infra/requirements.yml new file mode 100644 index 0000000..0e3a416 --- /dev/null +++ b/infra/requirements.yml @@ -0,0 +1,4 @@ +--- +roles: + - name: geerlingguy.docker + version: "7.1.0" diff --git a/infra/roles/configuressh/handlers/main.yml b/infra/roles/configuressh/handlers/main.yml new file mode 100644 index 0000000..e9b61de --- /dev/null +++ b/infra/roles/configuressh/handlers/main.yml @@ -0,0 +1,6 @@ +--- +- name: Restart ssh + become: true + ansible.builtin.service: + name: "ssh" + state: "restarted" diff --git a/infra/roles/configuressh/meta/main.yml b/infra/roles/configuressh/meta/main.yml new file mode 100644 index 0000000..23d65c7 --- /dev/null +++ b/infra/roles/configuressh/meta/main.yml @@ -0,0 +1,2 @@ +--- +dependencies: [] diff --git a/infra/roles/configuressh/tasks/main.yml b/infra/roles/configuressh/tasks/main.yml new file mode 100644 index 0000000..6471a69 --- /dev/null +++ b/infra/roles/configuressh/tasks/main.yml @@ -0,0 +1,26 @@ +--- +- name: Update SSH configuration. + become: true + ansible.builtin.lineinfile: + dest: "/etc/ssh/sshd_config" + regexp: "{{ item.regexp }}" + line: "{{ item.line }}" + state: present + validate: 'sshd -T -f %s' + mode: "u=rw,g=r,o=r" + with_items: + - regexp: "^PasswordAuthentication" + line: "PasswordAuthentication No" + - regexp: "^PermitRootLogin" + line: "PermitRootLogin No" + - regexp: "^PermitEmptyPasswords" + line: "PermitEmptyPasswords No" + - regexp: "^ChallengeResponseAuthentication" + line: "ChallengeResponseAuthentication No" + - regexp: "^GSSAPIAuthentication" + line: "GSSAPIAuthentication No" + - regexp: "^X11Forwarding" + line: "X11Forwarding No" + - regexp: '^AllowTcpForwarding' + line: "AllowTcpForwarding yes" + notify: Restart ssh \ No newline at end of file diff --git a/infra/roles/systemupdate/meta/main.yml b/infra/roles/systemupdate/meta/main.yml new file mode 100644 index 0000000..23d65c7 --- /dev/null +++ b/infra/roles/systemupdate/meta/main.yml @@ -0,0 +1,2 @@ +--- +dependencies: [] diff --git a/infra/roles/systemupdate/tasks/main.yml b/infra/roles/systemupdate/tasks/main.yml new file mode 100644 index 0000000..3c3ba2e --- /dev/null +++ b/infra/roles/systemupdate/tasks/main.yml @@ -0,0 +1,30 @@ +--- +- name: Update the system using apt, rebooting if required + become: true + block: + - name: Update apt cache if needed + ansible.builtin.apt: + update_cache: true + cache_valid_time: 3600 + + - name: Upgrade all packages on server + ansible.builtin.apt: + upgrade: dist + + - name: Check if a reboot is required + register: reboot_required_file + ansible.builtin.stat: + path: /var/run/reboot-required + + - name: Reboot if required + ansible.builtin.reboot: + connect_timeout: 5 + reboot_timeout: 300 + pre_reboot_delay: 0 + post_reboot_delay: 30 + test_command: uptime + when: reboot_required_file.stat.exists + + - name: Remove dependencies that are no longer required. + ansible.builtin.apt: + autoremove: true diff --git a/pdm.lock b/pdm.lock index 5a97089..3753214 100644 --- a/pdm.lock +++ b/pdm.lock @@ -2,10 +2,10 @@ # It is not intended for manual editing. [metadata] -groups = ["default", "linting", "notebooks", "testing"] +groups = ["default", "infra", "linting", "notebooks", "testing"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:cc0a24c76d139392219e53bba7587005f2f74de09cb88b870681c7c84aa6a7f9" +content_hash = "sha256:e578e4595b250994f16a02bcca3a47af03818d42bcaa20ea6f6f85b4d6c63f8b" [[metadata.targets]] requires_python = ">=3.12" @@ -24,6 +24,38 @@ files = [ {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, ] +[[package]] +name = "ansible" +version = "10.5.0" +requires_python = ">=3.10" +summary = "Radically simple IT automation" +groups = ["infra"] +dependencies = [ + "ansible-core~=2.17.5", +] +files = [ + {file = "ansible-10.5.0-py3-none-any.whl", hash = "sha256:1d10bddba58f1edd0fe0b8e0387e0fafc519535066bb3c919c33b6ea3ec32a0f"}, + {file = "ansible-10.5.0.tar.gz", hash = "sha256:ba2045031a7d60c203b6e5fe1f8eaddd53ae076f7ada910e636494384135face"}, +] + +[[package]] +name = "ansible-core" +version = "2.17.5" +requires_python = ">=3.10" +summary = "Radically simple IT automation" +groups = ["infra"] +dependencies = [ + "PyYAML>=5.1", + "cryptography", + "jinja2>=3.0.0", + "packaging", + "resolvelib<1.1.0,>=0.5.3", +] +files = [ + {file = "ansible_core-2.17.5-py3-none-any.whl", hash = "sha256:10f165b475cf2bc8d886e532cadb32c52ee6a533649793101d3166bca9bd3ea3"}, + {file = "ansible_core-2.17.5.tar.gz", hash = "sha256:ae7f51fd13dc9d57c9bcd43ef23f9c255ca8f18f4b5c0011a4f9b724d92c5a8e"}, +] + [[package]] name = "anyio" version = "4.6.2.post1" @@ -239,7 +271,7 @@ name = "cffi" version = "1.17.1" requires_python = ">=3.8" summary = "Foreign Function Interface for Python calling C code." -groups = ["default", "notebooks"] +groups = ["default", "infra", "notebooks"] dependencies = [ "pycparser", ] @@ -381,7 +413,7 @@ name = "cryptography" version = "43.0.1" requires_python = ">=3.7" summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -groups = ["default"] +groups = ["default", "infra"] dependencies = [ "cffi>=1.12; platform_python_implementation != \"PyPy\"", ] @@ -713,7 +745,7 @@ name = "jinja2" version = "3.1.4" requires_python = ">=3.7" summary = "A very fast and expressive template engine." -groups = ["notebooks"] +groups = ["infra", "notebooks"] dependencies = [ "MarkupSafe>=2.0", ] @@ -1017,7 +1049,7 @@ name = "markupsafe" version = "3.0.1" requires_python = ">=3.9" summary = "Safely add untrusted strings to HTML/XML markup." -groups = ["notebooks"] +groups = ["infra", "notebooks"] files = [ {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8ae369e84466aa70f3154ee23c1451fda10a8ee1b63923ce76667e3077f2b0c4"}, {file = "MarkupSafe-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40f1e10d51c92859765522cbd79c5c8989f40f0419614bcdc5015e7b6bf97fc5"}, @@ -1206,7 +1238,7 @@ name = "packaging" version = "24.1" requires_python = ">=3.8" summary = "Core utilities for Python packages" -groups = ["notebooks", "testing"] +groups = ["infra", "notebooks", "testing"] files = [ {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, @@ -1338,7 +1370,7 @@ name = "pycparser" version = "2.22" requires_python = ">=3.8" summary = "C parser in Python" -groups = ["default", "notebooks"] +groups = ["default", "infra", "notebooks"] files = [ {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, @@ -1525,7 +1557,7 @@ name = "pyyaml" version = "6.0.2" requires_python = ">=3.8" summary = "YAML parser and emitter for Python" -groups = ["notebooks"] +groups = ["infra", "notebooks"] files = [ {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, @@ -1626,6 +1658,16 @@ files = [ {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, ] +[[package]] +name = "resolvelib" +version = "1.0.1" +summary = "Resolve abstract dependencies into concrete ones" +groups = ["infra"] +files = [ + {file = "resolvelib-1.0.1-py2.py3-none-any.whl", hash = "sha256:d2da45d1a8dfee81bdd591647783e340ef3bcb104b54c383f70d422ef5cc7dbf"}, + {file = "resolvelib-1.0.1.tar.gz", hash = "sha256:04ce76cbd63fded2078ce224785da6ecd42b9564b1390793f64ddecbe997b309"}, +] + [[package]] name = "rfc3339-validator" version = "0.1.4" diff --git a/pyproject.toml b/pyproject.toml index 8a4ba48..34982b8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -46,6 +46,9 @@ testing = [ "pytest>=8.3.3", "coverage>=7.6.3", ] +infra = [ + "ansible>=10.5.0", +] [tool.ruff] line-length = 120