Automate an EOS producer node deployment with Ansible

in #eos6 years ago (edited)

Intro

In my previous post, we covered setting up a fresh EOS node step by step, and hooking it into a testnet. It's a great way to learn what's involved by setting up a server from scratch, but what if you want to experiment with several machines, deploy different configurations or run multiple testnets? Manual setup of multiple servers can become cumbersome and difficult to manage, and its inherently difficult to document.

Configuration Management

Thankfully there are some great tools out there to document and automate server configuration. Personally, i've had great experience with Ansible because it has some strong benefits:

  • It's open source
  • It doesn't require any software to be installed on the target machines
  • Uses SSH for server communication
  • Low barrier to entry, simple syntax

Example

Let's say we wanted to setup a simple EOS producing node on a remote server, create a relevant configuration, and automatically hook it into the Jungle testnet.

Inventory

With Ansible its possible to work with multiple servers, you can group them to perform actions across a range of related machines at the same time and if you work in the cloud its possible to have dynamic configurations.

For this example, lets just setup a single server hosted in Digital Ocean:

[digitalocean]
165.227.238.243

Tasks

Now that we can connect to a server, we want to define the tasks we want to complete. Ansible has various modules pre-baked into the application that allow you to dive in without having to write any boilerplate. It's also possible to just execute raw shell commands by specifying the shell module:

 - name: clone repo eos
   shell: git clone https://github.com/eosio/eos --recursive /opt/eos

Variables

To ensure we don't duplicate configurations, Ansible allows you to define variables. So you could use different credentials based on whether you are deploying to staging vs production, or it can pick up command line parameters passed at runtime. For the EOS project, the git tag is updated frequently, so this is something that could be captured into a variable, allowing us to easily deploy newer versions without a change being made to the generic task:

- git:
    repo: 'https://github.com/EOSIO/eos.git'
    dest: /opt/eos
    version: {{ version }}

Interactive response

As you probably know, when building the EOS project it asks you whether you want to install missing dependencies. This can be problematic for some automation tools, but thankfully Ansible has an expect module for this. You simply pass the regex to match the prompt you want to answer:

 - name: exec eosio_build.sh
   expect:
     chdir: /opt/eos
     command: /bin/bash /opt/eos/eosio_build.sh
     responses:
       \?: 1

Playbooks

Now we have a bunch of tasks, we can use a playbook to execute them in order on the targeted host. Within a playbook we can also define some of the global variables that we want to apply in the execution:

- hosts: digitalocean
  roles:
    - requirements
    - deploy
    - testnet

  vars:
    producer_name: blockmatrix
    p2p_address: bm-testnet.blockmatrix.network
    version: DAWN-2018-04-27-ALPHA

The Code

It's one thing reading about it, but it's way more fun running it for yourself! I have whipped this up into a simple git repo so you can try it out, i tried to be as verbose as possible in the code and stay away from some of the more complex module commands so that it's easier to follow for newcomers to Ansible.

Github: https://github.com/BlockMatrixNetwork/eos-testnet

Moving Forward

For our initial production Block Producer setup, we are using Ansible to help in various way, some examples:

  • Provisioning producer and full nodes
  • Running frequent cleos commands
  • Performing system and application updates
  • Assisting with disaster recovery

It's a great tool that offers a lot of flexibility, but configuration management is a fast moving space! There's already new kids on the block in the "infrastructure-as-code" realm such as Terraform, however they aren't necessarily mutually exclusive - it's important to trial these tools to find the best mix for your workflow.