This document describes the Ansible layout of the deployment of eduTEAMS Membership Management Service.

Preparation

Prerequisites for running the deployment:

  • Ansible 2.2+
  • SAML2 AttributeAuthority entity registered in some federation
  • SAML2 ServiceProvider entity registered in some federation
  • SSL certificate and key for the web server (user-facing pages)

Retrieving eduTEAMS source

Source code of the deployment playbook is available at: https://dev.niif.hu/vopaas/vopaas (not yet public! note that it contains encrypted keys)

The deployment scripts use git submodules, therefore you need to clone the repository recursively.

Clone recursively
$ git clone --recursive git@dev.niif.hu:vopaas/vopaas.git

Configuration

We suggest that the configuration should happen in three places:

  • group_vars/<group_name>/vars: this is the main configuration file of the relevant roles. It makes the secret variables available without the vault_ prefix, in order to facilitate debugging.
  • group_vars/<group_name>/vault: this file should be encrypted by ansible-vault, it contains all secrets in variables starting with vault_*
  • certs/ directory: you should keep X.509 keys and certificates there. The keys should be encrypted by ansible-vault. It is recommended to make the files using the following name structure:
<inventory_hostname>{-sp,-aa,}.{key,crt}

Look at role defaults!

MMS is implemented by the registry role. The role depends on two other roles:

The supported configuration of the roles are kept on their defaults file, therefore you should look for the following files to see what parts may be configured:

  • roles/registry/defaults/main.yml
  • roles/geerlingguy.mysql/defaults/main.yml
  • roles/ssp-aa/defaults/main.yml

Note that you should never edit the defaults files, as they belong to the roles. You should override them at somewhere else, for example in the vars file.

Configure credentials and secrets

The following generic section in the vars file makes the credentials available to the roles:

# Note that 'file' lookup decrypts vaulted files automatically
aa_key: "{{ lookup('file','certs/' + inventory_hostname + '-aa.key') }}"
aa_cert: "{{ lookup('file','certs/' + inventory_hostname + '-aa.crt') }}"
sp_key: "{{ lookup('file','certs/' + inventory_hostname + '-sp.key') }}"
sp_cert: "{{ lookup('file','certs/' + inventory_hostname + '-sp.crt') }}"
web_key: "{{ lookup('file','certs/' + inventory_hostname + '.key') }}"
# with intermediates in server -> ca order
web_cert: "{{ lookup('file','certs/' + inventory_hostname + '.crt') }}"

#vopaas db credentials (this is where the export script writes)
vopaas_db_host: 127.0.0.1
vopaas_db_port: 3306
vopaas_db_dbname: vopaas
vopaas_db_user: vopaas
vopaas_db_password: "{{ vars['vault_' + env + '_vopaas_db_password'] }}"

# No password for mysql root -- only unix root can access from local host

comanage_db_host: 127.0.0.1
comanage_db_port: 3306
comanage_db_dbname: comanage
comanage_db_user: comanage
comanage_db_password: "{{ vars['vault_' + env + '_comanage_db_password'] }}"
comanage_prefix: cm_

ssp_cronkey: "{{ vars['vault_' + env + '_ssp_cronkey'] }}"

Configure SimpleSAMLphp Attribute Authority

# SSP AA
## Contact information
ssp_contactname: "{{ comanage_admin_givenname }} {{ comanage_admin_familyname }}"
ssp_contactmail: support@eduteams.org

## AA entityID
aa_entity: https://registry.eduteams.org/aa

## AA authproc configuration (you usually don't need to change them)
ssp_authproc_config: |
    'authproc.aa' => array(
        60 => array(
            'class' => 'vopaas:Vopaas',
            'nameId_attribute_name' =>  'subject_nameid',
            'vopaas_db_host' => '{{ vopaas_db_host }}',
            'vopaas_db_port' => {{ vopaas_db_port }},
            'vopaas_db_dbname' => '{{ vopaas_db_dbname }}',
            'vopaas_db_user' => '{{ vopaas_db_user }}',
            'vopaas_db_password' => '{{ vopaas_db_password }}',
            'debug_log' => {{ vopaas_debug_log }},
            'debug_echo' => {{ vopaas_debug_echo }}
        ),
        // remove 'subject_nameid' manually, as it is injected by aa:Bypass
        69 => array(
            'class' => 'core:AttributeAlter',
            'subject' => 'subject_nameid',
            'pattern' => '/.*/',
            '%remove',
        ),
        70 => array(
            'class' => 'core:AttributeMap', 'name2oid'
        ),
    ),

## No static metadata files for AA
ssp_aa_md: []

## Use eduID.hu MDX service for AA
ssp_aa_mdx:
  - id: eduid.hu-mdx
    source: "https://mdx.eduid.hu"
    fingerprint: "91:81:AD:2B:F1:C1:4E:47:93:A2:9D:49:34:B7:77:62:4F:2F:98:43"
    cachelength: 3600

Configure Shibboleth SP

# Shibboleth
## Shibboleth SP entityID
shib_entity_id: "https://{{ inventory_hostname }}/shibboleth"

## Discovery Service URL
shib_DS: "https://mdx.eduid.hu/role/idp.ds"
## Shibboleth metadata config
### Both 'mdx' and traditional xml URLs ('metadata) are supported
shib:
  mdx:
    - url: "http://mdx.eduid.hu/entities"
      signer:
        # This is automatically downloaded
        url: "https://metadata.eduid.hu/current/mdx-test-signer-2015.crt"
        # this can be checked by `openssl x509 -text -noout`
        sha1_fingerprint: "91:81:AD:2B:F1:C1:4E:47:93:A2:9D:49:34:B7:77:62:4F:2F:98:43"
        # this can be verified by get_url
        cert_pem_sha1sum: "0df8d66eb492e7ecf3cdb396385490b1fa07468e"
        localname: "mdx-test-signer-2015.crt"
### for XML metadata you can uncomment this:
#  metadata:
#    - url: "http://metadata.eduid.hu/current/href.xml"
#      backingFile: "href.xml"
#      signer:
#        url: "https://metadata.eduid.hu/2011/href-metadata-signer-2011.crt"
#        # this can be checked by `openssl x509 -text -noout`
#        sha1_fingerprint: "FE:AE:0B:E8:FB:59:ED:F7:CB:7F:69:DF:19:4F:8B:6D:C7:F6:96:66"
#        # this can be verified by get_url
#        cert_pem_sha1sum: "0df8d66eb492e7ecf3cdb396385490b1fa07468e"
#        localname: "metadata-signer.crt"
### Use default_idp_entity_id to skip Discovery Service
#  default_idp_entity_id: "https://idp.niif.hu/shibboleth"

Comanage & co.

The defaults of the registry role is written respecting eduTEAMS deployments, therefore all comanage configuration (except for credentials) are located in roles/registry/defaults/main.yml.

Deployment

The registry.yml playbook has the following contents (it makes some tweaking that is relevant for the OpenStack cloud infrastructure):

---
- hosts: registry
  vars:
    housekeeping: false
  pre_tasks:
  - name: Make hosts file manageable
    become: yes
    lineinfile:
      dest: /etc/cloud/cloud.cfg
      regexp: '^manage_etc_hosts:'
      line: "manage_etc_hosts: false"
      create: no
    ignore_errors: yes

  - name: Configure /etc/hosts file
    become: yes
    lineinfile:
      dest: /etc/hosts
      line: "{{ ansible_default_ipv4.address }}\t{{ inventory_hostname }}\t{{ ansible_hostname }}"
      insertafter: '^127\.0\.0\.1'

  roles:
  - registry

The actual deployment can be run with the following command:

ansible-playbook -i inventory/prod -l registry -u debian --vault-password-file=vault.password registry.yml

Please check that you understand each options before you proceed!

Here be dragons!

There are certain control switches made available as boolean parameters, but some of them may result in the complete reset of the actual deployment, so use them with extreme care.

  • housekeeping: when set to true, it doesn't run any of the tasks, only the handlers. It can be useful if the playbook has been aborted by some oversight and the handlers need to be run to make the system consistent.
  • wipe_vopaas_db: reset the exportscript's database to empty. This is reconstructed automatically on the next exportscript run.
  • wipe_comanage_db: drop all COmanage data (including user and organizational data) and start with an empty database.
  • comanage_db_load: drop all active COmanage data and reload them from an existing SQL dump. This requires the following (string) parameter to be also set:
  • comanage_db_importfile: path to a file on the local machine (that executes the playbook) that contains the SQL dump of the COmanage db.

You should use these control switches added as --extra-vars parameters to the playbook. But again, be very cautious / verify your backups first.

  • No labels