You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

147 lines
5.6 KiB

7 years ago
7 years ago
7 years ago
7 years ago
  1. # Terraform & Ansible
  2. Automated deployments are done using
  3. [Terraform](https://www.terraform.io/) to create servers on Digital
  4. Ocean then [Ansible](http://www.ansible.com/) to create and manage
  5. testnets on those servers.
  6. ## Install
  7. NOTE: see the [integration bash
  8. script](https://github.com/tendermint/tendermint/blob/develop/networks/remote/integration.sh)
  9. that can be run on a fresh DO droplet and will automatically spin up a 4
  10. node testnet. The script more or less does everything described below.
  11. - Install [Terraform](https://www.terraform.io/downloads.html) and
  12. [Ansible](http://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html)
  13. on a Linux machine.
  14. - Create a [DigitalOcean API
  15. token](https://cloud.digitalocean.com/settings/api/tokens) with read
  16. and write capability.
  17. - Install the python dopy package (`pip install dopy`)
  18. - Create SSH keys (`ssh-keygen`)
  19. - Set environment variables:
  20. ```
  21. export DO_API_TOKEN="abcdef01234567890abcdef01234567890"
  22. export SSH_KEY_FILE="$HOME/.ssh/id_rsa.pub"
  23. ```
  24. These will be used by both `terraform` and `ansible`.
  25. ### Terraform
  26. This step will create four Digital Ocean droplets. First, go to the
  27. correct directory:
  28. cd $GOPATH/src/github.com/tendermint/tendermint/networks/remote/terraform
  29. then:
  30. terraform init
  31. terraform apply -var DO_API_TOKEN="$DO_API_TOKEN" -var SSH_KEY_FILE="$SSH_KEY_FILE"
  32. and you will get a list of IP addresses that belong to your droplets.
  33. With the droplets created and running, let's setup Ansible.
  34. ### Ansible
  35. The playbooks in [the ansible
  36. directory](https://github.com/tendermint/tendermint/tree/master/networks/remote/ansible)
  37. run ansible roles to configure the sentry node architecture. You must
  38. switch to this directory to run ansible
  39. (`cd $GOPATH/src/github.com/tendermint/tendermint/networks/remote/ansible`).
  40. There are several roles that are self-explanatory:
  41. First, we configure our droplets by specifying the paths for tendermint
  42. (`BINARY`) and the node files (`CONFIGDIR`). The latter expects any
  43. number of directories named `node0, node1, ...` and so on (equal to the
  44. number of droplets created). For this example, we use pre-created files
  45. from [this
  46. directory](https://github.com/tendermint/tendermint/tree/master/docs/examples).
  47. To create your own files, use either the `tendermint testnet` command or
  48. review [manual deployments](./deploy-testnets.md).
  49. Here's the command to run:
  50. ansible-playbook -i inventory/digital_ocean.py -l sentrynet config.yml -e BINARY=$GOPATH/src/github.com/tendermint/tendermint/build/tendermint -e CONFIGDIR=$GOPATH/src/github.com/tendermint/tendermint/docs/examples
  51. Voila! All your droplets now have the `tendermint` binary and required
  52. configuration files to run a testnet.
  53. Next, we run the install role:
  54. ansible-playbook -i inventory/digital_ocean.py -l sentrynet install.yml
  55. which as you'll see below, executes
  56. `tendermint node --proxy_app=kvstore` on all droplets. Although we'll
  57. soon be modifying this role and running it again, this first execution
  58. allows us to get each `node_info.id` that corresponds to each
  59. `node_info.listen_addr`. (This part will be automated in the future). In
  60. your browser (or using `curl`), for every droplet, go to IP:26657/status
  61. and note the two just mentioned `node_info` fields. Notice that blocks
  62. aren't being created (`latest_block_height` should be zero and not
  63. increasing).
  64. Next, open `roles/install/templates/systemd.service.j2` and look for the
  65. line `ExecStart` which should look something like:
  66. ExecStart=/usr/bin/tendermint node --proxy_app=kvstore
  67. and add the `--p2p.persistent_peers` flag with the relevant information
  68. for each node. The resulting file should look something like:
  69. [Unit]
  70. Description={{service}}
  71. Requires=network-online.target
  72. After=network-online.target
  73. [Service]
  74. Restart=on-failure
  75. User={{service}}
  76. Group={{service}}
  77. PermissionsStartOnly=true
  78. ExecStart=/usr/bin/tendermint node --proxy_app=kvstore --p2p.persistent_peers=167b80242c300bf0ccfb3ced3dec60dc2a81776e@165.227.41.206:26656,3c7a5920811550c04bf7a0b2f1e02ab52317b5e6@165.227.43.146:26656,303a1a4312c30525c99ba66522dd81cca56a361a@159.89.115.32:26656,b686c2a7f4b1b46dca96af3a0f31a6a7beae0be4@159.89.119.125:26656
  79. ExecReload=/bin/kill -HUP $MAINPID
  80. KillSignal=SIGTERM
  81. [Install]
  82. WantedBy=multi-user.target
  83. Then, stop the nodes:
  84. ansible-playbook -i inventory/digital_ocean.py -l sentrynet stop.yml
  85. Finally, we run the install role again:
  86. ansible-playbook -i inventory/digital_ocean.py -l sentrynet install.yml
  87. to re-run `tendermint node` with the new flag, on all droplets. The
  88. `latest_block_hash` should now be changing and `latest_block_height`
  89. increasing. Your testnet is now up and running :)
  90. Peek at the logs with the status role:
  91. ansible-playbook -i inventory/digital_ocean.py -l sentrynet status.yml
  92. ### Logging
  93. The crudest way is the status role described above. You can also ship
  94. logs to Logz.io, an Elastic stack (Elastic search, Logstash and Kibana)
  95. service provider. You can set up your nodes to log there automatically.
  96. Create an account and get your API key from the notes on [this
  97. page](https://app.logz.io/#/dashboard/data-sources/Filebeat), then:
  98. yum install systemd-devel || echo "This will only work on RHEL-based systems."
  99. apt-get install libsystemd-dev || echo "This will only work on Debian-based systems."
  100. go get github.com/mheese/journalbeat
  101. ansible-playbook -i inventory/digital_ocean.py -l sentrynet logzio.yml -e LOGZIO_TOKEN=ABCDEFGHIJKLMNOPQRSTUVWXYZ012345
  102. ### Cleanup
  103. To remove your droplets, run:
  104. terraform destroy -var DO_API_TOKEN="$DO_API_TOKEN" -var SSH_KEY_FILE="$SSH_KEY_FILE"