Changeset - 7be03b9a5d15
[Not reviewed]
0 2 0
Branko Majic (branko) - 9 months ago 2025-02-21 19:01:44
branko@majic.rs
MAR-245: Fix some linting errors in documentation:

- Use proper truthy YAML expressions.
- Explicitly specify file permissions.
2 files changed with 31 insertions and 29 deletions:
0 comments (0 inline, 0 general)
docs/rolereference.rst
Show inline comments
 
@@ -1470,25 +1470,25 @@ Here is an example configuration for setting-up the mail forwarder:
 

	
 
  ---
 

	
 
  # All mails sent to local user root will be forwarded to external account as
 
  # well.
 
  local_mail_aliases:
 
    root: "root john.doe@example.com"
 

	
 
  smtp_relay_host: mail.example.com
 

	
 
  smtp_relay_host_port: 27
 

	
 
  smtp_from_relay_allowed: False
 
  smtp_from_relay_allowed: false
 

	
 
  smtp_relay_truststore: /etc/ssl/certs/example_ca_chain.pem
 

	
 

	
 
Web Server
 
----------
 

	
 
The ``web_server`` role can be used for setting-up a web server on destination
 
machine.
 

	
 
The role is supposed to be very lightweight, providing a basis for deployment of
 
web applications.
docs/usage.rst
Show inline comments
 
@@ -513,51 +513,51 @@ etc.
 

	
 
Let's take care of this common configuration right away:
 

	
 
1. Create playbook for the communications server:
 

	
 
   :file:`~/mysite/playbooks/communications.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: communications
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 

	
 
2. Create playbook for the web server:
 

	
 
   :file:`~/mysite/playbooks/web.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: web
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 

	
 
3. Create playbook for the backup server:
 

	
 
   :file:`~/mysite/playbooks/backup.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: backup
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 

	
 
4. Create the global site playbook:
 

	
 
   :file:`~/mysite/playbooks/site.yml`
 
   ::
 

	
 
      ---
 

	
 
      - import_playbook: preseed.yml
 
      - import_playbook: communications.yml
 
@@ -625,41 +625,41 @@ Since some of the services actually depend on LDAP, we'll go ahead and set that
 
one up first. This includes both the LDAP *server* and *client* configuration.
 

	
 
1. Update the playbook for communications server to include the LDAP client and
 
   server roles (``ldap_client`` and ``ldap_server``, respectively).
 

	
 
   :file:`~/mysite/playbooks/communications.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: communications
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - ldap_client
 
          - ldap_server
 

	
 
2. Update the playbook for web server to include the LDAP client role
 
   (``ldap_client``). You never know when it might come in handy :)
 

	
 
   :file:`~/mysite/playbooks/web.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: web
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - ldap_client
 

	
 
3. Time to configure the roles. For start, let us configure the LDAP
 
   server role. Keep in mind that there is a lot of default variables
 
   set-up by the role itself, making our config rather short. The
 
   ``ldap_server_domain`` parameter will be used to form the base DN
 
   of the LDAP directory (resulting in ``dc=example,dc=com``).
 

	
 
   :file:`~/mysite/group_vars/communications.yml`
 
   ::
 
@@ -776,25 +776,25 @@ LDAP directory. This has already been set-up on the server
 

	
 
1. Update the playbook for communications server to include the mail server
 
role.
 

	
 

	
 
    :file:`~/mysite/playbooks/communications.yml`
 
    ::
 

	
 
      ---
 

	
 
      - hosts: communications
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - ldap_client
 
          - ldap_server
 
          - mail_server
 

	
 
2. Let's configure the role next.
 

	
 
   :file:`~/mysite/group_vars/communications.yml`
 
   ::
 

	
 
      # Set the LDAP URL to connect through. Keep in mind TLS is required.
 
@@ -987,38 +987,38 @@ server. This way we can make sure that mail that gets sent via local SMTP to
 
external addresses on those two servers goes through our anti-virus scanner.
 

	
 
1. Update the list of roles for web and backup server to include the mail
 
   forwarder role.
 

	
 
   :file:`~/mysite/playbooks/web.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: web
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - ldap_client
 
          - mail_forwarder
 

	
 
   :file:`~/mysite/playbooks/backup.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: backup
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - mail_forwarder
 

	
 
2. The next thing is to set-up the configuration for the new role. We can define
 
   this globally for all servers
 

	
 
   :file:`~/mysite/group_vars/all.yml`
 
   ::
 

	
 
      # Define what X.509 certificates should be used for validating
 
      # the certificate of server we are relaying the mails through.
 
@@ -1077,25 +1077,25 @@ for some instant messaging. For this purpose, we will use the ``xmpp_server``
 
role.
 

	
 
1. Update the playbook for communications server to include the XMPP server
 
   role.
 

	
 
   :file:`~/mysite/playbooks/communications.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: communications
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - ldap_client
 
          - ldap_server
 
          - mail_server
 
          - xmpp_server
 

	
 
2. Configure the role.
 

	
 
   :file:`~/mysite/group_vars/communications.yml`
 
   ::
 

	
 
@@ -1252,25 +1252,25 @@ with... Well, erm, web server deployment! To be more precise, we will set-up
 
Nginx.
 

	
 
1. Update the playbook for web server to include the web server role.
 

	
 

	
 
    :file:`~/mysite/playbooks/web.yml`
 
    ::
 

	
 
      ---
 

	
 
      - hosts: web
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - ldap_client
 
          - mail_forwarder
 
          - web_server
 

	
 
2. You know the drill, role configuration comes up next. No
 
   configuration has been deployed before for the web server, so we
 
   will be creating a new file. Only the TLS parameters are really
 
   necessary, but we'll spice things up a bit by setting custom title
 
   and message for default virtual host.
 

	
 
@@ -1335,25 +1335,25 @@ server.
 
   over database server unix socket.
 

	
 
1. Update the playbook for web server to include the database server role.
 

	
 

	
 
    :file:`~/mysite/playbooks/web.yml`
 
    ::
 

	
 
      ---
 

	
 
      - hosts: web
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - ldap_client
 
          - mail_forwarder
 
          - web_server
 
          - database_server
 

	
 
2. This particular role has no parameters, and no additional steps are
 
   necessary to configure it. So move along...
 

	
 
3. No TLS support has been implemented for this role (yet), so simply apply the
 
   changes::
 
@@ -1549,34 +1549,35 @@ Before we start, here is a couple of useful pointers regarding the
 
   ::
 

	
 
      ---
 

	
 
      # Deployment
 
      # ==========
 

	
 
      - name: Download the application archive
 
        ansible.builtin.get_url:
 
          url: "https://download.nextcloud.com/server/releases/nextcloud-29.0.4.tar.bz2"
 
          dest: "/var/www/nextcloud.example.com/nextcloud-29.0.4.tar.gz"
 
          checksum: "sha256:19c469e264b31ee80400f8396460854546569e88db4c15fc0854e192f96027eb"
 
        become: yes
 
          mode: "0640"
 
        become: true
 
        become_user: admin-nextcloud_example_com
 

	
 
      - name: Unpack the application archive
 
        ansible.builtin.unarchive:
 
          src: "/var/www/nextcloud.example.com/nextcloud-29.0.4.tar.gz"
 
          dest: "/var/www/nextcloud.example.com/"
 
          copy: no
 
          copy: false
 
          creates: "/var/www/nextcloud.example.com/nextcloud"
 
        become: yes
 
        become: true
 
        become_user: admin-nextcloud_example_com
 

	
 
      # Majic Ansible Roles currently only support utf8 encoding.
 
      - name: Disable opportunistic use of utf8mb4 on fresh installs
 
        ansible.builtin.lineinfile:
 
          dest: "/var/www/nextcloud.example.com/nextcloud/lib/private/Setup/MySQL.php"
 
          line: "{{ '\t\t\t' }}$this->config->setValue('mysql.utf8mb4', true);"
 
          state: absent
 

	
 
      - name: Allow application user to install and update applications
 
        ansible.builtin.file:
 
          path: "/var/www/nextcloud.example.com/nextcloud/apps"
 
@@ -1598,85 +1599,86 @@ Before we start, here is a couple of useful pointers regarding the
 
      - name: Create directory for storing configuration files
 
        ansible.builtin.file:
 
          path: "/var/www/nextcloud.example.com/nextcloud/config"
 
          state: directory
 
          mode: "02750"
 
          owner: "admin-nextcloud_example_com"
 
          group: "web-nextcloud_example_com"
 

	
 
      - name: Create an empty log file if it does not exist
 
        ansible.builtin.copy:
 
          content: ""
 
          dest: "/var/www/nextcloud.example.com/data/nextcloud.log"
 
          force: no
 
          force: false
 
          mode: "0660"
 

	
 
      - name: Set-up log file permissions
 
        ansible.builtin.file:
 
          path: "/var/www/nextcloud.example.com/data/nextcloud.log"
 
          owner: "admin-nextcloud_example_com"
 
          group: "web-nextcloud_example_com"
 
          mode: "0660"
 

	
 
      - name: Symlink the default path used by the web server for finding application files
 
        ansible.builtin.file:
 
          src: "/var/www/nextcloud.example.com/nextcloud"
 
          dest: "/var/www/nextcloud.example.com/htdocs"
 
          state: link
 
          owner: "admin-nextcloud_example_com"
 
          group: "web-nextcloud_example_com"
 
        notify:
 
          - Restart PHP-FPM
 

	
 

	
 
      # Installation
 
      # ============
 

	
 
      - name: Get application installation status
 
        ansible.builtin.command: "/var/www/nextcloud.example.com/nextcloud/occ status"
 
        become: yes
 
        become: true
 
        become_user: "admin-nextcloud_example_com"
 
        register: nextcloud_status
 
        changed_when: False
 
        failed_when: False
 
        changed_when: false
 
        failed_when: false
 

	
 
      - name: Check if application is installed
 
        ansible.builtin.set_fact:
 
          nextcloud_installed: "{{ 'Nextcloud is not installed' not in nextcloud_status.stderr }}"
 

	
 
      - name: Deploy installation script
 
        ansible.builtin.copy:
 
          src: "install_nextcloud.py"
 
          dest: "/var/www/nextcloud.example.com/install_nextcloud.py"
 
          owner: "admin-nextcloud_example_com"
 
          group: "web-nextcloud_example_com"
 
          mode: "0700"
 
        when: "not nextcloud_installed"
 

	
 
      - name: Install application
 
        ansible.builtin.command: "/var/www/nextcloud.example.com/install_nextcloud.py"
 
        become: yes
 
        become: true
 
        become_user: "admin-nextcloud_example_com"
 
        when: "not nextcloud_installed"
 

	
 
      - name: Remove installation script
 
        ansible.builtin.file:
 
          path: "/var/www/nextcloud.example.com/install_nextcloud.py"
 
          state: absent
 

	
 
      - name: Fix data file permissions for application user/group
 
        ansible.builtin.file:
 
          path: "/var/www/nextcloud.example.com/data"
 
          mode: g+w
 
          recurse: yes
 
          follow: no
 
          recurse: true
 
          follow: false
 

	
 
      - name: Deploy local configuration overrides
 
        ansible.builtin.copy:
 
          src: "local.config.php"
 
          dest: "/var/www/nextcloud.example.com/nextcloud/config/local.config.php"
 
          owner: "admin-nextcloud_example_com"
 
          group: "web-nextcloud_example_com"
 
          mode: "0640"
 

	
 
5. Set-up files that are deployed by the role.
 

	
 
   :file:`~/mysite/roles/nextcloud/files/local.config.php`
 
@@ -1745,25 +1747,25 @@ Before we start, here is a couple of useful pointers regarding the
 
      # Return same exit code like child process.
 
      exit(install_process.exitstatus)
 

	
 
6. And... Let's add the new role to our web server.
 

	
 
   :file:`~/mysite/playbooks/web.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: web
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - ldap_client
 
          - mail_forwarder
 
          - web_server
 
          - database_server
 
          - nextcloud
 

	
 
7. Apply the changes::
 

	
 
     workon mysite && ansible-playbook playbooks/site.yml
 

	
 
@@ -1934,64 +1936,64 @@ on the safe side:
 
        ansible.builtin.file:
 
          dest: "/var/www/wiki.example.com/code"
 
          state: directory
 
          owner: admin-wiki_example_com
 
          group: web-wiki_example_com
 
          mode: "02750"
 

	
 
      - name: Start Django project for the Wiki website
 
        ansible.builtin.command: "/var/www/wiki.example.com/virtualenv/bin/exec django-admin startproject wiki_example_com /var/www/wiki.example.com/code"
 
        args:
 
          chdir: "/var/www/wiki.example.com"
 
          creates: "/var/www/wiki.example.com/code/wiki_example_com"
 
        become: yes
 
        become: true
 
        become_user: admin-wiki_example_com
 

	
 
      - name: Deploy settings for wiki website
 
        ansible.builtin.copy:
 
          src: "{{ item }}"
 
          dest: "/var/www/wiki.example.com/code/wiki_example_com/{{ item }}"
 
          mode: "0640"
 
          owner: admin-wiki_example_com
 
          group: web-wiki_example_com
 
        with_items:
 
          - settings.py
 
          - urls.py
 
        notify:
 
          - Restart wiki
 

	
 
      - name: Deploy project database and deploy static files
 
        community.general.django_manage:
 
          command: "{{ item }}"
 
          app_path: "/var/www/wiki.example.com/code/"
 
          virtualenv: "/var/www/wiki.example.com/virtualenv/"
 
        become: yes
 
        become: true
 
        become_user: admin-wiki_example_com
 
        with_items:
 
          - migrate
 
          - collectstatic
 

	
 
      - name: Deploy the superuser creation script
 
        ansible.builtin.copy:
 
          src: "create_superuser.py"
 
          dest: "/var/www/wiki.example.com/code/create_superuser.py"
 
          owner: admin-wiki_example_com
 
          group: web-wiki_example_com
 
          mode: "0750"
 

	
 
      - name: Create initial superuser
 
        ansible.builtin.command: "/var/www/wiki.example.com/virtualenv/bin/exec ./create_superuser.py"
 
        args:
 
          chdir: "/var/www/wiki.example.com/code/"
 
        become: yes
 
        become: true
 
        become_user: admin-wiki_example_com
 
        register: wiki_superuser
 
        changed_when: "wiki_superuser.stdout ==  'Created superuser.'"
 

	
 
   :file:`~/mysite/roles/wiki/handlers/main.yml`
 
   ::
 

	
 
      ---
 

	
 
      - name: Restart wiki
 
        ansible.builtin.service:
 
          name: wiki.example.com
 
@@ -2202,25 +2204,25 @@ on the safe side:
 
          User.objects.create_superuser('admin', 'john.doe@example.com', 'admin')
 
          print("Created superuser.")
 

	
 
6. Time to add the new role to our web server.
 

	
 
   :file:`~/mysite/playbooks/web.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: web
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - ldap_client
 
          - mail_forwarder
 
          - web_server
 
          - database_server
 
          - nextcloud
 
          - wiki
 

	
 
7. Apply the changes:
 

	
 
   ::
 
@@ -2280,25 +2282,25 @@ With the overview of backups out of the way, it is time to set-up the backup
 
server itself first. This is a farily simple task to perform, so let's get
 
straight to it:
 

	
 
1. Update the playbook for backup server to include the backup server role.
 

	
 
   :file:`~/mysite/playbooks/backup.yml`
 
   ::
 

	
 
      ---
 

	
 
      - hosts: backup
 
        remote_user: ansible
 
        become: yes
 
        become: true
 
        roles:
 
          - common
 
          - mail_forwarder
 
          - backup_server
 

	
 
2. There is just one mandatory parameter for the role - OpenSSH server keys to
 
   be used for backup-dedicated instance:
 

	
 
   :file:`~/mysite/group_vars/backup.yml`
 
   ::
 

	
 
      ---
 
@@ -2363,25 +2365,25 @@ So, back to the business:
 
   .. warning::
 
      By default Ansible's file lookup plugin will strip newlines and
 
      spaces from the end of the file. This is a problem when
 
      deploying the RSA ssh keys, since if there is no newline after
 
      the ``-----END OPENSSH PRIVATE KEY-----`` delimeter, ssh client
 
      will report error about the format of the key file being
 
      invalid. Therefore the example below explicitly disables
 
      stripping newline from the end of the file.
 

	
 
   :file:`~/mysite/group_vars/all.yml`
 
   ::
 

	
 
      enable_backup: yes
 
      enable_backup: true
 
      backup_encryption_key: "{{ lookup('pipe', 'gpg --homedir ~/mysite/gnupg/ --armour --export-secret-keys ' + ansible_fqdn ) }}"
 
      backup_server: bak.example.com
 
      backup_server_host_ssh_public_keys:
 
        - "{{ lookup('file', inventory_dir + '/ssh/bak_rsa_key.pub') }}"
 
        - "{{ lookup('file', inventory_dir + '/ssh/bak_ed25519_key.pub') }}"
 
        - "{{ lookup('file', inventory_dir + '/ssh/bak_ecdsa_key.pub') }}"
 
      backup_ssh_key: "{{ lookup('file', inventory_dir + '/ssh/' + ansible_fqdn, rstrip=False) }}"
 

	
 
3. So, looking at the configuration up there, there is a couple of file lookups
 
   for getting the variable values, as well as one pipe lookup for fetching the
 
   encryption keys. For start, let's create the SSH private keys used for client
 
   log-ins to backup server::
0 comments (0 inline, 0 general)