deploying a Bitcoin node using Terraform and ansible-pull

deploying a Bitcoin node using Terraform and ansible-pull

Update - 2017-11-23 - I’ve updated the bitcoin-node repository to also include Terraform instructions on deploying to Google Cloud.

This was a fun one; in an attempt to keep deployment instructions super simple, I dug into ansible-pull a bit. I kind of liked it. Using ansible-pull, triggered by Terraform and an AWS User Data shell script, a Bitcoin full node can be deployed using a single terraform apply.


The goal here was simple; deploy a full Bitcoin node, for additional network capacity. There are good reasons to run a full Bitcoin node, and this post aims at supporting the deployment of a node. I’ve historically done something like this by provisioning infrastructure through Terraform and then running an Ansible playbook. Often times that involves deploying VPNs, automating SSH key gatheringWhich can turn into a mess of steps, as some of my playbooks have devolved into. I mean, it’s nice to carve up the tasks into very order specific tasks, but sometimes, a single command is all that’s needed.

And that’s what this Github project does. It combines Terraform and ansible-pull to automate the deployment of a Bitcoin node with (esentially) a single command. I had always tracked the pull functionality of Ansible, but I’ve never really USED it. So here it is.

notes on Terraform

The Terraform section is pretty straightforward. It deploys a VPC, subnets, an Internet Gateway, and a single t2.micro instance with 250 GB disk space. It launches the script to kick off the Ansible playbook using ansible-pull.

Running is pretty straightforward. Download and install Terraform (tested with 0.10.x, should work with 0.11.x…). Set the AWS access and secret keys, and kick off Terraform:

terraform init
terraform plan
terraform apply

In a few minutes that instance will be sweating as it catches up to the latest block on the Bitcoin blockchain!

thoughts on ansible-pull

Ansible-pull is pretty neat and amazingly simple. It literally:

  • Pulls a git repo
  • Runs an Ansible playbook in that repo

That’s it. If no playbook is specified, it defaults to <hostname>.yml or local.yml. If you pass in a playbook it runs that. It accepts your classic Ansible parameters. In this particular example, Terraform is launching an instance with an AWS User Data script, which kicks off the Ansible playbook:

HOME=/root ansible-pull -d /opt/bitcoin-node -U /opt/bitcoin-node/ansible/bitcoin_node.yml >> /var/log/ansible-pull.log

The HOME=/root was needed, due to a funky Ansible bug and the $HOME variable. But still, simple:

  • -d specifies the directory to run in
  • -U specifies the repository
  • the final parameter is the playbook.

In this, I specify the playbook to run. If using ansible-pull for managing many systems with a single repository, it might be better to use the default playbook scheme, where it attempts to load the <hostname>.yml playbook.


I really liked this for a simple deployment. Simple and effective. For configuration management, I could see configuring a systemd timer or cron job. I also wonder how effective it would be with something like CircleCI or Travis CI or some other automated build/deployment tool.

Where it falls down is where the Ansible push model excels: order of operations and orchestration of starting/stopping systems. Sometimes, system A needs to start before system B. With this git pull model, it’s trickier to get a system to execute now.

Regardless, a really nice feature when teamed up with Terraform and AWS User Data. I anticipate using it further.