Added automation for BS deployment

This commit is contained in:
Arsenii Petrovich 2019-03-19 20:09:10 +03:00
parent 8a17a38c81
commit 5290e2c5f2
8 changed files with 202 additions and 4 deletions

2
.gitignore vendored
View File

@ -24,3 +24,5 @@ group_vars/*.yml
*.temp
*.swp
.*.swp
blockscout-*/

View File

@ -188,7 +188,7 @@ The configuration variable `db_storage` can be used to define the amount of stor
3. Set the configuration file as described at the [corresponding part of instruction](#Configuration);
4. Run `ansible-playbook deploy.yml`;
4. Run `ansible-playbook deploy_infra.yml`;
**Note:** during the deployment the ["diffs didn't match"](#error-applying-plan-diffs-didnt-match) error may occur, it will be ignored automatically. If Ansible play recap shows 0 failed plays, then the deployment was successful despite the error.
@ -202,7 +202,7 @@ Once infrastructure is deployed, read [this](https://forum.poa.network/t/deployi
You can use `ansible-playbook destroy.yml` file to remove any generated infrastructure. But first of all you have to remove resources deployed via CodeDeploy manually (it includes a virtual machine and associated autoscaling group). It is also important to note though that if you run this script on partially generated infrastructure, or if an error occurs during the destroy process, that you may need to manually check for, and remove, any resources that were not able to be deleted for you.
**Note!** While Terraform is stateful, Ansible is stateless, so if you modify `bucket` or `dynamodb_table` variables and run `destroy.yml` or `deploy.yml` playbooks, it will not alter the current S3/Dynamo resources names, but create a new resources. Moreover, altering `bucket` variable will make Terraform to forget about existing infrastructure and, as a consequence, redeploy it. If it absolutely necessary for you to alter the S3 or DynamoDB names you can do it manually and then change the appropriate variable accordingly.
**Note!** While Terraform is stateful, Ansible is stateless, so if you modify `bucket` or `dynamodb_table` variables and run `destroy.yml` or `deploy_infra.yml` playbooks, it will not alter the current S3/Dynamo resources names, but create a new resources. Moreover, altering `bucket` variable will make Terraform to forget about existing infrastructure and, as a consequence, redeploy it. If it absolutely necessary for you to alter the S3 or DynamoDB names you can do it manually and then change the appropriate variable accordingly.
Also note, that changing `backend` variable will force Terraform to forget about created infrastructure also, since it will start searching the current state files locally instead of remote.
@ -213,7 +213,7 @@ You can easily manipulate your deployment from any machine with sufficient prere
## Attaching the existing RDS instance to the current deployment
In some cases you may want not to create a new database, but to add the existing one to use within the deployment. In order to do that configure all the proper values at `group_vars/all.yml` including yours DB ID and name and execute the `ansible-playbook attach_existing_rds.yml` command. This will add the current DB instance into Terraform-managed resource group. After that run `ansible-playbook deploy.yml` as usually.
In some cases you may want not to create a new database, but to add the existing one to use within the deployment. In order to do that configure all the proper values at `group_vars/all.yml` including yours DB ID and name and execute the `ansible-playbook attach_existing_rds.yml` command. This will add the current DB instance into Terraform-managed resource group. After that run `ansible-playbook deploy_infra.yml` as usually.
**Note 1**: while executing `ansible-playbook attach_existing_rds.yml` the S3 and DynamoDB will be automatically created (if `backend` variable is set to `true`) to store Terraform state files.
@ -250,4 +250,4 @@ Please include the following information in your report:
Mismatch reason: attribute mismatch: availability_zones.1252502072
```
This is due to a bug in Terraform, however the fix is to just rerun `ansible-playbook deploy.yml` again, and Terraform will pick up where it left off. This does not always happen, but this is the current workaround if you see it.
This is due to a bug in Terraform, however the fix is to just rerun `ansible-playbook deploy_infra.yml` again, and Terraform will pick up where it left off. This does not always happen, but this is the current workaround if you see it.

14
deploy_software.yml Normal file
View File

@ -0,0 +1,14 @@
- name: Deploy BlockScout
hosts: localhost
tasks:
- name: Use role in loop
include_role:
name: main_software
loop: "{{ chains.keys() }}"
loop_control:
loop_var: chain
index_var: index
environment:
AWS_ACCESS_KEY_ID: "{{ aws_access_key }}"
AWS_SECRET_ACCESS_KEY: "{{ aws_secret_key }}"
AWS_REGION: "{{ region }}"

View File

@ -178,3 +178,34 @@ chain_db_storage_type:
chain_db_version:
core: "10.5"
sokol: "10.6"
chain_branch:
core: "production-core"
sokol: "production-sokol"
#chain_merge_commit:
# core: "2cdead1"
# sokol: "2cdead1"
# An address of BlockScout repo to download
blockscout_repo: https://github.com/poanetwork/blockscout
# If you want you can download and configure repo on your own. It should has the following name - blockscout-{{ chain_name }} and exist inside root playbook folder. Use the following variable to prevent playbooks from overriding
skip_fetch: false
# Login data for the test database. Please, use postgres database with the version specified at BlockScout repo prerequisites
ps_host: localhost
ps_user: myuser
ps_password: mypass
ps_db: mydb
# Custom environment variables that will be exported when testing the Blockscout instance
chain_custom_environment:
core:
METADATA_CONTRACT: 0xE3FfFD154931EB80b2aCE096EC32D6df23661203
VALIDATORS_CONTRACT: 0xa105Db0e6671C7B5f4f350ff1Af6460E6C696e71
LINK_TO_OTHER_EXPLORERS: false
sokol:
METADATA_CONTRACT: 0x81c47A798226e1b90A1b4C9dBDd844033B528D06
VALIDATORS_CONTRACT: 0x4c6a159659CCcb033F4b2e2Be0C16ACC62b89DDB
LINK_TO_OTHER_EXPLORERS: false

View File

@ -0,0 +1 @@
skip_fetch: false

View File

@ -0,0 +1,141 @@
- name: Clone BlockScout
git:
repo: "{{ blockscout_repo }}"
dest: "blockscout-{{ chain }}"
version: "{{ chain_branch[chain] }}"
force: true
when: skip_fetch | bool != true
- name: Merge branches
command: "git merge {{ chain_merge_commit[chain] }}"
args:
chdir: "blockscout-{{ chain }}"
when: skip_fetch | bool != true and chain_merge_commit_item | bool != false
vars:
chain_mc: "{{ chain_merge_commit | default({}) }}"
chain_merge_commit_item: "{{ chain_mc[chain] | default('false') }}"
- name: Copy web config files
copy:
src: "blockscout-{{ chain }}/apps/block_scout_web/config/dev.secret.exs.example"
dest: "blockscout-{{ chain }}/apps/block_scout_web/config/dev.secret.exs"
- name: Template explorer config files
template:
src: dev.secret.exs.j2
dest: "blockscout-{{ chain }}/apps/explorer/config/dev.secret.exs"
- name: Remove static assets from previous deployment, if any
file:
path: "blockscout-{{ chain }}/apps/block_scout_web/priv/static"
state: absent
- name: Compile BlockScout
command: mix do deps.get, local.rebar --force, deps.compile, compile, ecto.drop, ecto.create, ecto.migrate
args:
chdir: "blockscout-{{ chain }}"
- name: Install Node modules at apps/block_scout_web/assets
command: npm install && node_modules/webpack/bin/webpack.js --mode production
args:
chdir: "blockscout-{{ chain }}/apps/block_scout_web/assets"
- name: Instal Node modules at apps/explorer
command: npm install
args:
chdir: "blockscout-{{ chain }}/apps/explorer"
- name: Install SSL certificates
command: mix phx.gen.cert blockscout blockscout.local
args:
chdir: "blockscout-{{ chain }}/apps/block_scout_web"
- name: Start server
command: mix phx.server &
environment:
- BLOCKSCOUT_VERSION: "{{ chain_blockscout_version[chain].value }}"
- COIN: "{{ chain_coin[chain].value }}"
- ETHEREUM_JSONRPC_HTTP_URL: "{{ chains[chain].value }}"
- ETHEREUM_JSONRPC_TRACE_URL: "{{ chain_trace_endpoint[chain].value }}"
- ETHEREUM_JSONRPC_WS_URL: "{{ chain_ws_endpoint[chain].value }}"
- ETHEREUM_JSONRPC_VARIANT: "{{ chain_jsonrpc_variant[chain].value }}"
- HEART_BEAT_TIMEOUT: "{{ chain_heart_beat_timeout[chain].value }}"
- HEART_COMMAND: "{{ chain_heart_command[chain].value }}"
- LOGO: "{{ chain_logo[chain].value }}"
- NETWORK: "{{ chain_network[chain].value }}"
- SUBNETWORK: "{{ chain_subnetwork[chain].value }}"
- NETWORK_ICON: "{{ chain_network_icon[chain].value }}"
- "{{ chain_custom_environment_chain }}"
args:
chdir: "blockscout-{{ chain }}"
vars:
chain_custom_environment_chain: "{{ chain_cec[chain] | default('') }}"
chain_cec: "{{ chain_custom_environment | default('') }}"
- name: User prompt
pause:
prompt: "Please, open your browser and open 4000 port at the machine were Ansible is currently run. BlockScout should appear. Ensure that there is no visual artifacts and then press Enter to continue. Press Ctrl+C if you face any issues to cancel the deployment."
- name: Build static assets
command: mix phx.digest
args:
chdir: "blockscout-{{ chain }}"
- name: Remove dev dependencies
file:
state: absent
path: "{{ item }}"
with_items:
- "blockscout-{{ chain }}/build/"
- "blockscout-{{ chain }}/deps/"
- "blockscout-{{ chain }}/apps/block_scout_web/assets/node_modules/"
- "blockscout-{{ chain }}/apps/explorer/node_modules/"
- "blockscout-{{ chain }}/logs/dev/"
- name: Upload Blockscout to S3
command: "aws deploy push --application-name={{ application_name }} --s3-location {{ s3_connection_string }} --source=blockscout-{{ chain }}"
register: push_output
- name: User prompt
pause:
prompt: "Do you want to deploy the built BlockScout version? [Yes/No] Default: No"
register: user_answer
- name: Update chain variables
aws_ssm_parameter_store:
name: "/{{ prefix }}/{{ chain }}/{{ item.name }}"
value: "{{ item.value }}"
with_items:
- { name: elixir_version, value: "{{ elixir_version }}" }
- { name: block_transformet, value: "{{ chain_block_transformer[chain] }}" }
- { name: new_relic_app_name, value: "{{ chain_new_relic_app_name[chain] }}" }
- { name: new_relic_license_key, value: "{{ chain_new_relic_license_key[chain] }}" }
- { name: pool_size, value: "{{ pool_size }}" }
- { name: ecto_use_ssl, value: "{{ use_ssl }}" }
- { name: ethereum_jsonrpc_variant, value: "{{ chain_jsonrpc_variant[chain] }}" }
- { name: ethereum_jsonrpc_http_url, value: "{{ chains[chain] }}" }
- { name: ethereum_jsonrpc_trace_url, value: "{{ chain_trace_endpoint[chain] }}" }
- { name: ethereum_jsonrpc_ws_url, value: "{{ chain_ws_endpoint[chain] }}" }
- { name: logo, value: "{{ chain_logo[chain] }}" }
- { name: coin, value: "{{ chain_coin[chain] }}" }
- { name: network, value: "{{ chain_network[chain] }}" }
- { name: subnetwork, value: "{{ chain_subnetwork[chain] }}" }
- { name: network_path, value: "{{ chain_network_path[chain] }}" }
- { name: network_icon, value: "{{ chain_network_icon[chain] }}" }
- { name: graphiql_transaction, value: "{{ chain_graphiql_transaction[chain] }}" }
- { name: exq_blocks_concurrency, value: 1 }
- { name: exq_concurrency, value: 1 }
- { name: exq_internal_transactions_concurrency, value: 1 }
- { name: exq_receipts_concurrency, value: 1 }
- { name: exq_transactions_concurrency, value: 1 }
- { name: secret_key_base, value: "{{ secret_key_base }}" }
- { name: alb_ssl_policy, value: "{{ alb_ssl_policy }}" }
- { name: alb_certificate_arn, value: "{{ alb_certificate_arn }}" }
- { name: heart_beat_timeout, value: "{{ chain_heart_beat_timeout[chain] }}" }
- { name: heart_command, value: "{{ chain_heart_command[chain] }}" }
- { name: blockscout_version, value: "{{ chain_blockscout_version[chain] }}" }
# DB info will not be refreshed
- name: Deploy Blockscout
command: "{{ push_output.stdout | regex_replace('^--deployment-group-name <deployment-group-name> --deployment-config-name <deployment-config-name> --description <description>$', '') }} --deployment-group-name {{ prefix }}-explorer-dg{{ index }} --deployment-config-name CodeDeployDefault.OneAtATime --description '{{ chain_blockscout_version[chain] }}'"
when: user_answer.user_input|bool == true

View File

@ -0,0 +1,9 @@
use Mix.Config
config :explorer, Explorer.Repo,
database: "{{ ps_db }}",
hostname: "{{ ps_host }}",
username: "{{ ps_user }}",
password: "{{ ps_password }}",
pool_size: 20,
timeout: 80_000