sky-uk / clusterverse

Full-lifecycle cloud infrastructure cluster management, using Ansible
BSD 3-Clause "New" or "Revised" License
15 stars 9 forks source link
ansible ansible-role automation aws gcp lifecycle-management

clusterverse   License PRs Welcome

A full-lifecycle, immutable cloud infrastructure cluster management role, using Ansible.

clusterverse is designed to manage base-vm infrastructure that underpins cluster-based infrastructure, for example, Couchbase, Kafka, Elasticsearch, or Cassandra.

Contributing

Contributions are welcome and encouraged. Please see CONTRIBUTING.md for details.

Requirements

Python dependencies

Dependencies are managed via pipenv:

To active the pipenv:

AWS

GCP

DNS

DNS is optional. If unset, no DNS names will be created. If DNS is required, you will need a DNS zone delegated to one of the following:

Credentials to the DNS server will also be required. These are specified in the cluster_vars variable described below.

Cluster Definition Variables

Clusters are defined as code within Ansible yaml files that are imported at runtime. Because clusters are built from scratch on the localhost, the automatic Ansible group_vars inclusion cannot work with anything except the special all.yml group (actual groups need to be in the inventory, which cannot exist until the cluster is built). The group_vars/all.yml file is instead used to bootstrap _mergevars.

merge_vars

Clusterverse is designed to be used to deploy the same clusters in multiple clouds and multiple environments, potentially using similar configurations. In order to avoid duplicating configuration (adhering to the DRY principle), a new action plugin has been developed (called merge_vars) to use in place of the standard include_vars, which allows users to define the variables hierarchically, and include (and potentially override) those defined before them. This plugin is similar to include_vars, but when it finds dictionaries that have already been defined, it combines them instead of replacing them.

- merge_vars:
    ignore_missing_files: True
    from: "{{ merge_dict_vars_list }}"     #defined in `group_vars/all.yml`


merge_dict_vars_list - hierarchical:

In the case of a fully hierarchical set of cluster definitions where each directory is a variable, (e.g. cloud (aws or gcp), region (eu-west-1) and _clusterid (test)), the folders may look like:

|-- aws
|   |-- eu-west-1
|   |   |-- sandbox
|   |   |   |-- test
|   |   |   |   `-- cluster_vars.yml
|   |   |   `-- cluster_vars.yml
|   |   `-- cluster_vars.yml
|   `-- cluster_vars.yml
|-- gcp
|   |-- europe-west1
|   |   `-- sandbox
|   |       |-- test
|   |       |   `-- cluster_vars.yml
|   |       `-- cluster_vars.yml
|   `-- cluster_vars.yml
|-- app_vars.yml
`-- cluster_vars.yml

group_vars/all.yml would contain merge_dict_vars_list with the files and directories, listed from top to bottom in the order in which they should override their predecessor:

merge_dict_vars_list:
  - "./cluster_defs/cluster_vars.yml"
  - "./cluster_defs/app_vars.yml"
  - "./cluster_defs/{{ cloud_type }}/"
  - "./cluster_defs/{{ cloud_type }}/{{ region }}/"
  - "./cluster_defs/{{ cloud_type }}/{{ region }}/{{ buildenv }}/"
  - "./cluster_defs/{{ cloud_type }}/{{ region }}/{{ buildenv }}/{{ clusterid }}/"


merge_dict_vars_list - flat:

It is also valid to define all the variables in a single sub-directory:

cluster_defs/
|-- test_aws_euw1
|   |-- app_vars.yml
|   +-- cluster_vars.yml
+-- test_gcp_euw1
    |-- app_vars.yml
    +-- cluster_vars.yml

In this case, merge_dict_vars_list would be only the top-level directory (using cluster_id as a variable). merge_vars does not recurse through directories.

merge_dict_vars_list:
  - "./cluster_defs/{{ clusterid }}"


/group_vars/{{cluster_id}}/*.yml:

If merge_dict_vars_list is not defined, it is still possible to put the flat variables in /group_vars/{{cluster_id}}, where they will be imported using the standard include_vars plugin.

This functionality offers no advantages over simply defining the same cluster yaml files in the directory structure defined in merge_dict_vars_list - flat merge_vars technique above, and that is considered preferred.


Cloud Credential Management

Credentials can be encrypted inline in the playbooks using ansible-vault.


Usage

clusterverse is an Ansible role, and as such must be imported into your \<project>/roles directory. There is a full-featured example in the /EXAMPLE subdirectory.

To import the role into your project, create a requirements.yml file containing:

roles:
  - name: clusterverse
    src: https://github.com/sky-uk/clusterverse
    version: master          ## branch, hash, or tag 

Invocation

For full invocation examples and command-line arguments, please see the example README.md

The role is designed to run in two modes:

Deploy (also performs scaling and repairs)

Redeploy