Changeset - 61ddc6eab566
[Not reviewed]
0 3 0
Branko Majic (branko) - 11 years ago 2015-05-05 01:18:18
branko@majic.rs
MAR-13: Updated documentation for the preseed role (added missin parameter description for ansible_key). Remove the ansible key from list of authorised keys for root user at end of bootstrap process. Updated testsite documentation to be more explicit for bootstrap process.
3 files changed with 22 insertions and 3 deletions:
0 comments (0 inline, 0 general)
docs/rolereference.rst
Show inline comments
 
Role Reference
 
==============
 

	
 

	
 
Preseed
 
-------
 

	
 
The ``preseed`` role can be used for generating simple preseed files for Debian
 
Wheezy installations.
 

	
 
The generated preseed files allow simplified installation, with a single root
 
partition. A number of common parameters can be provided.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**ansible_key** (string, mandatory)
 
  SSH public key that should be deployed to authorized_keys truststore for
 
  operating system user ``root``. This is necessary for the bootstrap process
 
  to work since Debian Jessie does not allow password-based logins for root.
 

	
 
**preseed_directory** (mandatory)
 
    Destination directory where the preseed files should be stored.
 

	
 
**preseed_servers** (mandatory)
 
  List of servers for which a preseed file should be created. Each item in
 
  this list defines options for a single server. The options are as follows:
 

	
 
  **name** (string, mandatory)
 
    Name associated with the server. This name is used in the preseed
 
    configuration filename.
 

	
 
  **language** (string, mandatory)
 
    Language.
 

	
 
  **country** (string, mandatory)
 
    Country.
 

	
 
  **locale** (string, mandatory)
 
    Locale.
 

	
 
  **keymap** (string, mandatory)
 
    Keymap.
 

	
 
  **network_interface** (string, mandatory)
 
    Name of network interface (for example *eth0*) that should be
 
    configured.
 

	
 
  **network_auto** (boolean, mandatory)
 
    Specifies whether the network configuration should be automatic (using
 
    DHCP) or manual. If manual configuration is selected a number of
 
    additional options needs to be specified.
 

	
 
  **network_ip** (string, mandatory if **network_auto** is set to ``no``)
 
    IP address for the server network interface.
 

	
 
  **network_netmask** (string, mandatory if **network_auto** is set to ``no``)
 
    Netmask for the server network interface.
 

	
 
  **network_gateway** (string, mandatory if **network_auto** is set to ``no``)
 
    Default gateway for the server.
 

	
 
  **network_dns** (string, mandatory if **network_auto** is set to ``no``)
 
    Comma-separated list of DNS servers.
 

	
 
  **network_hostname** (string, mandatory if **network_auto** is set to ``no``)
 
    Server hostname.
 

	
 
  **network_domain** (string, mandatory if **network_auto** is set to ``no``)
 
@@ -101,96 +106,99 @@ automatic and one with manual network configuration:
 
  preseed_servers:
 
    - name: test1.example.com
 
      language: en
 
      country: SE
 
      locale: en_US.UTF-8
 
      keymap: us
 
      network_interface: eth0
 
      network_auto: yes
 
      mirror_hostname: ftp.se.debian.org
 
      mirror_directory: /debian
 
      mirror_proxy: http://proxy.example.com/
 
      root_password: testserver
 
      timezone: Europe/Stockholm
 
    - name: test2.example.com
 
      language: en
 
      country: SE
 
      locale: en_US.UTF-8
 
      keymap: us
 
      network_interface: eth0
 
      network_auto: no
 
      network_ip: 10.0.0.10
 
      network_netmask: 255.255.255.0
 
      network_gateway: 10.0.0.1
 
      network_dns: 10.0.0.2,10.0.0.3
 
      network_hostname: test1
 
      network_domain: example.com
 
      mirror_hostname: ftp.se.debian.org
 
      mirror_proxy: http://proxy.example.com/
 
      mirror_directory: /debian
 
      root_password: testserver
 
      timezone: Europe/Stockholm
 

	
 

	
 
Bootstrap
 
---------
 

	
 
The ``bootstrap`` role can be used for bootstraping a new server with
 
Ansible. In order to apply this role to a server, all that is necessary is root
 
access to the server (either via SSH or locally).
 

	
 
The role implements the following:
 

	
 
* Installs sudo package.
 
* Creates operating system user and group for Ansible (``ansible``).
 
* Sets-up an authorized_key for operating system user ``ansible`` (for remote
 
  SSH access).
 
* Configures sudo to allow operating system user ``ansible`` to run sudo
 
  commands without password authentication.
 
* Removes the Ansible user's key from the list of authorized keys for user root
 
  at the end of bootstrap process. This key was necessary only for the bootstrap
 
  process.
 

	
 

	
 
Parameters
 
~~~~~~~~~~
 

	
 
**ansible_key** (string, mandatory)
 
  SSH public key that should be deployed to authorized_keys truststore for
 
  operating system user ``ansible``.
 

	
 

	
 
Examples
 
~~~~~~~~
 

	
 
Since the role is meant to be used just after the server has been installed, and
 
using the ``root`` account, it is probably going to be invoked from a separate
 
playbook.
 

	
 
For example, a playbook (``bootstrap.yml``) could look something similar to:
 

	
 
.. code-block:: yaml
 

	
 
  ---
 

	
 
  - hosts: "{{ server }}"
 
    remote_user: root
 
    roles:
 
      - bootstrap
 
    vars:
 
      ansible_key: "{{ lookup('file', 'authorized_keys/ansible.pub') }}"
 

	
 
With such a playbook in place, it would be invoked with:
 

	
 
  ansible-playbook --ask-pass -e server=test1.example.com bootstrap.yml
 

	
 

	
 
Common
 
------
 

	
 
The ``common`` role can be used for applying a common configuration and
 
hardening across all servers, no matter what services they provide.
 

	
 
The role implements the following:
 

	
 
* Sets-up umask for all logins to ``0027``.
 
* Installs sudo.
 
* Installs additional base packages, as configured.
 
* Creates additional operating system groups, as configured.
 
* Creates additional operating system users, as configured.
docs/testsite.rst
Show inline comments
 
@@ -25,73 +25,81 @@ bootstrap.yml (for bootstrapping fresh nodes)
 
  .. code-block:: shell
 

	
 
    ansible-playbook -l ldap.example.com playbooks/bootstrap.yml
 

	
 
ldap.yml
 
  This playbook sets-up the LDAP servers. It is included in ``site.yml``.
 

	
 
preseed.yml
 
  This playbook sets-up the Debian preseed files. It is included in
 
  ``site.yml``.
 

	
 
site.yml
 
  This playbook sets-up all servers, including preseed files on local host.
 

	
 
In order to deploy the test site, the following steps would normally be taken:
 

	
 
1. Create TLS private keys (relative to top level directory):
 

	
 
   - ``testsite/tls/mail.example.com_imap.key``
 
   - ``testsite/tls/mail.example.com_smtp.key``
 
   - ``testsite/tls/xmpp.example.com_xmpp.key``
 
   - ``testsite/tls/ldap.example.com_ldap.key``
 

	
 
2. Issue TLS certificates corresponding to the generated TLS private keys (make
 
   sure to use correct FQDN for DNS subject alternative name):
 

	
 
   - ``testsite/tls/mail.example.com_imap.pem`` (subject alternative name should
 
     be ``mail.example.com``)
 
   - ``testsite/tls/mail.example.com_smtp.pem`` (subject alternative name should
 
     be ``mail.example.com``)
 
   - ``testsite/tls/xmpp.example.com_xmpp.pem`` (subject alternative name should
 
     be ``xmpp.example.com``)
 
   - ``testsite/tls/ldap.example.com_ldap.pem`` (subject alternative name should
 
     be ``ldap.example.com``)
 

	
 
3. Create ``PEM`` truststore file which contains all CA certificates that form
 
   CA chain for the issued end entity certificates from previous step at
 
   location ``testsite/tls/example_ca_chain.pem``. It is very important to
 
   include the CA chain used for LDAP server.
 

	
 
4. Generate the preseed files:
 

	
 
  .. code-block:: shell
 

	
 
    ansible-playbook playbooks/preseed.yml
 

	
 
5. Install all servers using the generated preseed files.
 

	
 
6. Invoke the ``bootstrap.yml`` playbook in order to set-up some basic
 
6. Add the SSH host fingerprints to your ``known_hosts`` file (don't forget to
 
   remove old entries if you are redoing the process). You can easily obtain all
 
   the necessary fingerprints with command:
 

	
 
   .. code-block:: shell
 

	
 
      ssh-keyscan mail.example.com ldap.example.com xmpp.example.com
 

	
 
7. Invoke the ``bootstrap.yml`` playbook in order to set-up some basic
 
   environment for Ansible runs on all servers:
 

	
 
  .. code-block:: shell
 

	
 
    ansible-playbook playbooks/bootstrap.yml
 

	
 
7. Finally, apply configuration on all servers:
 
8. Finally, apply configuration on all servers:
 

	
 
  .. code-block:: shell
 

	
 
    ansible-playbook playbooks/site.yml
 

	
 
The playbooks and configurations for test site make a couple of assumptions:
 

	
 
* Each server will be set-up with an operating system user ``admin``, capable of
 
  running the sudo commands.
 
* The password for operating system user ``admin`` is hard-coded to ``admin``.
 
* An SSH ``authorized_keys`` file is set-up for the operating system user
 
  ``admin``. The SSH key stored in it will be read from location
 
  ``~/.ssh/id_rsa.pub`` (i.e. from home directory of user running the Ansible
 
  commands).
 

	
 
For more details on how the playbooks and configuration have been implemented,
 
feel free to browse the test site files (in directory ``testsite``).
roles/bootstrap/tasks/main.yml
Show inline comments
 
---
 

	
 
- name: Install sudo
 
  apt: name=sudo state=installed
 

	
 
- name: Set-up the Ansible group
 
  group: name=ansible system=yes
 

	
 
- name: Set-up the Ansible user
 
  user: name=ansible system=yes group=ansible shell=/bin/bash
 

	
 
- name: Set-up authorized key for the Ansible user
 
  authorized_key: user=ansible key="{{ ansible_key }}"
 

	
 
- name: Set-up password-less sudo for the ansible user
 
  copy: src=ansible_sudo dest=/etc/sudoers.d/ansible mode=640 owner=root group=root
 
\ No newline at end of file
 
  copy: src=ansible_sudo dest=/etc/sudoers.d/ansible mode=640 owner=root group=root
 

	
 
- name: Revoke rights for Ansible user to log-in as root to server via ssh
 
  authorized_key: user=root key="{{ ansible_key }}" state=absent
 
\ No newline at end of file
0 comments (0 inline, 0 general)