From 5888d4148755f47cd2e02abf3f3601a9970d7be7 Mon Sep 17 00:00:00 2001 From: Victor Morales Date: Fri, 18 Feb 2022 13:52:22 -0800 Subject: [PATCH] Add terraform scripts for deploying DCL nodes --- .gitignore | 2 + deployment/README.md | 25 ++++ deployment/ansible/deploy.yml | 30 +++++ deployment/ansible/inventory/aws_ec2.yml | 23 ++++ .../ansible/inventory/group_vars/all.yml | 27 ++++ deployment/requirements.in | 17 +++ deployment/requirements.txt | 47 +++++++ deployment/terraform/main.tf | 120 ++++++++++++++++++ deployment/terraform/outputs.tf | 3 + deployment/terraform/variables.tf | 19 +++ 10 files changed, 313 insertions(+) create mode 100644 deployment/README.md create mode 100644 deployment/ansible/deploy.yml create mode 100644 deployment/ansible/inventory/aws_ec2.yml create mode 100644 deployment/ansible/inventory/group_vars/all.yml create mode 100644 deployment/requirements.in create mode 100644 deployment/requirements.txt create mode 100644 deployment/terraform/main.tf create mode 100644 deployment/terraform/outputs.tf create mode 100644 deployment/terraform/variables.tf diff --git a/.gitignore b/.gitignore index e3f2175c3..51d74205a 100644 --- a/.gitignore +++ b/.gitignore @@ -28,3 +28,5 @@ dclbench_stats.csv dclbench_stats_history.csv dclbench_exceptions.csv bench/txns +terraform.tfstate* +.terraform* diff --git a/deployment/README.md b/deployment/README.md new file mode 100644 index 000000000..e3128b418 --- /dev/null +++ b/deployment/README.md @@ -0,0 +1,25 @@ +# Terraform deployment + +[Terraform][1] is an open-source infrastructure as code software tool that +codifies cloud APIs into declarative configuration files. + +## Requirements + +1. Install [Terraform][2] and [AWS][3] CLIs +2. Install Ansible requirements. `pip install -r requirements.txt` +3. Configure AWS access keys for CLI. `aws configure` +4. Modify the [deploy ansible playbook](ansible/deploy.yml) accordingly. + +## Deployment + +The following instructions automates the provision of a DCL node in AWS Cloud. + +```bash +cd terraform/ +terraform init +terraform apply -auto-approve +``` + +[1]: https://www.terraform.io/ +[2]: https://learn.hashicorp.com/tutorials/terraform/install-cli +[3]: https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html diff --git a/deployment/ansible/deploy.yml b/deployment/ansible/deploy.yml new file mode 100644 index 000000000..5ac62aae6 --- /dev/null +++ b/deployment/ansible/deploy.yml @@ -0,0 +1,30 @@ +--- +# Copyright 2022 Samsung Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +- name: bootstrap DCL nodes + hosts: all + become: true + roles: + - bootstrap + tasks: + - name: get genesis.json file + get_url: + url: https://raw.githubusercontent.com/zigbee-alliance/distributed-compliance-ledger/master/deployment/persistent_chains/testnet-2.0/genesis.json + dest: /var/lib/dcl/.dcl/config/genesis.json + - name: start DCL service + become: true + service: + name: dcld + state: started diff --git a/deployment/ansible/inventory/aws_ec2.yml b/deployment/ansible/inventory/aws_ec2.yml new file mode 100644 index 000000000..6923824e0 --- /dev/null +++ b/deployment/ansible/inventory/aws_ec2.yml @@ -0,0 +1,23 @@ +--- +# Copyright 2022 Samsung Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +plugin: amazon.aws.aws_ec2 +regions: + - us-west-1 +boto_profile: default +filters: + instance-state-name: running +compose: + ansible_host: public_ip_address diff --git a/deployment/ansible/inventory/group_vars/all.yml b/deployment/ansible/inventory/group_vars/all.yml new file mode 100644 index 000000000..89fb7d85f --- /dev/null +++ b/deployment/ansible/inventory/group_vars/all.yml @@ -0,0 +1,27 @@ +--- +# Copyright 2022 Samsung Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +chain_id: test-net2 +moniker: tf-test-node +# These accounts must be configured per node +accounts: + - name: user1 + passphrase: password123 + roles: + - NodeAdmin + - name: user2 + passphrase: secret1234 + roles: + - Trustee diff --git a/deployment/requirements.in b/deployment/requirements.in new file mode 100644 index 000000000..cee1a6d43 --- /dev/null +++ b/deployment/requirements.in @@ -0,0 +1,17 @@ +# Copyright 2022 Samsung Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ansible # GPLv3 +boto3 # Apache-2.0 +botocore # Apache-2.0 diff --git a/deployment/requirements.txt b/deployment/requirements.txt new file mode 100644 index 000000000..07a9a37df --- /dev/null +++ b/deployment/requirements.txt @@ -0,0 +1,47 @@ +# +# This file is autogenerated by pip-compile with python 3.8 +# To update, run: +# +# pip-compile --output-file=requirements.txt requirements.in +# +ansible==5.4.0 + # via -r requirements.in +ansible-core==2.12.3 + # via ansible +boto3==1.21.18 + # via -r requirements.in +botocore==1.24.18 + # via + # -r requirements.in + # boto3 + # s3transfer +cffi==1.15.0 + # via cryptography +cryptography==36.0.1 + # via ansible-core +jinja2==3.0.3 + # via ansible-core +jmespath==0.10.0 + # via + # boto3 + # botocore +markupsafe==2.1.0 + # via jinja2 +packaging==21.3 + # via ansible-core +pycparser==2.21 + # via cffi +pyparsing==3.0.7 + # via packaging +python-dateutil==2.8.2 + # via botocore +pyyaml==6.0 + # via ansible-core +resolvelib==0.5.4 + # via ansible-core +s3transfer==0.5.2 + # via boto3 +six==1.16.0 + # via python-dateutil +urllib3==1.26.8 + # via botocore diff --git a/deployment/terraform/main.tf b/deployment/terraform/main.tf new file mode 100644 index 000000000..eda434c63 --- /dev/null +++ b/deployment/terraform/main.tf @@ -0,0 +1,120 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = ">= 3.72" + } + } +} + +# Configure the AWS Provider +provider "aws" { + region = var.region +} + +module "dcl_sg" { + source = "terraform-aws-modules/security-group/aws" + version = "~> 4.0" + + name = "dcl-security_group" + description = "Security group for accessing DCL nodes from outside" + vpc_id = module.network_lab.vpc_id + + ingress_cidr_blocks = ["0.0.0.0/0"] + ingress_rules = ["all-icmp", "ssh-tcp"] + egress_rules = ["all-all"] + ingress_with_cidr_blocks = [ + { + from_port = 26656 + to_port = 26656 + protocol = "tcp" + description = "DCL p2p" + cidr_blocks = "0.0.0.0/0" + }, + { + from_port = 26657 + to_port = 26657 + protocol = "tcp" + description = "DCL RPC" + cidr_blocks = "0.0.0.0/0" + }, + ] +} + +resource "aws_instance" "dcl_node" { + ami = data.aws_ami.ubuntu.id + instance_type = "c5.4xlarge" + + subnet_id = element(module.network_lab.public_subnets, 0) + vpc_security_group_ids = [module.dcl_sg.security_group_id] + + key_name = aws_key_pair.key_pair.id + monitoring = true + + root_block_device { + encrypted = true + volume_size = 20 + } + + connection { + type = "ssh" + host = self.public_ip + user = var.ssh_username + private_key = file(var.ssh_private_key_path) + } + + provisioner "remote-exec" { + inline = [ + "sudo apt-get update", + "sudo apt-get install -y --no-install-recommends python3", + ] + } + + provisioner "local-exec" { + command = "ansible-playbook -i ../ansible/inventory/aws_ec2.yml -u ${var.ssh_username} ../ansible/deploy.yml" + environment = { + ANSIBLE_HOST_KEY_CHECKING = "False" + } + } + + metadata_options { + http_endpoint = "enabled" + http_tokens = "required" + } +} + +data "aws_ami" "ubuntu" { + most_recent = true + owners = ["099720109477"] + + filter { + name = "name" + values = ["ubuntu-minimal/images/hvm-ssd/ubuntu-focal-20.04-amd64-minimal-*"] + } + + filter { + name = "virtualization-type" + values = ["hvm"] + } +} + +resource "aws_key_pair" "key_pair" { + public_key = file(var.ssh_public_key_path) +} + +data "aws_availability_zones" "available" { + state = "available" +} + +module "network_lab" { + source = "terraform-aws-modules/vpc/aws" + version = "~> 3.0" + + name = "dcl-network" + cidr = "10.0.0.0/16" + + azs = [data.aws_availability_zones.available.names[0]] + private_subnets = ["10.0.1.0/24"] + public_subnets = ["10.0.101.0/24"] + enable_nat_gateway = true +} diff --git a/deployment/terraform/outputs.tf b/deployment/terraform/outputs.tf new file mode 100644 index 000000000..724eff1b1 --- /dev/null +++ b/deployment/terraform/outputs.tf @@ -0,0 +1,3 @@ +output "ssh_console" { + value = format("ssh -o 'StrictHostKeyChecking=no' ubuntu@%s", aws_instance.dcl_node.public_ip) +} diff --git a/deployment/terraform/variables.tf b/deployment/terraform/variables.tf new file mode 100644 index 000000000..a07d81eb8 --- /dev/null +++ b/deployment/terraform/variables.tf @@ -0,0 +1,19 @@ +variable "ssh_public_key_path" { + description = "SSH public key file path" + default = "~/.ssh/id_rsa.pub" +} + +variable "ssh_private_key_path" { + description = "SSH private key file path" + default = "~/.ssh/id_rsa" +} + +variable "ssh_username" { + description = "SSH username" + default = "ubuntu" +} + +variable "region" { + description = "AWS Region" + default = "us-west-1" +}