Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mpc terraform config #159

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions libs/mpc
Submodule mpc added at 79ec50
79 changes: 79 additions & 0 deletions provisioning/terraform/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Multichain Infrastructure Overview

## Environments:
- Testnet (Production)
- Dev (Development)

## Deployment:

### Development
#### This environment has been automated for deployment, simply make a pull request with your changes to the `develop` branch, get it reviewed, and merge the PR.
- Deployment steps:
1. A merged PR triggers the following Github Actions Workflows:
- [multichain-dev.yml](../.github/workflows/multichain-dev.yml)
- [deploy-multichain-dev-contract.yml](../.github/workflows/deploy-multichain-dev-contract.yml)
2. These workflows deploy a new imaged based off of the github SHA tag to the 8 GCP vms and restart the VM
3. Then, the smart contract for the dev environment is redeployed

### "Break Glass" Deployment of Development environment
#### This should only be used if the environment is completely broken
- Deployment steps:
1. Make sure you have [terraform installed](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) on your local machine
2. Navigate to the `infra` directory, and then the `multichain-dev` directory
3. Verify the variables in both `variables.tf` and `terraform-dev.tfvars` are up to date
4. Verify the environment variables (`main.tf lines 17-61`, `variables.tf lines 87-150`) for the container are as desired
5. Run the `terraform init` command to initialize the infrastructure
- *Note: if you run into permissions issues, please reach out to SRE (Kody)*
6. Run `terraform plan --var-file=terraform-dev.tfvars` and ensure the changes are indeed what you want to change
7. Run `terraform apply --var-file=terraform-dev.tfvars`, This will replace the instance templates with new changes, and rebuild the VMs from scratch.
- *Note: This will cause downtime, so make sure you let your team members know whats going on*
8. Verify that the container has been started by ssh'ing to at least one of the VMs and running `docker ps`
- *Note: use ```gcloud compute ssh multichain-dev-0``` or similar to ssh into machine, contact SRE if you have IAM issues*

---

### Testnet
#### Please keep in mind that this is a live environment, and any changes you make may also effect our ecosystem partners. Ensure your new changes are rigorously tested, and will not break Testnet. This deployment is semi-automated.

- Deployment steps:
1. After verifying these are the changes you would like to make accross all parter environments, publish a new image to the following public image repository: [Public Production Image Repo](https://console.cloud.google.com/artifacts/docker/pagoda-discovery-platform-prod/us-east1/multichain-public/multichain-testnet?project=pagoda-discovery-platform-prod&supportedpurview=project)
2. This can be done 2 different ways:
1. Utilize [Github Actions pipeline](https://github.com/near/mpc-recovery/actions/workflows/multichain-prod.yml)
2. Manually push a docker image with the `latest` tag to the public image repository
3. Track updates accross network using [this grafana dashboard](https://nearinc.grafana.net/d/bdg2srektjy0wd/chain-signatures?orgId=1&tab=query&var-node_account_id=All&var-environment=testnet) (this will take 1-2 hours to propogate)

### "Break Glass" Deployment of Production environment
#### **This should only be used if the environment is completely broken**
- Deployment steps:
1. Make sure you have [terraform installed](https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli) on your local machine
2. Navigate to the `infra` directory, and then the `multichain-testnet` directory
3. Verify the variables in both `variables.tf` and `terraform-testnet.tfvars` are up to date
4. Verify the environment variables (`main.tf lines 17-61`, `variables.tf lines 87-150`) for the container are as desired
5. Run the `terraform init` command to initialize the infrastructure
- *Note: if you run into permissions issues, please reach out to SRE (Kody)*
6. Run `terraform plan --var-file=terraform-testnet.tfvars` and ensure the changes are indeed what you want to change
7. Run `terraform apply --var-file=terraform-testnet.tfvars`, This will replace the instance templates with new changes, and rebuild the VMs from scratch.
- *Note: This will cause downtime, **MAKE SURE YOU ACTUALLY WANT TO DO THIS AND NOTIFY PARTNERS IN TELEGRAM CHANNEL "NEAR MPC Node Operators" If you don't have access to that telegram channel, you should probably not be doing this***
8. Verify that the container has been started by ssh'ing to at least one of the VMs and running `docker ps`
- *Note: use ```gcloud compute ssh multichain-testnet-partner-0``` or similar to ssh into machine, contact SRE if you have IAM issues*

# MPC Recovery Infrastructure Overview

There are currently 3 mostly static environments for MPC
- Mainnet (production)
- Testnet (production)
- Dev (development)

## Mainnet/Testnet

Mainnet and Testnet infra code is in the directory `mpc-recovery-prod` and is built off of the `main` GitHub Branch
- This environment should be deployed via the GHA pipeline `deploy-prod.yml` manually in order to prevent unwanted changes
- Both Mainnet and Testnet are treated as production environments

## Dev

The Dev environment infra code is located in the `mpc-recovery-dev` directory and is built off of the `develop` GitHub Branch
- This should be used as the main development environment
- Every time a pull request is opened up against the `develop` branch, a new, ephemeral environment is created with your changes
- *Note: These environments will have the associated PR number appended to all resources*
- When a pull request is approved and merged into the `develop` branch, a new revision is deployed to the static Dev environment with the PRs changes and the PRs ephemeral environment is destroyed
83 changes: 83 additions & 0 deletions provisioning/terraform/modules/instance-from-tpl/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
locals {
hostname = var.hostname == "" ? "default" : var.hostname
num_instances = length(var.static_ips) == 0 ? var.num_instances : length(var.static_ips)

# local.static_ips is the same as var.static_ips with a dummy element appended
# at the end of the list to work around "list does not have any elements so cannot
# determine type" error when var.static_ips is empty
static_ips = concat(var.static_ips, ["NOT_AN_IP"])

zones = length(var.zones) == 0 ? data.google_compute_zones.available.names : var.zones

instance_group_count = min(
local.num_instances,
length(local.zones),
)
}

###############
# Data Sources
###############

data "google_compute_zones" "available" {
project = var.project_id
region = var.region
status = "UP"
}

resource "google_compute_instance_from_template" "compute_instance" {
provider = google
count = local.num_instances
name = local.hostname
project = var.project_id
zone = local.zones[count.index % length(local.zones)]

network_interface {
network = var.network
subnetwork = var.subnetwork
subnetwork_project = var.subnetwork_project
network_ip = length(var.static_ips) == 0 ? "" : element(local.static_ips, count.index)

dynamic "access_config" {
# convert to map to use lookup function with default value
for_each = lookup({ for k, v in var.access_config : k => v }, count.index, [])
content {
nat_ip = access_config.value.nat_ip
network_tier = access_config.value.network_tier
}
}

dynamic "ipv6_access_config" {
# convert to map to use lookup function with default value
for_each = lookup({ for k, v in var.ipv6_access_config : k => v }, count.index, [])
content {
network_tier = ipv6_access_config.value.network_tier
}
}
}

dynamic "network_interface" {
for_each = var.additional_networks
content {
network = network_interface.value.network
subnetwork = network_interface.value.subnetwork
subnetwork_project = network_interface.value.subnetwork_project
network_ip = length(network_interface.value.network_ip) > 0 ? network_interface.value.network_ip : null
dynamic "access_config" {
for_each = network_interface.value.access_config
content {
nat_ip = access_config.value.nat_ip
network_tier = access_config.value.network_tier
}
}
dynamic "ipv6_access_config" {
for_each = network_interface.value.ipv6_access_config
content {
network_tier = ipv6_access_config.value.network_tier
}
}
}
}

source_instance_template = var.instance_template
}
Loading
Loading