From 1b2565d26996deb5334cc4107827469f61ece33f Mon Sep 17 00:00:00 2001 From: kogeler <25884155+kogeler@users.noreply.github.com> Date: Wed, 22 Nov 2023 15:57:51 +0200 Subject: [PATCH] nginx and nginx_exporter roles were added (#62) * nginx and nginx_exporter roles were added Signed-off-by: kogeler --- .github/workflows/branch-main.yml | 4 +- .github/workflows/pr-nginx-exporter.yml | 18 +++ .github/workflows/pr-nginx.yml | 18 +++ .github/workflows/pr-node-backup.yml | 2 +- .github/workflows/pr-node.yml | 2 +- .github/workflows/pr-ws-health-exporter.yml | 2 +- .github/workflows/reusable-galaxy-deploy.yml | 6 +- .github/workflows/reusable-molecule.yml | 31 ++++- galaxy.yml | 2 +- roles/key_inject/README.md | 1 + roles/nginx/.yamllint | 33 +++++ roles/nginx/README.md | 1 + roles/nginx/defaults/main.yml | 50 +++++++ roles/nginx/files/reload-nginx-config | 2 + roles/nginx/handlers/main.yml | 8 ++ roles/nginx/molecule/default/README.md | 18 +++ roles/nginx/molecule/default/converge.yml | 9 ++ .../molecule/default/files/pebble/cert.pem | 19 +++ .../molecule/default/files/pebble/key.pem | 27 ++++ roles/nginx/molecule/default/files/test1.pem | 55 ++++++++ roles/nginx/molecule/default/files/test2.pem | 55 ++++++++ .../nginx/molecule/default/group_vars/all.yml | 30 +++++ roles/nginx/molecule/default/molecule.yml | 34 +++++ roles/nginx/molecule/default/prepare.yml | 95 ++++++++++++++ .../default/templates/http-stub.service.j2 | 10 ++ .../default/templates/pebble-config.json.j2 | 12 ++ .../default/templates/pebble.service.j2 | 10 ++ .../default/templates/websocat.service.j2 | 11 ++ roles/nginx/molecule/default/verify.yml | 20 +++ roles/nginx/tasks/certs-loop.yml | 12 ++ roles/nginx/tasks/certs.yml | 47 +++++++ roles/nginx/tasks/letsencrypt-loop.yml | 25 ++++ roles/nginx/tasks/letsencrypt.yml | 16 +++ roles/nginx/tasks/main.yml | 123 ++++++++++++++++++ roles/nginx/tasks/remove.yml | 28 ++++ roles/nginx/tasks/sites.yml | 49 +++++++ roles/nginx/tasks/tests.yml | 31 +++++ roles/nginx/templates/nginx.conf.j2 | 42 ++++++ roles/nginx/templates/override.conf.j2 | 2 + roles/nginx/templates/site-connect.j2 | 52 ++++++++ roles/nginx/templates/site-default.j2 | 20 +++ roles/nginx/templates/site-rpc.j2 | 55 ++++++++ roles/nginx/vars/main.yml | 3 + roles/nginx_exporter/.yamllint | 33 +++++ roles/nginx_exporter/README.md | 1 + roles/nginx_exporter/defaults/main.yml | 6 + roles/nginx_exporter/handlers/main.yml | 8 ++ roles/nginx_exporter/tasks/main.yml | 44 +++++++ roles/nginx_exporter/templates/.service.j2 | 15 +++ roles/nginx_exporter/vars/main.yml | 1 + roles/node/molecule/default/molecule.yml | 4 - roles/node/molecule/parachain/molecule.yml | 4 - .../molecule/parachain_remote_rc/molecule.yml | 4 - .../node_backup/molecule/default/molecule.yml | 4 - .../molecule/default/molecule.yml | 4 - 55 files changed, 1182 insertions(+), 36 deletions(-) create mode 100644 .github/workflows/pr-nginx-exporter.yml create mode 100644 .github/workflows/pr-nginx.yml create mode 100644 roles/nginx/.yamllint create mode 100644 roles/nginx/README.md create mode 100644 roles/nginx/defaults/main.yml create mode 100755 roles/nginx/files/reload-nginx-config create mode 100644 roles/nginx/handlers/main.yml create mode 100644 roles/nginx/molecule/default/README.md create mode 100644 roles/nginx/molecule/default/converge.yml create mode 100644 roles/nginx/molecule/default/files/pebble/cert.pem create mode 100644 roles/nginx/molecule/default/files/pebble/key.pem create mode 100644 roles/nginx/molecule/default/files/test1.pem create mode 100644 roles/nginx/molecule/default/files/test2.pem create mode 100644 roles/nginx/molecule/default/group_vars/all.yml create mode 100644 roles/nginx/molecule/default/molecule.yml create mode 100644 roles/nginx/molecule/default/prepare.yml create mode 100644 roles/nginx/molecule/default/templates/http-stub.service.j2 create mode 100644 roles/nginx/molecule/default/templates/pebble-config.json.j2 create mode 100644 roles/nginx/molecule/default/templates/pebble.service.j2 create mode 100644 roles/nginx/molecule/default/templates/websocat.service.j2 create mode 100644 roles/nginx/molecule/default/verify.yml create mode 100644 roles/nginx/tasks/certs-loop.yml create mode 100644 roles/nginx/tasks/certs.yml create mode 100644 roles/nginx/tasks/letsencrypt-loop.yml create mode 100644 roles/nginx/tasks/letsencrypt.yml create mode 100644 roles/nginx/tasks/main.yml create mode 100644 roles/nginx/tasks/remove.yml create mode 100644 roles/nginx/tasks/sites.yml create mode 100644 roles/nginx/tasks/tests.yml create mode 100644 roles/nginx/templates/nginx.conf.j2 create mode 100644 roles/nginx/templates/override.conf.j2 create mode 100644 roles/nginx/templates/site-connect.j2 create mode 100644 roles/nginx/templates/site-default.j2 create mode 100644 roles/nginx/templates/site-rpc.j2 create mode 100644 roles/nginx/vars/main.yml create mode 100644 roles/nginx_exporter/.yamllint create mode 100644 roles/nginx_exporter/README.md create mode 100644 roles/nginx_exporter/defaults/main.yml create mode 100644 roles/nginx_exporter/handlers/main.yml create mode 100644 roles/nginx_exporter/tasks/main.yml create mode 100644 roles/nginx_exporter/templates/.service.j2 create mode 100644 roles/nginx_exporter/vars/main.yml diff --git a/.github/workflows/branch-main.yml b/.github/workflows/branch-main.yml index 7824341..5709e41 100644 --- a/.github/workflows/branch-main.yml +++ b/.github/workflows/branch-main.yml @@ -11,9 +11,9 @@ jobs: fail-fast: false matrix: role-names: [node, ws_health_exporter] - molecule-drivers: [docker, lxd] + molecule-drivers: [docker] # We test the latest version and minimum supported version - ansible-versions: [8.0.0, 8.6.1] + ansible-versions: [8.0.0, 9.0.1] uses: ./.github/workflows/reusable-molecule.yml with: role-name: ${{ matrix.role-names }} diff --git a/.github/workflows/pr-nginx-exporter.yml b/.github/workflows/pr-nginx-exporter.yml new file mode 100644 index 0000000..91951ab --- /dev/null +++ b/.github/workflows/pr-nginx-exporter.yml @@ -0,0 +1,18 @@ +name: check PR (nginx_exporter) + +on: + pull_request: + paths: + - roles/nginx_exporter/** + - .github/** + +jobs: + run-molecule-tests: + strategy: + fail-fast: false + matrix: + molecule-driver: [docker] + uses: ./.github/workflows/reusable-molecule.yml + with: + role-name: nginx_exporter + molecule-driver: ${{ matrix.molecule-driver }} diff --git a/.github/workflows/pr-nginx.yml b/.github/workflows/pr-nginx.yml new file mode 100644 index 0000000..b885fa1 --- /dev/null +++ b/.github/workflows/pr-nginx.yml @@ -0,0 +1,18 @@ +name: check PR (nginx) + +on: + pull_request: + paths: + - roles/nginx/** + - .github/** + +jobs: + run-molecule-tests: + strategy: + fail-fast: false + matrix: + molecule-driver: [docker] + uses: ./.github/workflows/reusable-molecule.yml + with: + role-name: nginx + molecule-driver: ${{ matrix.molecule-driver }} diff --git a/.github/workflows/pr-node-backup.yml b/.github/workflows/pr-node-backup.yml index 76a9157..2dc63f5 100644 --- a/.github/workflows/pr-node-backup.yml +++ b/.github/workflows/pr-node-backup.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - molecule-driver: [lxd, docker] + molecule-driver: [docker] uses: ./.github/workflows/reusable-molecule.yml with: role-name: node diff --git a/.github/workflows/pr-node.yml b/.github/workflows/pr-node.yml index c8f1d0f..a19cd12 100644 --- a/.github/workflows/pr-node.yml +++ b/.github/workflows/pr-node.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - molecule-driver: [lxd, docker] + molecule-driver: [docker] uses: ./.github/workflows/reusable-molecule.yml with: role-name: node diff --git a/.github/workflows/pr-ws-health-exporter.yml b/.github/workflows/pr-ws-health-exporter.yml index 88423c4..5bec99d 100644 --- a/.github/workflows/pr-ws-health-exporter.yml +++ b/.github/workflows/pr-ws-health-exporter.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - molecule-driver: [lxd, docker] + molecule-driver: [docker] uses: ./.github/workflows/reusable-molecule.yml with: role-name: ws_health_exporter diff --git a/.github/workflows/reusable-galaxy-deploy.yml b/.github/workflows/reusable-galaxy-deploy.yml index 84de1a8..64c68e0 100644 --- a/.github/workflows/reusable-galaxy-deploy.yml +++ b/.github/workflows/reusable-galaxy-deploy.yml @@ -4,7 +4,7 @@ on: ansible-version: required: false type: string - default: 8.4.0 + default: 9.0.1 secrets: api-token: required: true @@ -21,9 +21,7 @@ jobs: with: python-version: '3.x' - name: Setup Python modules - # PyYAML==5.3.1 fixes the 'The license_file parameter is deprecated, use license_files instead.' error - # the 5.4.1 version still has the issue - run: pip3 install --no-cache-dir PyYAML==5.3.1 ansible==${{ inputs.ansible-version }} yq + run: pip3 install --no-cache-dir ansible==${{ inputs.ansible-version }} yq - name: Print Ansible version run: ansible --version - name: Build collection diff --git a/.github/workflows/reusable-molecule.yml b/.github/workflows/reusable-molecule.yml index 8a73cce..3ce3e4c 100644 --- a/.github/workflows/reusable-molecule.yml +++ b/.github/workflows/reusable-molecule.yml @@ -10,7 +10,7 @@ on: ansible-version: required: false type: string - default: 8.4.0 + default: 9.0.1 jobs: molecule: runs-on: ubuntu-22.04 @@ -25,18 +25,37 @@ jobs: uses: actions/setup-python@v4 with: python-version: '3.x' - - name: Setup Python modules - # PyYAML==5.3.1 fixes the 'The license_file parameter is deprecated, use license_files instead.' error - # 5.4.1 version still has the issue - run: pip3 install --no-cache-dir PyYAML==5.3.1 yamllint ansible==${{ inputs.ansible-version }} ansible-lint molecule molecule-plugins[docker] molecule-lxd docker + - name: Check molecule + run: | + if [ -d "molecule" ]; then + echo "MOLECULE_IS_PRESENT=PRESENT" >> "${GITHUB_ENV}" + fi + working-directory: "${{ github.repository }}/roles/${{ inputs.role-name }}" + - name: Setup molecule + run: | + pip3 install --no-cache-dir yamllint ansible==${{ inputs.ansible-version }} ansible-lint \ + molecule molecule-plugins[docker] docker \ + jmespath - name: Print Ansible version run: ansible --version - name: Setup LXD - if: ${{ inputs.molecule-driver == 'lxd' }} + if: ${{ env.MOLECULE_IS_PRESENT && inputs.molecule-driver == 'lxd' }} # https://github.com/canonical/setup-lxd uses: canonical/setup-lxd@v0.1.1 with: channel: latest/stable + - name: Setup LXD molecule module + if: ${{ env.MOLECULE_IS_PRESENT && inputs.molecule-driver == 'lxd' }} + run: | + pip3 install --no-cache-dir molecule-lxd +# enable and fix issues as separate PR +# - name: Run lint +# run: | +# set -e +# yamllint . +# ansible-lint +# working-directory: "${{ github.repository }}/roles/${{ inputs.role-name }}" - name: Run molecule tests + if: ${{ env.MOLECULE_IS_PRESENT }} run: molecule test --all working-directory: "${{ github.repository }}/roles/${{ inputs.role-name }}" diff --git a/galaxy.yml b/galaxy.yml index 1cf083a..9dd2553 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -8,7 +8,7 @@ namespace: paritytech name: chain # The version of the collection. Must be compatible with semantic versioning -version: 1.6.1 +version: 1.7.0 # The path to the Markdown (.md) readme file. This path is relative to the root of the collection readme: README.md diff --git a/roles/key_inject/README.md b/roles/key_inject/README.md index 2672394..28777a2 100644 --- a/roles/key_inject/README.md +++ b/roles/key_inject/README.md @@ -1 +1,2 @@ # key_inject ansible role + diff --git a/roles/nginx/.yamllint b/roles/nginx/.yamllint new file mode 100644 index 0000000..8827676 --- /dev/null +++ b/roles/nginx/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/roles/nginx/README.md b/roles/nginx/README.md new file mode 100644 index 0000000..ad8ad78 --- /dev/null +++ b/roles/nginx/README.md @@ -0,0 +1 @@ +# nginx ansible role diff --git a/roles/nginx/defaults/main.yml b/roles/nginx/defaults/main.yml new file mode 100644 index 0000000..0e1572f --- /dev/null +++ b/roles/nginx/defaults/main.yml @@ -0,0 +1,50 @@ +nginx_letsencrypt_email: "devops-team@parity.io" +nginx_letsencrypt_mock: false +nginx_dhparam_size: 4096 +nginx_worker_rlimit_nofile: 30000 +# requests per second +nginx_max_request_rate: 2 +nginx_burst_request_rate: 5 + + +# print extended data about clients +nginx_log_extended_enable: false + +nginx_http_context_directives: [] +# - "server_names_hash_bucket_size 128" + +# flow +## Remove nginx, letsencrypt. Wipe all configs and , certificates. +nginx_remove_enable: false + +# 'nginx_sites': +## - 'template' - a name of a site template file, including '.j2'. +## - 'domain' - a real domain name as is, without placeholders etc. +## - 'ssl_issuer' - defines how TLS certificates are managed. Can be 'manual' or 'letsencrypt'. +## - 'ssl_manual_cert_file' - it must be specified if 'ssl_issuer'='manual'. +## It defines the name of a custom certificate file. +## Custom certificates have to be stored in the 'files' directories on the role or playbook levels. +## But it's better to store them on the playbook level. +## - 'params' - optional. But, it must be specified if the template of the site uses any custom variables inside. +## The dictionary contains user variables that are used in site templates. +## +## 'template', 'domain', 'ssl_manual_cert_file' variables can have the same values +## in more than one item of the 'nginx_sites' list, the role can manage it. +## But, a pair of 'template' and 'domain' variables must be unique for each item of the list. + +#nginx_sites: +# - template: site-rpc.j2 +# domain: "a.r-test-2.parity-lab.parity.io" +# ssl_issuer: letsencrypt +# params: +# rpc_port: 9933 +# rpc_ws_port: 9944 +# no_host_external_port: 8081 # it accepts any host in headers. It's useful for health checks. +# - template: site-rpc.j2 +# domain: "b.r-test-2.parity-lab.parity.io" +# ssl_issuer: letsencrypt +# params: {} +# - template: site-connect.j2 +# domain: "c.r-test-2.parity-lab.parity.io" +# ssl_issuer: manual +# ssl_manual_cert_file: "ws.polkadot.io.pem" diff --git a/roles/nginx/files/reload-nginx-config b/roles/nginx/files/reload-nginx-config new file mode 100755 index 0000000..06b8cc5 --- /dev/null +++ b/roles/nginx/files/reload-nginx-config @@ -0,0 +1,2 @@ +#!/bin/bash +/bin/systemctl reload nginx diff --git a/roles/nginx/handlers/main.yml b/roles/nginx/handlers/main.yml new file mode 100644 index 0000000..e4dacf6 --- /dev/null +++ b/roles/nginx/handlers/main.yml @@ -0,0 +1,8 @@ +--- + +- name: reload nginx config + ansible.builtin.systemd: + name: "nginx" + state: reloaded + enabled: yes + daemon_reload: yes diff --git a/roles/nginx/molecule/default/README.md b/roles/nginx/molecule/default/README.md new file mode 100644 index 0000000..8ae68a1 --- /dev/null +++ b/roles/nginx/molecule/default/README.md @@ -0,0 +1,18 @@ +### Molecule +#### Docker +Test role with docker driver +```shell +molecule create +molecule converge +molecule verify +molecule destroy +``` + +#### LXD +Test role with LXD driver +```shell +DRIVER=lxd molecule create +DRIVER=lxd molecule converge +DRIVER=lxd molecule verify +DRIVER=lxd molecule destroy +``` diff --git a/roles/nginx/molecule/default/converge.yml b/roles/nginx/molecule/default/converge.yml new file mode 100644 index 0000000..be4cb18 --- /dev/null +++ b/roles/nginx/molecule/default/converge.yml @@ -0,0 +1,9 @@ +--- +- name: converge + hosts: all + tasks: + - name: converge | deploy nginx without wipe + ansible.builtin.include_role: + name: "nginx" + vars: + nginx_remove_enable: false diff --git a/roles/nginx/molecule/default/files/pebble/cert.pem b/roles/nginx/molecule/default/files/pebble/cert.pem new file mode 100644 index 0000000..2866a2b --- /dev/null +++ b/roles/nginx/molecule/default/files/pebble/cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDGzCCAgOgAwIBAgIIbEfayDFsBtwwDQYJKoZIhvcNAQELBQAwIDEeMBwGA1UE +AxMVbWluaWNhIHJvb3QgY2EgMjRlMmRiMCAXDTE3MTIwNjE5NDIxMFoYDzIxMDcx +MjA2MTk0MjEwWjAUMRIwEAYDVQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCbFMW3DXXdErvQf2lCZ0qz0DGEWadDoF0O2neM5mVa +VQ7QGW0xc5Qwvn3Tl62C0JtwLpF0pG2BICIN+DHdVaIUwkf77iBS2doH1I3waE1I +8GkV9JrYmFY+j0dA1SwBmqUZNXhLNwZGq1a91nFSI59DZNy/JciqxoPX2K++ojU2 +FPpuXe2t51NmXMsszpa+TDqF/IeskA9A/ws6UIh4Mzhghx7oay2/qqj2IIPjAmJj +i73kdUvtEry3wmlkBvtVH50+FscS9WmPC5h3lDTk5nbzSAXKuFusotuqy3XTgY5B +PiRAwkZbEY43JNfqenQPHo7mNTt29i+NVVrBsnAa5ovrAgMBAAGjYzBhMA4GA1Ud +DwEB/wQEAwIFoDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0T +AQH/BAIwADAiBgNVHREEGzAZgglsb2NhbGhvc3SCBnBlYmJsZYcEfwAAATANBgkq +hkiG9w0BAQsFAAOCAQEAYIkXff8H28KS0KyLHtbbSOGU4sujHHVwiVXSATACsNAE +D0Qa8hdtTQ6AUqA6/n8/u1tk0O4rPE/cTpsM3IJFX9S3rZMRsguBP7BSr1Lq/XAB +7JP/CNHt+Z9aKCKcg11wIX9/B9F7pyKM3TdKgOpqXGV6TMuLjg5PlYWI/07lVGFW +/mSJDRs8bSCFmbRtEqc4lpwlrpz+kTTnX6G7JDLfLWYw/xXVqwFfdengcDTHCc8K +wtgGq/Gu6vcoBxIO3jaca+OIkMfxxXmGrcNdseuUCa3RMZ8Qy03DqGu6Y6XQyK4B +W8zIG6H9SVKkAznM2yfYhW8v2ktcaZ95/OBHY97ZIw== +-----END CERTIFICATE----- diff --git a/roles/nginx/molecule/default/files/pebble/key.pem b/roles/nginx/molecule/default/files/pebble/key.pem new file mode 100644 index 0000000..66be6da --- /dev/null +++ b/roles/nginx/molecule/default/files/pebble/key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAmxTFtw113RK70H9pQmdKs9AxhFmnQ6BdDtp3jOZlWlUO0Blt +MXOUML5905etgtCbcC6RdKRtgSAiDfgx3VWiFMJH++4gUtnaB9SN8GhNSPBpFfSa +2JhWPo9HQNUsAZqlGTV4SzcGRqtWvdZxUiOfQ2TcvyXIqsaD19ivvqI1NhT6bl3t +redTZlzLLM6Wvkw6hfyHrJAPQP8LOlCIeDM4YIce6Gstv6qo9iCD4wJiY4u95HVL +7RK8t8JpZAb7VR+dPhbHEvVpjwuYd5Q05OZ280gFyrhbrKLbqst104GOQT4kQMJG +WxGONyTX6np0Dx6O5jU7dvYvjVVawbJwGuaL6wIDAQABAoIBAGW9W/S6lO+DIcoo +PHL+9sg+tq2gb5ZzN3nOI45BfI6lrMEjXTqLG9ZasovFP2TJ3J/dPTnrwZdr8Et/ +357YViwORVFnKLeSCnMGpFPq6YEHj7mCrq+YSURjlRhYgbVPsi52oMOfhrOIJrEG +ZXPAwPRi0Ftqu1omQEqz8qA7JHOkjB2p0i2Xc/uOSJccCmUDMlksRYz8zFe8wHuD +XvUL2k23n2pBZ6wiez6Xjr0wUQ4ESI02x7PmYgA3aqF2Q6ECDwHhjVeQmAuypMF6 +IaTjIJkWdZCW96pPaK1t+5nTNZ+Mg7tpJ/PRE4BkJvqcfHEOOl6wAE8gSk5uVApY +ZRKGmGkCgYEAzF9iRXYo7A/UphL11bR0gqxB6qnQl54iLhqS/E6CVNcmwJ2d9pF8 +5HTfSo1/lOXT3hGV8gizN2S5RmWBrc9HBZ+dNrVo7FYeeBiHu+opbX1X/C1HC0m1 +wJNsyoXeqD1OFc1WbDpHz5iv4IOXzYdOdKiYEcTv5JkqE7jomqBLQk8CgYEAwkG/ +rnwr4ThUo/DG5oH+l0LVnHkrJY+BUSI33g3eQ3eM0MSbfJXGT7snh5puJW0oXP7Z +Gw88nK3Vnz2nTPesiwtO2OkUVgrIgWryIvKHaqrYnapZHuM+io30jbZOVaVTMR9c +X/7/d5/evwXuP7p2DIdZKQKKFgROm1XnhNqVgaUCgYBD/ogHbCR5RVsOVciMbRlG +UGEt3YmUp/vfMuAsKUKbT2mJM+dWHVlb+LZBa4pC06QFgfxNJi/aAhzSGvtmBEww +xsXbaceauZwxgJfIIUPfNZCMSdQVIVTi2Smcx6UofBz6i/Jw14MEwlvhamaa7qVf +kqflYYwelga1wRNCPopLaQKBgQCWsZqZKQqBNMm0Q9yIhN+TR+2d7QFjqeePoRPl +1qxNejhq25ojE607vNv1ff9kWUGuoqSZMUC76r6FQba/JoNbefI4otd7x/GzM9uS +8MHMJazU4okwROkHYwgLxxkNp6rZuJJYheB4VDTfyyH/ng5lubmY7rdgTQcNyZ5I +majRYQKBgAMKJ3RlII0qvAfNFZr4Y2bNIq+60Z+Qu2W5xokIHCFNly3W1XDDKGFe +CCPHSvQljinke3P9gPt2HVdXxcnku9VkTti+JygxuLkVg7E0/SWwrWfGsaMJs+84 +fK+mTZay2d3v24r9WKEKwLykngYPyZw5+BdWU0E+xx5lGUd3U4gG +-----END RSA PRIVATE KEY----- diff --git a/roles/nginx/molecule/default/files/test1.pem b/roles/nginx/molecule/default/files/test1.pem new file mode 100644 index 0000000..2a4ef42 --- /dev/null +++ b/roles/nginx/molecule/default/files/test1.pem @@ -0,0 +1,55 @@ +-----BEGIN CERTIFICATE----- +MIIEWjCCA7ugAwIBAgIUFi6dt6Ljwt7usmsFraZQkHbBR+4wCgYIKoZIzj0EAwIw +XTELMAkGA1UEBhMCRVUxDTALBgNVBAgMBFRFU1QxDTALBgNVBAcMBFRFU1QxDTAL +BgNVBAoMBFRFU1QxDTALBgNVBAsMBFRFU1QxEjAQBgNVBAMMCSoucnBjLmxhbjAe +Fw0yMjA0MjUxODExMzZaFw0zMjA0MjIxODExMzZaMF0xCzAJBgNVBAYTAkVVMQ0w +CwYDVQQIDARURVNUMQ0wCwYDVQQHDARURVNUMQ0wCwYDVQQKDARURVNUMQ0wCwYD +VQQLDARURVNUMRIwEAYDVQQDDAkqLnJwYy5sYW4wggJdMIIB0AYHKoZIzj0CATCC +AcMCAQEwTQYHKoZIzj0BAQJCAf////////////////////////////////////// +////////////////////////////////////////////////MIGfBEIB//////// +//////////////////////////////////////////////////////////////// +//////////////wEQgBRlT65YY4cmh+SmiGgtoVA7qLacluZsxXzuLSJkY7xCeFW +GTlR7H6TexZSwL07sb8HNXPfiD0sNPHvRR/Ua1A/AAMVANCeiAApHLhTlsxnFzky +hKqg2mS6BIGFBADGhY4GtwQE6c2ePstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS153 +7+dZKP4dwSei/6jeM0izwYVqQpv5fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1 +RElXm0RoF6+9Fyc+ZiyX7nKZXvQmQMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJC +Af//////////////////////////////////////////+lGGh4O/L5Zrf8wBSPcJ +pdA7tcm4iZxHrrtvtx6ROGQJAgEBA4GGAAQBexiUvRext+wPweeabtxEBGRhrUHY +AVVOVGJNZajY4cs1fFj6ibC7hRDx/zoe1K8/8JfPjIErpGGUDddwDPGO9BsAaxnw +9Zjsqcg7eVZ80FCcV7NkidCWowW+2vNGJVz+H7Uvni/nP8EV/rirPkikJ7GLZo+i +2GFlbyd5aiXjpXmiuBejUzBRMB0GA1UdDgQWBBTDRA1ZGMG/Mug+UA/FpXbxKhIt ++TAfBgNVHSMEGDAWgBTDRA1ZGMG/Mug+UA/FpXbxKhIt+TAPBgNVHRMBAf8EBTAD +AQH/MAoGCCqGSM49BAMCA4GMADCBiAJCARjvVk6dGYDkBNzwyGOOP9MzWnsNgaDg +HPnpBFMM5Ut/P/P9ApWcc4HDOv+zp22KkgVfoIyF1J3S6djA/3qHMV5XAkIBjlfr +LznARSA19eeU69LHSd4+kfZ/45eE48bfC/pxkgmRMdIFqb5r72z5quj/W/SM4F8s +l3LHQFWzwMex/DVwU/I= +-----END CERTIFICATE----- +-----BEGIN EC PARAMETERS----- +MIIBwwIBATBNBgcqhkjOPQEBAkIB//////////////////////////////////// +//////////////////////////////////////////////////8wgZ8EQgH///// +//////////////////////////////////////////////////////////////// +/////////////////ARCAFGVPrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ +4VYZOVHsfpN7FlLAvTuxvwc1c9+IPSw08e9FH9RrUD8AAxUA0J6IACkcuFOWzGcX +OTKEqqDaZLoEgYUEAMaFjga3BATpzZ4+y2YjlbRCnGSBOQU/tSH4KK9ga009uqFL +Xnfv51ko/h3BJ6L/qN4zSLPBhWpCm/l+fjHC5b1mARg5KWp4mjvABFyKX7QsfRvZ +mPVESVebRGgXr70XJz5mLJfucple9CZAxVC5AT+tB2E1PHCGonLCQIi+lHaf0WZQ +AkIB///////////////////////////////////////////6UYaHg78vlmt/zAFI +9wml0Du1ybiJnEeuu2+3HpE4ZAkCAQE= +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIICngIBAQRCAdg/rpMq12SkpeFecWlMaOjp1Xrd7TKCyHyrz5m5W7MEDowo80h3 +wBFdrCtauwzSz6UBzBvk4QMdaAhVlCngel/woIIBxzCCAcMCAQEwTQYHKoZIzj0B +AQJCAf////////////////////////////////////////////////////////// +////////////////////////////MIGfBEIB//////////////////////////// +//////////////////////////////////////////////////////////wEQgBR +lT65YY4cmh+SmiGgtoVA7qLacluZsxXzuLSJkY7xCeFWGTlR7H6TexZSwL07sb8H +NXPfiD0sNPHvRR/Ua1A/AAMVANCeiAApHLhTlsxnFzkyhKqg2mS6BIGFBADGhY4G +twQE6c2ePstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS1537+dZKP4dwSei/6jeM0iz +wYVqQpv5fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1RElXm0RoF6+9Fyc+ZiyX +7nKZXvQmQMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJCAf////////////////// +////////////////////////+lGGh4O/L5Zrf8wBSPcJpdA7tcm4iZxHrrtvtx6R +OGQJAgEBoYGJA4GGAAQBexiUvRext+wPweeabtxEBGRhrUHYAVVOVGJNZajY4cs1 +fFj6ibC7hRDx/zoe1K8/8JfPjIErpGGUDddwDPGO9BsAaxnw9Zjsqcg7eVZ80FCc +V7NkidCWowW+2vNGJVz+H7Uvni/nP8EV/rirPkikJ7GLZo+i2GFlbyd5aiXjpXmi +uBc= +-----END EC PRIVATE KEY----- \ No newline at end of file diff --git a/roles/nginx/molecule/default/files/test2.pem b/roles/nginx/molecule/default/files/test2.pem new file mode 100644 index 0000000..2a4ef42 --- /dev/null +++ b/roles/nginx/molecule/default/files/test2.pem @@ -0,0 +1,55 @@ +-----BEGIN CERTIFICATE----- +MIIEWjCCA7ugAwIBAgIUFi6dt6Ljwt7usmsFraZQkHbBR+4wCgYIKoZIzj0EAwIw +XTELMAkGA1UEBhMCRVUxDTALBgNVBAgMBFRFU1QxDTALBgNVBAcMBFRFU1QxDTAL +BgNVBAoMBFRFU1QxDTALBgNVBAsMBFRFU1QxEjAQBgNVBAMMCSoucnBjLmxhbjAe +Fw0yMjA0MjUxODExMzZaFw0zMjA0MjIxODExMzZaMF0xCzAJBgNVBAYTAkVVMQ0w +CwYDVQQIDARURVNUMQ0wCwYDVQQHDARURVNUMQ0wCwYDVQQKDARURVNUMQ0wCwYD +VQQLDARURVNUMRIwEAYDVQQDDAkqLnJwYy5sYW4wggJdMIIB0AYHKoZIzj0CATCC +AcMCAQEwTQYHKoZIzj0BAQJCAf////////////////////////////////////// +////////////////////////////////////////////////MIGfBEIB//////// +//////////////////////////////////////////////////////////////// +//////////////wEQgBRlT65YY4cmh+SmiGgtoVA7qLacluZsxXzuLSJkY7xCeFW +GTlR7H6TexZSwL07sb8HNXPfiD0sNPHvRR/Ua1A/AAMVANCeiAApHLhTlsxnFzky +hKqg2mS6BIGFBADGhY4GtwQE6c2ePstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS153 +7+dZKP4dwSei/6jeM0izwYVqQpv5fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1 +RElXm0RoF6+9Fyc+ZiyX7nKZXvQmQMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJC +Af//////////////////////////////////////////+lGGh4O/L5Zrf8wBSPcJ +pdA7tcm4iZxHrrtvtx6ROGQJAgEBA4GGAAQBexiUvRext+wPweeabtxEBGRhrUHY +AVVOVGJNZajY4cs1fFj6ibC7hRDx/zoe1K8/8JfPjIErpGGUDddwDPGO9BsAaxnw +9Zjsqcg7eVZ80FCcV7NkidCWowW+2vNGJVz+H7Uvni/nP8EV/rirPkikJ7GLZo+i +2GFlbyd5aiXjpXmiuBejUzBRMB0GA1UdDgQWBBTDRA1ZGMG/Mug+UA/FpXbxKhIt ++TAfBgNVHSMEGDAWgBTDRA1ZGMG/Mug+UA/FpXbxKhIt+TAPBgNVHRMBAf8EBTAD +AQH/MAoGCCqGSM49BAMCA4GMADCBiAJCARjvVk6dGYDkBNzwyGOOP9MzWnsNgaDg +HPnpBFMM5Ut/P/P9ApWcc4HDOv+zp22KkgVfoIyF1J3S6djA/3qHMV5XAkIBjlfr +LznARSA19eeU69LHSd4+kfZ/45eE48bfC/pxkgmRMdIFqb5r72z5quj/W/SM4F8s +l3LHQFWzwMex/DVwU/I= +-----END CERTIFICATE----- +-----BEGIN EC PARAMETERS----- +MIIBwwIBATBNBgcqhkjOPQEBAkIB//////////////////////////////////// +//////////////////////////////////////////////////8wgZ8EQgH///// +//////////////////////////////////////////////////////////////// +/////////////////ARCAFGVPrlhjhyaH5KaIaC2hUDuotpyW5mzFfO4tImRjvEJ +4VYZOVHsfpN7FlLAvTuxvwc1c9+IPSw08e9FH9RrUD8AAxUA0J6IACkcuFOWzGcX +OTKEqqDaZLoEgYUEAMaFjga3BATpzZ4+y2YjlbRCnGSBOQU/tSH4KK9ga009uqFL +Xnfv51ko/h3BJ6L/qN4zSLPBhWpCm/l+fjHC5b1mARg5KWp4mjvABFyKX7QsfRvZ +mPVESVebRGgXr70XJz5mLJfucple9CZAxVC5AT+tB2E1PHCGonLCQIi+lHaf0WZQ +AkIB///////////////////////////////////////////6UYaHg78vlmt/zAFI +9wml0Du1ybiJnEeuu2+3HpE4ZAkCAQE= +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MIICngIBAQRCAdg/rpMq12SkpeFecWlMaOjp1Xrd7TKCyHyrz5m5W7MEDowo80h3 +wBFdrCtauwzSz6UBzBvk4QMdaAhVlCngel/woIIBxzCCAcMCAQEwTQYHKoZIzj0B +AQJCAf////////////////////////////////////////////////////////// +////////////////////////////MIGfBEIB//////////////////////////// +//////////////////////////////////////////////////////////wEQgBR +lT65YY4cmh+SmiGgtoVA7qLacluZsxXzuLSJkY7xCeFWGTlR7H6TexZSwL07sb8H +NXPfiD0sNPHvRR/Ua1A/AAMVANCeiAApHLhTlsxnFzkyhKqg2mS6BIGFBADGhY4G +twQE6c2ePstmI5W0QpxkgTkFP7Uh+CivYGtNPbqhS1537+dZKP4dwSei/6jeM0iz +wYVqQpv5fn4xwuW9ZgEYOSlqeJo7wARcil+0LH0b2Zj1RElXm0RoF6+9Fyc+ZiyX +7nKZXvQmQMVQuQE/rQdhNTxwhqJywkCIvpR2n9FmUAJCAf////////////////// +////////////////////////+lGGh4O/L5Zrf8wBSPcJpdA7tcm4iZxHrrtvtx6R +OGQJAgEBoYGJA4GGAAQBexiUvRext+wPweeabtxEBGRhrUHYAVVOVGJNZajY4cs1 +fFj6ibC7hRDx/zoe1K8/8JfPjIErpGGUDddwDPGO9BsAaxnw9Zjsqcg7eVZ80FCc +V7NkidCWowW+2vNGJVz+H7Uvni/nP8EV/rirPkikJ7GLZo+i2GFlbyd5aiXjpXmi +uBc= +-----END EC PRIVATE KEY----- \ No newline at end of file diff --git a/roles/nginx/molecule/default/group_vars/all.yml b/roles/nginx/molecule/default/group_vars/all.yml new file mode 100644 index 0000000..7235298 --- /dev/null +++ b/roles/nginx/molecule/default/group_vars/all.yml @@ -0,0 +1,30 @@ +## Molecule +ansible_user: root + +nginx_letsencrypt_mock: true +nginx_dhparam_size: 1024 +nginx_sites: + - template: site-rpc.j2 + domain: "a.rpc.lan" + ssl_issuer: letsencrypt + params: + rpc_port: 9933 + rpc_ws_port: 9944 + - template: site-rpc.j2 + domain: "b.rpc.lan" + ssl_issuer: manual + ssl_manual_cert_file: "test1.pem" + params: + rpc_port: 9933 + rpc_ws_port: 9944 + - template: site-connect.j2 + domain: "c.rpc.lan" + ssl_issuer: letsencrypt + params: + connect_port: 9944 + - template: site-connect.j2 + domain: "d.rpc.lan" + ssl_issuer: manual + ssl_manual_cert_file: "test2.pem" + params: + connect_port: 9944 diff --git a/roles/nginx/molecule/default/molecule.yml b/roles/nginx/molecule/default/molecule.yml new file mode 100644 index 0000000..85b0b38 --- /dev/null +++ b/roles/nginx/molecule/default/molecule.yml @@ -0,0 +1,34 @@ +--- +dependency: + name: galaxy +driver: + name: ${DRIVER:-docker} +platforms: + - name: molecule-instance-nginx + # LXD + source: + alias: debian/bullseye/amd64 + # DOCKER + image: "paritytech/debian11:latest" + command: ${MOLECULE_DOCKER_COMMAND:-""} + # need this for systemctl to work in Docker + privileged: true + # to pull image from docker hub uncomment this + pre_build_image: true + etc_hosts: + 'a.rpc.lan': '127.0.0.1' + 'b.rpc.lan': '127.0.0.1' + 'c.rpc.lan': '127.0.0.1' + 'd.rpc.lan': '127.0.0.1' + +provisioner: + name: ansible + options: + D: True + config_options: + defaults: + callbacks_enabled: timer +verifier: + name: ansible + options: + D: True diff --git a/roles/nginx/molecule/default/prepare.yml b/roles/nginx/molecule/default/prepare.yml new file mode 100644 index 0000000..87db92e --- /dev/null +++ b/roles/nginx/molecule/default/prepare.yml @@ -0,0 +1,95 @@ +- name: prepare + hosts: all + gather_facts: false + pre_tasks: + - name: prepare | install Python3 + ansible.builtin.raw: apt -y update && apt install -y python3 + changed_when: false + vars: + websocat_dist_binary: "https://github.com/vi/websocat/releases/download/v1.9.0/websocat_linux64" + websocat_binary: "/usr/local/bin/websocat" + pebble_dist_binary: "https://github.com/letsencrypt/pebble/releases/download/v2.3.1/pebble_linux-amd64" + pebble_binary: "/usr/local/bin/pebble" + pebble_conf_dir: "/usr/local/etc/pebble/" + tasks: + - name: prepare | install packeges + ansible.builtin.apt: + name: "{{ packeges }}" + state: present + update_cache: no + vars: + packeges: + - ca-certificates + - bash + - netcat-openbsd + - name: prepare | build hosts file + ansible.builtin.lineinfile: + dest: "/etc/hosts" + line: "127.0.0.1 {{ item.domain }}" + state: present + loop: "{{ nginx_sites }}" + when: molecule_yml.driver.name == 'lxd' + # websocat provides mock for WebSocket + - name: prepare | download websocat binary + ansible.builtin.get_url: + url: "{{ websocat_dist_binary }}" + dest: "{{ websocat_binary }}" + mode: 0755 + owner: "root" + group: "root" + # pebble provides mock for ACME (letsencrypt) + - name: prepare | create pebble config directory + ansible.builtin.file: + name: "{{ pebble_conf_dir }}" + state: directory + owner: root + group: root + mode: "0755" + - name: prepare | download pebble binary + ansible.builtin.get_url: + url: "{{ pebble_dist_binary }}" + dest: "{{ pebble_binary }}" + mode: 0755 + owner: "root" + group: "root" + - name: prepare | copy pebble config files + ansible.builtin.copy: + src: "{{ item.src }}" + dest: "{{ item.dst }}" + owner: root + group: root + mode: "0644" + loop: + - {src: "pebble/cert.pem", dst: "{{ pebble_conf_dir }}"} # fake 127.0.0.1 certificate + - {src: "pebble/key.pem", dst: "{{ pebble_conf_dir }}"} # fake 127.0.0.1 certificate + - name: prepare | copy config templates + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ item.dst }}" + owner: root + group: root + mode: "0644" + loop: + - {src: "pebble.service.j2", dst: "/etc/systemd/system/pebble.service"} + - {src: "pebble-config.json.j2", dst: "{{ pebble_conf_dir }}pebble-config.json"} + - {src: "websocat.service.j2", dst: "/etc/systemd/system/websocat.service"} + - {src: "http-stub.service.j2", dst: "/etc/systemd/system/http-stub.service"} + - name: prepare | run services + ansible.builtin.systemd: + name: "{{ item }}" + state: started + enabled: true + daemon_reload: true + loop: + - "pebble.service" + - "http-stub.service" + - "websocat.service" + - name: prepare | collect service facts + ansible.builtin.service_facts: + - name: prepare | check services + ansible.builtin.assert: + that: ansible_facts.services[item].state == 'running' + loop: + - "pebble.service" + - "http-stub.service" + - "websocat.service" diff --git a/roles/nginx/molecule/default/templates/http-stub.service.j2 b/roles/nginx/molecule/default/templates/http-stub.service.j2 new file mode 100644 index 0000000..b49c5c6 --- /dev/null +++ b/roles/nginx/molecule/default/templates/http-stub.service.j2 @@ -0,0 +1,10 @@ +[Unit] +Description=websocat systemd service + +[Service] +ExecStart=/usr/bin/python3 -m http.server 9933 + +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/roles/nginx/molecule/default/templates/pebble-config.json.j2 b/roles/nginx/molecule/default/templates/pebble-config.json.j2 new file mode 100644 index 0000000..e0e7fce --- /dev/null +++ b/roles/nginx/molecule/default/templates/pebble-config.json.j2 @@ -0,0 +1,12 @@ +{ + "pebble": { + "listenAddress": "127.0.0.1:14000", + "managementListenAddress": "127.0.0.1:15000", + "certificate": "{{ pebble_conf_dir }}cert.pem", + "privateKey": "{{ pebble_conf_dir }}key.pem", + "httpPort": 80, + "tlsPort": 443, + "ocspResponderURL": "", + "externalAccountBindingRequired": false + } +} diff --git a/roles/nginx/molecule/default/templates/pebble.service.j2 b/roles/nginx/molecule/default/templates/pebble.service.j2 new file mode 100644 index 0000000..015c136 --- /dev/null +++ b/roles/nginx/molecule/default/templates/pebble.service.j2 @@ -0,0 +1,10 @@ +[Unit] +Description=pebble systemd service + +[Service] +Environment="PEBBLE_WFE_NONCEREJECT=20" +ExecStart={{ pebble_binary }} -config {{ pebble_conf_dir }}pebble-config.json +Restart=always + +[Install] +WantedBy=multi-user.target diff --git a/roles/nginx/molecule/default/templates/websocat.service.j2 b/roles/nginx/molecule/default/templates/websocat.service.j2 new file mode 100644 index 0000000..ae05b0f --- /dev/null +++ b/roles/nginx/molecule/default/templates/websocat.service.j2 @@ -0,0 +1,11 @@ +[Unit] +Description=websocat systemd service + +[Service] +ExecStart={{ websocat_binary }} --oneshot -b ws-l:127.0.0.1:9944 tcp:127.0.0.1:9933 +Restart=always +Wants=netcat.service +After=netcat.service + +[Install] +WantedBy=multi-user.target diff --git a/roles/nginx/molecule/default/verify.yml b/roles/nginx/molecule/default/verify.yml new file mode 100644 index 0000000..f7ab861 --- /dev/null +++ b/roles/nginx/molecule/default/verify.yml @@ -0,0 +1,20 @@ +--- +- name: verify + hosts: all + gather_facts: false + tasks: + - name: verify | deploy nginx with wipe + ansible.builtin.include_role: + name: "nginx" + vars: + nginx_remove_enable: true + - name: verify | check https RPC endpoints + ansible.builtin.uri: + url: "https://{{ item.domain }}" + validate_certs: no + loop: "{{ nginx_sites }}" + when: item.template == 'site-rpc.j2' + - name: verify | check wss RPC endpoints + ansible.builtin.command: "websocat --insecure -E wss:///{{ item.domain }}" + changed_when: False + loop: "{{ nginx_sites }}" diff --git a/roles/nginx/tasks/certs-loop.yml b/roles/nginx/tasks/certs-loop.yml new file mode 100644 index 0000000..49abf83 --- /dev/null +++ b/roles/nginx/tasks/certs-loop.yml @@ -0,0 +1,12 @@ +--- + +- block: + + - name: nginx | certs | copy {{ item }} + ansible.builtin.copy: + src: "{{ item }}" + dest: "{{ _nginx_custom_certs_base_path }}{{ item }}" + owner: root + group: root + mode: "0600" + notify: reload nginx config diff --git a/roles/nginx/tasks/certs.yml b/roles/nginx/tasks/certs.yml new file mode 100644 index 0000000..ea8b9eb --- /dev/null +++ b/roles/nginx/tasks/certs.yml @@ -0,0 +1,47 @@ +--- + +- name: nginx | certs | calculate list of custom certs + ansible.builtin.set_fact: + _nginx_custom_certs: "{{ nginx_sites | json_query(pattern) | map(attribute='ssl_manual_cert_file') | unique }}" + vars: + pattern: "[?ssl_issuer==`manual`]" + +- name: nginx | certs | print list of custom certs + ansible.builtin.debug: + var: _nginx_custom_certs + +- name: nginx | certs | manage cert directory + ansible.builtin.file: + name: "{{ _nginx_custom_certs_base_path }}" + state: "{% if _nginx_custom_certs | length > 0 %}directory{% else %}absent{% endif %}" + owner: root + group: root + mode: "0755" + +- block: + + - name: nginx | certs | find unmanaged custom certs files + ansible.builtin.find: + paths: "{{ _nginx_custom_certs_base_path }}" + patterns: "^((?!{{ _nginx_custom_certs | join('|') }}).)*$" + use_regex: true + register: _nginx_unmanaged_custom_certs_files + + - name: nginx | certs | print list of unmanaged custom certs files + ansible.builtin.debug: + msg: "{{ _nginx_unmanaged_custom_certs_files.files | map(attribute='path') }}" + + - name: nginx | certs | remove unmanaged custom certs files + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + loop: "{{ _nginx_unmanaged_custom_certs_files.files }}" + + when: _nginx_custom_certs | length > 0 + +- name: nginx | certs | include tasks of sorts copying + ansible.builtin.include_tasks: + file: certs-loop.yml + apply: + tags: ['nginx', 'nginx-custom-certs'] + loop: "{{ _nginx_custom_certs }}" diff --git a/roles/nginx/tasks/letsencrypt-loop.yml b/roles/nginx/tasks/letsencrypt-loop.yml new file mode 100644 index 0000000..6657dcc --- /dev/null +++ b/roles/nginx/tasks/letsencrypt-loop.yml @@ -0,0 +1,25 @@ +--- + +- name: nginx | letsencrypt | domain - {{ item }} | setup letsencrypt cmd + ansible.builtin.set_fact: + _nginx_letsencrypt_cmd: "certbot certonly --webroot -w /var/www/letsencrypt -d {{ item }} -n \ + -m {{ nginx_letsencrypt_email }} --agree-tos \ + {%- if ansible_check_mode %} --dry-run{% endif %} \ + {%- if nginx_letsencrypt_mock %} --server https://127.0.0.1:14000/dir --no-verify-ssl{%- endif %}" + +- name: nginx | letsencrypt | domain - {{ item }} | print letsencrypt cmd + ansible.builtin.debug: + var: _nginx_letsencrypt_cmd + +- name: nginx | letsencrypt | domain - {{ item }} | create certificate + ansible.builtin.command: "{{ _nginx_letsencrypt_cmd }}" + register: _nginx_letsencrypt_register + until: _nginx_letsencrypt_register.rc is defined and _nginx_letsencrypt_register.rc == 0 + retries: 5 + delay: 10 + check_mode: false + changed_when: false + +- name: nginx | letsencrypt | domain - {{ item }} | print letsencrypt output + ansible.builtin.debug: + var: _nginx_letsencrypt_register.stdout diff --git a/roles/nginx/tasks/letsencrypt.yml b/roles/nginx/tasks/letsencrypt.yml new file mode 100644 index 0000000..e1d2029 --- /dev/null +++ b/roles/nginx/tasks/letsencrypt.yml @@ -0,0 +1,16 @@ +- name: nginx | letsencrypt | calculate list of letsencrypt domains + ansible.builtin.set_fact: + _nginx_letsencrypt_domains: "{{ nginx_sites | json_query(pattern) | map(attribute='domain') | unique }}" + vars: + pattern: "[?ssl_issuer==`letsencrypt`]" + +- name: nginx| letsencrypt | print list of letsencrypt domains + ansible.builtin.debug: + var: _nginx_letsencrypt_domains + +- name: nginx | letsencrypt | include issuing tasks of letsencrypt certs + ansible.builtin.include_tasks: + file: letsencrypt-loop.yml + apply: + tags: ['nginx', 'nginx-letsencrypt'] + loop: "{{ _nginx_letsencrypt_domains }}" diff --git a/roles/nginx/tasks/main.yml b/roles/nginx/tasks/main.yml new file mode 100644 index 0000000..28ce7fa --- /dev/null +++ b/roles/nginx/tasks/main.yml @@ -0,0 +1,123 @@ +--- + +- block: + + - name: nginx | include test tasks + ansible.builtin.include_tasks: + file: tests.yml + apply: + tags: ['nginx', 'nginx-tests'] + tags: ['nginx-tests'] + + - name: nginx | include remove tasks + ansible.builtin.include_tasks: + file: remove.yml + apply: + tags: ['nginx', 'nginx-remove'] + when: nginx_remove_enable | bool + tags: ['nginx-remove'] + + - name: nginx | install packeges + ansible.builtin.apt: + name: "{{ packeges }}" + state: present + update_cache: yes + vars: + packeges: + - nginx + - certbot + + - name: nginx | create directories + ansible.builtin.file: + name: "{{ item }}" + state: directory + owner: root + group: root + mode: "0755" + loop: + - "/var/www/letsencrypt" + - "/etc/letsencrypt/renewal-hooks/deploy" + - "/etc/systemd/system/nginx.service.d" + + - name: nginx | copy letsencrypt renewal-hook reload script + ansible.builtin.copy: + src: reload-nginx-config + dest: "/etc/letsencrypt/renewal-hooks/deploy" + owner: root + group: root + mode: "0744" + + - name: nginx | stat dhparams + ansible.builtin.stat: + path: /etc/nginx/dhparams.pem + register: stat_dhparams + + # The file is generated locally because it takes a LONG time to generate on VMs + - name: nginx | generate dhparams locally + become: no + community.crypto.openssl_dhparam: + path: /tmp/dhparams_{{ inventory_hostname }}.pem + size: "{{ nginx_dhparam_size }}" + delegate_to: localhost + when: not stat_dhparams.stat.exists + # molecule skip test + tags: molecule-notest + + - name: nginx | copy dhparams to node + ansible.builtin.copy: + src: /tmp/dhparams_{{ inventory_hostname }}.pem + dest: /etc/nginx/dhparams.pem + notify: reload nginx config + when: not stat_dhparams.stat.exists + # molecule skip test + tags: molecule-notest + + - name: nginx | copy config templates + ansible.builtin.template: + src: "{{ item.src }}" + dest: "{{ item.dst }}" + owner: "root" + group: "root" + mode: "0644" + notify: reload nginx config + loop: + - { src: "nginx.conf.j2", dst: "/etc/nginx/nginx.conf" } + - { src: "site-default.j2", dst: "/etc/nginx/sites-enabled/default" } + - { src: "override.conf.j2", dst: "/etc/systemd/system/nginx.service.d/override.conf" } + + - name: nginx | flush handlers + ansible.builtin.meta: flush_handlers + + - name: nginx | include custom certs tasks + ansible.builtin.include_tasks: + file: certs.yml + apply: + tags: ['nginx', 'nginx-custom-certs'] + tags: ['nginx-custom-certs'] + + - name: nginx | include letsencrypt tasks + ansible.builtin.include_tasks: + file: letsencrypt.yml + apply: + tags: ['nginx', 'nginx-letsencrypt'] + tags: ['nginx-letsencrypt'] + + - name: nginx | include site tasks + ansible.builtin.include_tasks: + file: sites.yml + apply: + tags: ['nginx', 'nginx-sites'] + tags: ['nginx-sites'] + + # to avoid 2 restarts during the first deploy + - name: nginx | flush handlers + ansible.builtin.meta: flush_handlers + + - name: nginx | start nginx + ansible.builtin.systemd: + name: "nginx" + state: started + enabled: yes + daemon_reload: yes + + tags: ['nginx'] diff --git a/roles/nginx/tasks/remove.yml b/roles/nginx/tasks/remove.yml new file mode 100644 index 0000000..55b8073 --- /dev/null +++ b/roles/nginx/tasks/remove.yml @@ -0,0 +1,28 @@ +--- + +- name: nginx | remove | stop nginx + ansible.builtin.systemd: + name: "nginx" + state: stopped + +- name: nginx | remove | remove packeges + ansible.builtin.apt: + name: "{{ packeges }}" + state: absent + purge: yes + vars: + packeges: + - nginx + - nginx-common + - nginx-full + - certbot + +- name: nginx | remove | remove directories + ansible.builtin.file: + name: "{{ item }}" + state: absent + loop: + - "/var/www/letsencrypt" + - "/etc/letsencrypt" + - "/etc/nginx" + - "/etc/systemd/system/nginx.service.d" diff --git a/roles/nginx/tasks/sites.yml b/roles/nginx/tasks/sites.yml new file mode 100644 index 0000000..7c1b323 --- /dev/null +++ b/roles/nginx/tasks/sites.yml @@ -0,0 +1,49 @@ +--- + +- name: nginx | sites | build the list of site configs 1 + ansible.builtin.set_fact: + _nginx_sites: [] + +- name: nginx | sites | build the list of site configs 2 + ansible.builtin.set_fact: + _nginx_sites: "{{ _nginx_sites + [ item | combine({'site_name': _nginx_site_name, + 'site_id': _nginx_site_id, + 'params': _nginx_site_params}, + recursive=True) ] }}" + vars: + _nginx_site_name: "{{ (item.template.split('.')[0] + '_' + item.domain) | regex_replace('[^0-9a-zA-Z]+', '_') }}" + _nginx_site_id: "{{ (_nginx_site_name | hash('sha1'))[:6] }}" + _nginx_site_params: "{{ item.params | default({}) }}" + loop: "{{ nginx_sites }}" + +- name: nginx | sites | print the list of site configs + ansible.builtin.debug: + msg: "{{ _nginx_sites }}" + +- name: nginx | sites | find unmanaged site config files + ansible.builtin.find: + paths: "/etc/nginx/sites-enabled" + patterns: "^((?!{{ _nginx_sites | map(attribute='site_name') | join('|') }}|default).)*$" + use_regex: true + register: _nginx_unmanaged_site_config_files + +- name: nginx | sites | print list of unmanaged site config files + ansible.builtin.debug: + msg: "{{ _nginx_unmanaged_site_config_files.files | map(attribute='path') }}" + +- name: nginx | sites | remove unmanaged site config files + ansible.builtin.file: + path: "{{ item.path }}" + state: absent + loop: "{{ _nginx_unmanaged_site_config_files.files }}" + notify: reload nginx config + +- name: nginx | sites | copy site configs + ansible.builtin.template: + src: "{{ item.template }}" + dest: "/etc/nginx/sites-enabled/{{ item.site_name }}" + owner: "root" + group: "root" + mode: "0644" + notify: reload nginx config + loop: "{{ _nginx_sites }}" diff --git a/roles/nginx/tasks/tests.yml b/roles/nginx/tasks/tests.yml new file mode 100644 index 0000000..9b905a6 --- /dev/null +++ b/roles/nginx/tasks/tests.yml @@ -0,0 +1,31 @@ +--- + +- name: nginx | tests | fail if the site isn't unique 1 + ansible.builtin.set_fact: + _nginx_revised_sites: [] + +- name: nginx | tests | fail if the site isn't unique 2 + ansible.builtin.set_fact: + _nginx_revised_sites: "{{ _nginx_revised_sites + [ 'template: ' + item.template + + ' domain: ' + item.domain ] }}" + loop: "{{ nginx_sites }}" + +- name: nginx | tests | fail if the site isn't unique 3 + ansible.builtin.fail: + msg: "{{ item }}. A pair of 'template' and 'domain' variables must be unique for each item of the 'nginx_sites' variable " + loop: "{{ _nginx_revised_sites | sort }}" + loop_control: + extended: yes + when: not ansible_loop.last and (item == ansible_loop.nextitem) + +- name: nginx | tests | check the ssl_issuer variable + ansible.builtin.fail: + msg: "The 'ssl_issuer' variable must be defined, it can contain only 'manual', 'letsencrypt' values!" + loop: "{{ nginx_sites }}" + when: item.ssl_issuer is not defined or item.ssl_issuer not in ['manual', 'letsencrypt'] + +- name: nginx | tests | check the ssl_manual_cert_file variable + ansible.builtin.fail: + msg: "The 'ssl_manual_cert_file' variable must be defined, if 'ssl_issuer' == 'manual'" + loop: "{{ nginx_sites }}" + when: item.ssl_issuer == 'manual' and item.ssl_manual_cert_file is not defined diff --git a/roles/nginx/templates/nginx.conf.j2 b/roles/nginx/templates/nginx.conf.j2 new file mode 100644 index 0000000..a964904 --- /dev/null +++ b/roles/nginx/templates/nginx.conf.j2 @@ -0,0 +1,42 @@ +user www-data; +worker_processes auto; +pid /run/nginx.pid; +include /etc/nginx/modules-enabled/*.conf; +worker_rlimit_nofile {{ nginx_worker_rlimit_nofile }}; + +events { + worker_connections 8000; + # multi_accept on; +} + +http { + limit_req_zone "$http_x_forwarded_for" zone=zone:10m rate={{ nginx_max_request_rate }}r/s; + limit_req_zone "$binary_remote_addr" zone=ipzone:10m rate={{ nginx_max_request_rate }}r/s; + sendfile on; + tcp_nopush on; + tcp_nodelay on; + keepalive_timeout 65; + types_hash_max_size 2048; + + include /etc/nginx/mime.types; + default_type application/octet-stream; + {% for directive in nginx_http_context_directives %} + {{ directive }}; + {% endfor %} + + {% if nginx_log_extended_enable %} +log_format main '$remote_addr - $http_x_forwarded_for - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent "$http_referer" ' '"$http_user_agent"'; + access_log /var/log/nginx/access.log main; + {% else %} +access_log /var/log/nginx/access.log; + {% endif %} + error_log /var/log/nginx/error.log; + + gzip on; + gzip_disable "msie6"; + + server_tokens off; + + include /etc/nginx/conf.d/*.conf; + include /etc/nginx/sites-enabled/*; +} diff --git a/roles/nginx/templates/override.conf.j2 b/roles/nginx/templates/override.conf.j2 new file mode 100644 index 0000000..3ed728a --- /dev/null +++ b/roles/nginx/templates/override.conf.j2 @@ -0,0 +1,2 @@ +[Service] +LimitNOFILE={{ nginx_worker_rlimit_nofile }} \ No newline at end of file diff --git a/roles/nginx/templates/site-connect.j2 b/roles/nginx/templates/site-connect.j2 new file mode 100644 index 0000000..537a7a9 --- /dev/null +++ b/roles/nginx/templates/site-connect.j2 @@ -0,0 +1,52 @@ +upstream websocket_{{ item.site_id }} { + server 127.0.0.1:{{ item.params.connect_port | default('30333') }}; +} + +map $http_upgrade $endpoint_{{ item.site_id }} { + default websocket_{{ item.site_id }}; + '' close; +} + + +server { + listen 443 ssl; + server_name {{ item.domain }}; +{% if item.ssl_issuer == 'letsencrypt' %} + ssl_certificate /etc/letsencrypt/live/{{ item.domain }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ item.domain }}/privkey.pem; +{% elif item.ssl_issuer == 'manual' %} + ssl_certificate {{ _nginx_custom_certs_base_path }}{{ item.ssl_manual_cert_file }}; + ssl_certificate_key {{ _nginx_custom_certs_base_path }}{{ item.ssl_manual_cert_file }}; +{% else %} + {{ "the ssl_issuer parameter must be defined."/0 }} +{% endif %} + + location / { + limit_req zone=ipzone burst={{ nginx_burst_request_rate }}; + proxy_buffers 16 4k; + proxy_buffer_size 2k; + proxy_pass http://$endpoint_{{ item.site_id }}; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } +} + +{% if item.params.no_host_external_port is defined %} +# we need it to execute the cloud host healthcheck, we can't use TLS there +server { + listen {{ item.params.no_host_external_port }}; + server_name _; + location / { + limit_req zone=ipzone burst={{ nginx_burst_request_rate }}; + proxy_buffers 16 4k; + proxy_buffer_size 2k; + proxy_pass http://$endpoint_{{ item.site_id }}; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } +} +{% endif %} diff --git a/roles/nginx/templates/site-default.j2 b/roles/nginx/templates/site-default.j2 new file mode 100644 index 0000000..d109746 --- /dev/null +++ b/roles/nginx/templates/site-default.j2 @@ -0,0 +1,20 @@ +server { + listen 80 default_server; + server_name _; + + location /.well-known/acme-challenge { + root /var/www/letsencrypt; + try_files $uri $uri/ =404; + } + + location / { + rewrite ^ https://$host$request_uri? permanent; + } +} + +server { + listen 8080; + location = /stub_status { + stub_status; + } +} diff --git a/roles/nginx/templates/site-rpc.j2 b/roles/nginx/templates/site-rpc.j2 new file mode 100644 index 0000000..f061c93 --- /dev/null +++ b/roles/nginx/templates/site-rpc.j2 @@ -0,0 +1,55 @@ +upstream rpc_{{ item.site_id }} { + server 127.0.0.1:{{ item.params.rpc_port | default('9944') }}; +} + +upstream ws_{{ item.site_id }} { + server 127.0.0.1:{{ item.params.rpc_ws_port | default('9944') }}; +} + +# map to different upstream backends based on header +map $http_upgrade $endpoint_{{ item.site_id }} { + default ws_{{ item.site_id }}; + '' rpc_{{ item.site_id }}; +} + +server { + listen 443 ssl; + server_name {{ item.domain }}; +{% if item.ssl_issuer == 'letsencrypt' %} + ssl_certificate /etc/letsencrypt/live/{{ item.domain }}/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/{{ item.domain }}/privkey.pem; +{% elif item.ssl_issuer == 'manual' %} + ssl_certificate {{ _nginx_custom_certs_base_path }}{{ item.ssl_manual_cert_file }}; + ssl_certificate_key {{ _nginx_custom_certs_base_path }}{{ item.ssl_manual_cert_file }}; +{% else %} + {{ "the ssl_issuer parameter must be defined."/0 }} +{% endif %} + location / { + limit_req zone=zone burst={{ nginx_burst_request_rate }}; + proxy_buffers 16 4k; + proxy_buffer_size 2k; + proxy_pass http://$endpoint_{{ item.site_id }}; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } +} + +{% if item.params.no_host_external_port is defined %} +# we need it to execute the cloud host healthcheck, we can't use TLS there +server { + listen {{ item.params.no_host_external_port }}; + server_name _; + location / { + limit_req zone=zone burst={{ nginx_burst_request_rate }}; + proxy_buffers 16 4k; + proxy_buffer_size 2k; + proxy_pass http://$endpoint_{{ item.site_id }}; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + } +} +{% endif %} diff --git a/roles/nginx/vars/main.yml b/roles/nginx/vars/main.yml new file mode 100644 index 0000000..a134bd2 --- /dev/null +++ b/roles/nginx/vars/main.yml @@ -0,0 +1,3 @@ +--- + +_nginx_custom_certs_base_path: "/etc/nginx/tls-certs/" diff --git a/roles/nginx_exporter/.yamllint b/roles/nginx_exporter/.yamllint new file mode 100644 index 0000000..8827676 --- /dev/null +++ b/roles/nginx_exporter/.yamllint @@ -0,0 +1,33 @@ +--- +# Based on ansible-lint config +extends: default + +rules: + braces: + max-spaces-inside: 1 + level: error + brackets: + max-spaces-inside: 1 + level: error + colons: + max-spaces-after: -1 + level: error + commas: + max-spaces-after: -1 + level: error + comments: disable + comments-indentation: disable + document-start: disable + empty-lines: + max: 3 + level: error + hyphens: + level: error + indentation: disable + key-duplicates: enable + line-length: disable + new-line-at-end-of-file: disable + new-lines: + type: unix + trailing-spaces: disable + truthy: disable diff --git a/roles/nginx_exporter/README.md b/roles/nginx_exporter/README.md new file mode 100644 index 0000000..c3f583a --- /dev/null +++ b/roles/nginx_exporter/README.md @@ -0,0 +1 @@ +# nginx_exporter ansible role diff --git a/roles/nginx_exporter/defaults/main.yml b/roles/nginx_exporter/defaults/main.yml new file mode 100644 index 0000000..a694ec0 --- /dev/null +++ b/roles/nginx_exporter/defaults/main.yml @@ -0,0 +1,6 @@ +--- + +nginx_exporter_name: "nginx-exporter" +nginx_exporter_user: "www-data" +nginx_exporter_binary: "https://github.com/nginxinc/nginx-prometheus-exporter/releases/download/v0.10.0/nginx-prometheus-exporter_0.10.0_linux_amd64.tar.gz" +nginx_metric_port: 8080 diff --git a/roles/nginx_exporter/handlers/main.yml b/roles/nginx_exporter/handlers/main.yml new file mode 100644 index 0000000..71caeca --- /dev/null +++ b/roles/nginx_exporter/handlers/main.yml @@ -0,0 +1,8 @@ +--- + +- name: Restart nginx-exporter + ansible.builtin.systemd: + name: "{{ nginx_exporter_name }}" + state: restarted + enabled: true + daemon_reload: true diff --git a/roles/nginx_exporter/tasks/main.yml b/roles/nginx_exporter/tasks/main.yml new file mode 100644 index 0000000..840d6a2 --- /dev/null +++ b/roles/nginx_exporter/tasks/main.yml @@ -0,0 +1,44 @@ +--- + +- name: Nginx exporter + tags: ["nginx-exporter"] + block: + + - name: Nginx exporter | download exporter + ansible.builtin.unarchive: + src: "{{ nginx_exporter_binary }}" + dest: "{{ _nginx_exporter_file | dirname }}" + remote_src: yes + owner: "root" + group: "root" + mode: 0644 + notify: Restart nginx-exporter + + - name: Nginx exporter | change permissions of binary + ansible.builtin.file: + path: "{{ _nginx_exporter_file }}" + owner: "root" + group: "root" + mode: 0755 + state: file + notify: Restart nginx-exporter + + - name: Nginx exporter | copy exporter systemd unit file + ansible.builtin.template: + src: ".service.j2" + dest: "/etc/systemd/system/{{ nginx_exporter_name }}.service" + owner: "root" + group: "root" + mode: "0600" + notify: Restart nginx-exporter + + # to avoid 2 restarts during the first deploy + - name: Nginx exporter | flush handlers + ansible.builtin.meta: flush_handlers + + - name: Nginx exporter | start exporter service + ansible.builtin.systemd: + name: "{{ nginx_exporter_name }}" + state: started + enabled: true + daemon_reload: true diff --git a/roles/nginx_exporter/templates/.service.j2 b/roles/nginx_exporter/templates/.service.j2 new file mode 100644 index 0000000..3643b69 --- /dev/null +++ b/roles/nginx_exporter/templates/.service.j2 @@ -0,0 +1,15 @@ +[Unit] +Description=Nginx exporter systemd service +After=nginx.service +Requires=nginx.service +PartOf=nginx.service + +[Service] +ExecStart={{ _nginx_exporter_file }} -nginx.scrape-uri http://127.0.0.1:{{ nginx_metric_port }}/stub_status + +Restart=always +User={{ nginx_exporter_user }} +Group={{ nginx_exporter_user}} + +[Install] +WantedBy=multi-user.target diff --git a/roles/nginx_exporter/vars/main.yml b/roles/nginx_exporter/vars/main.yml new file mode 100644 index 0000000..7ea7679 --- /dev/null +++ b/roles/nginx_exporter/vars/main.yml @@ -0,0 +1 @@ +_nginx_exporter_file: "/usr/local/bin/nginx-prometheus-exporter" \ No newline at end of file diff --git a/roles/node/molecule/default/molecule.yml b/roles/node/molecule/default/molecule.yml index 0a663df..579f2f0 100644 --- a/roles/node/molecule/default/molecule.yml +++ b/roles/node/molecule/default/molecule.yml @@ -27,7 +27,3 @@ verifier: name: ansible options: D: True -lint: | - set -e - yamllint . - ansible-lint \ No newline at end of file diff --git a/roles/node/molecule/parachain/molecule.yml b/roles/node/molecule/parachain/molecule.yml index f7b6c24..9264c15 100644 --- a/roles/node/molecule/parachain/molecule.yml +++ b/roles/node/molecule/parachain/molecule.yml @@ -27,7 +27,3 @@ verifier: name: ansible options: D: True -lint: | - set -e - yamllint . - ansible-lint \ No newline at end of file diff --git a/roles/node/molecule/parachain_remote_rc/molecule.yml b/roles/node/molecule/parachain_remote_rc/molecule.yml index 6353fb8..8847240 100644 --- a/roles/node/molecule/parachain_remote_rc/molecule.yml +++ b/roles/node/molecule/parachain_remote_rc/molecule.yml @@ -23,7 +23,3 @@ verifier: name: ansible options: D: True -lint: | - set -e - yamllint . - ansible-lint \ No newline at end of file diff --git a/roles/node_backup/molecule/default/molecule.yml b/roles/node_backup/molecule/default/molecule.yml index 4e44ecf..04195d1 100644 --- a/roles/node_backup/molecule/default/molecule.yml +++ b/roles/node_backup/molecule/default/molecule.yml @@ -25,7 +25,3 @@ verifier: name: ansible options: diff: True -lint: | - set -e - yamllint . - ansible-lint diff --git a/roles/ws_health_exporter/molecule/default/molecule.yml b/roles/ws_health_exporter/molecule/default/molecule.yml index 62ae2fd..5f36ff9 100644 --- a/roles/ws_health_exporter/molecule/default/molecule.yml +++ b/roles/ws_health_exporter/molecule/default/molecule.yml @@ -27,7 +27,3 @@ verifier: name: ansible options: D: True -lint: | - set -e - yamllint . - ansible-lint