Skip to content

Commit

Permalink
feat: decouple secret management from terraform (#300)
Browse files Browse the repository at this point in the history
  • Loading branch information
itegulov authored Sep 24, 2023
1 parent 01c5279 commit b37dfb8
Show file tree
Hide file tree
Showing 12 changed files with 247 additions and 221 deletions.
15 changes: 7 additions & 8 deletions .github/workflows/terraform-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,17 +53,19 @@ jobs:
env:
GOOGLE_CREDENTIALS: ${{ secrets.GCP_CREDENTIALS_DEV }}

# Build Docker image.
- name: Docker Image
id: build
run: docker build .. -t near/mpc-recovery

# Generates an execution plan for Terraform
- name: Terraform Plan
id: plan
run: |
terraform plan -input=false -no-color -lock-timeout=1h -var-file terraform-dev.tfvars \
-var "credentials=$GOOGLE_CREDENTIALS" \
-var "account_creator_id=mpc-recovery-dev-creator.testnet" \
-var "account_creator_sk=$ACCOUNT_CREATOR_SK"
-var "credentials=$GOOGLE_CREDENTIALS"
env:
GOOGLE_CREDENTIALS: ${{ secrets.GCP_CREDENTIALS_DEV }}
ACCOUNT_CREATOR_SK: ${{ secrets.ACCOUNT_CREATOR_SK_DEV }}

- uses: actions/github-script@v6
if: github.event_name == 'pull_request'
Expand Down Expand Up @@ -137,9 +139,6 @@ jobs:
if: github.ref == 'refs/heads/develop' && github.event_name == 'push'
run: |
terraform apply -auto-approve -input=false -lock-timeout=1h -var-file terraform-dev.tfvars \
-var "credentials=$GOOGLE_CREDENTIALS" \
-var "account_creator_id=mpc-recovery-dev-creator.testnet" \
-var "account_creator_sk=$ACCOUNT_CREATOR_SK"
-var "credentials=$GOOGLE_CREDENTIALS"
env:
GOOGLE_CREDENTIALS: ${{ secrets.GCP_CREDENTIALS_DEV }}
ACCOUNT_CREATOR_SK: ${{ secrets.ACCOUNT_CREATOR_SK_DEV }}
10 changes: 9 additions & 1 deletion .github/workflows/terraform-feature-env.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,18 @@ jobs:
GOOGLE_CREDENTIALS: ${{ secrets.GCP_CREDENTIALS_DEV }}
PR_NUMBER: ${{ env.PR_NUMBER }}

# Build Docker image.
- name: Docker Image
id: build
run: docker build .. -t near/mpc-recovery

# Applies Terraform configuration to the temporary environment
- name: Terraform Apply
id: apply
run: terraform apply -auto-approve -input=false -no-color -lock-timeout=1h -var-file terraform-dev.tfvars -var "credentials=$GOOGLE_CREDENTIALS" -var "env=dev-$PR_NUMBER"
run: |
terraform apply -auto-approve -input=false -no-color -lock-timeout=1h -var-file terraform-dev.tfvars \
-var "credentials=$GOOGLE_CREDENTIALS" \
-var "env=dev-$PR_NUMBER"
env:
GOOGLE_CREDENTIALS: ${{ secrets.GCP_CREDENTIALS_DEV }}
PR_NUMBER: ${{ env.PR_NUMBER }}
Expand Down
91 changes: 74 additions & 17 deletions infra/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ provider "docker" {
}
}

/*
* Create brand new service account with basic IAM
*/
resource "google_service_account" "service_account" {
account_id = "mpc-recovery-${var.env}"
display_name = "MPC Recovery ${var.env} Account"
Expand All @@ -76,43 +79,92 @@ resource "google_project_iam_member" "service-account-datastore-user" {
member = "serviceAccount:${google_service_account.service_account.email}"
}

/*
* Ensure service account has access to Secret Manager variables
*/
resource "google_secret_manager_secret_iam_member" "cipher_key_secret_access" {
count = length(var.signer_configs)

secret_id = var.signer_configs[count.index].cipher_key_secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.service_account.email}"
}

resource "google_secret_manager_secret_iam_member" "secret_share_secret_access" {
count = length(var.signer_configs)

secret_id = var.signer_configs[count.index].sk_share_secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.service_account.email}"
}

resource "google_secret_manager_secret_iam_member" "oidc_providers_secret_access" {
secret_id = var.oidc_providers_secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.service_account.email}"
}

resource "google_secret_manager_secret_iam_member" "account_creator_secret_access" {
secret_id = var.account_creator_sk_secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.service_account.email}"
}

resource "google_secret_manager_secret_iam_member" "fast_auth_partners_secret_access" {
secret_id = var.fast_auth_partners_secret_id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${google_service_account.service_account.email}"
}

/*
* Create Artifact Registry repo, tag existing Docker image and push to the repo
*/
resource "google_artifact_registry_repository" "mpc_recovery" {
repository_id = "mpc-recovery-${var.env}"
format = "DOCKER"
}

resource "docker_registry_image" "mpc_recovery" {
name = docker_image.mpc_recovery.name
name = docker_tag.mpc_recovery.target_image
keep_remotely = true
}

resource "docker_image" "mpc_recovery" {
name = "${var.region}-docker.pkg.dev/${var.project}/${google_artifact_registry_repository.mpc_recovery.name}/mpc-recovery-${var.env}:${data.external.git_checkout.result.sha}"
build {
context = "${path.cwd}/.."
}
resource "docker_tag" "mpc_recovery" {
source_image = var.docker_image
target_image = "${var.region}-docker.pkg.dev/${var.project}/${google_artifact_registry_repository.mpc_recovery.name}/mpc-recovery-${var.env}:${data.external.git_checkout.result.sha}"
}

/*
* Create multiple signer nodes
*/
module "signer" {
count = length(var.cipher_keys)
count = length(var.signer_configs)
source = "./modules/signer"

env = var.env
project = var.project
region = var.region
zone = var.zone
service_account_email = google_service_account.service_account.email
docker_image = docker_image.mpc_recovery.name
docker_image = docker_tag.mpc_recovery.target_image

node_id = count.index
oidc_providers = var.oidc_providers
node_id = count.index

cipher_key = var.cipher_keys[count.index]
sk_share = var.sk_shares[count.index]
oidc_providers_secret_id = var.oidc_providers_secret_id
cipher_key_secret_id = var.signer_configs[count.index].cipher_key_secret_id
sk_share_secret_id = var.signer_configs[count.index].sk_share_secret_id

depends_on = [docker_registry_image.mpc_recovery]
depends_on = [
docker_registry_image.mpc_recovery,
google_secret_manager_secret_iam_member.cipher_key_secret_access,
google_secret_manager_secret_iam_member.secret_share_secret_access,
google_secret_manager_secret_iam_member.oidc_providers_secret_access
]
}

/*
* Create leader node
*/
module "leader" {
source = "./modules/leader"

Expand All @@ -121,15 +173,20 @@ module "leader" {
region = var.region
zone = var.zone
service_account_email = google_service_account.service_account.email
docker_image = docker_image.mpc_recovery.name
docker_image = docker_tag.mpc_recovery.target_image

signer_node_urls = concat(module.signer.*.node.uri, var.external_signer_node_urls)
near_rpc = local.workspace.near_rpc
near_root_account = local.workspace.near_root_account
account_creator_id = var.account_creator_id
fast_auth_partners = var.fast_auth_partners

account_creator_sk = var.account_creator_sk
account_creator_sk_secret_id = var.account_creator_sk_secret_id
fast_auth_partners_secret_id = var.fast_auth_partners_secret_id

depends_on = [docker_registry_image.mpc_recovery, module.signer]
depends_on = [
docker_registry_image.mpc_recovery,
google_secret_manager_secret_iam_member.account_creator_secret_access,
google_secret_manager_secret_iam_member.fast_auth_partners_secret_access,
module.signer
]
}
60 changes: 18 additions & 42 deletions infra/modules/leader/main.tf
Original file line number Diff line number Diff line change
@@ -1,39 +1,3 @@
resource "google_secret_manager_secret" "account_creator_sk" {
secret_id = "mpc-recovery-account-creator-sk-${var.env}"
replication {
automatic = true
}
}

resource "google_secret_manager_secret_version" "account_creator_sk_data" {
secret = google_secret_manager_secret.account_creator_sk.name
secret_data = var.account_creator_sk
}

resource "google_secret_manager_secret_iam_member" "account_creator_secret_access" {
secret_id = google_secret_manager_secret.account_creator_sk.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${var.service_account_email}"
}

resource "google_secret_manager_secret" "fast_auth_partners" {
secret_id = "mpc-recovery-allowed-oidc-providers-leader-${var.env}"
replication {
automatic = true
}
}

resource "google_secret_manager_secret_version" "fast_auth_partners_data" {
secret = google_secret_manager_secret.fast_auth_partners.name
secret_data = jsonencode(var.fast_auth_partners)
}

resource "google_secret_manager_secret_iam_member" "fast_auth_partners_secret_access" {
secret_id = google_secret_manager_secret.fast_auth_partners.id
role = "roles/secretmanager.secretAccessor"
member = "serviceAccount:${var.service_account_email}"
}

resource "google_cloud_run_v2_service" "leader" {
name = "mpc-recovery-leader-${var.env}"
location = var.region
Expand Down Expand Up @@ -79,6 +43,24 @@ resource "google_cloud_run_v2_service" "leader" {
name = "MPC_RECOVERY_ENV"
value = var.env
}
env {
name = "MPC_RECOVERY_ACCOUNT_CREATOR_SK"
value_source {
secret_key_ref {
secret = var.account_creator_sk_secret_id
version = "latest"
}
}
}
env {
name = "FAST_AUTH_PARTNERS"
value_source {
secret_key_ref {
secret = var.fast_auth_partners_secret_id
version = "latest"
}
}
}
env {
name = "RUST_LOG"
value = "mpc_recovery=debug"
Expand All @@ -98,12 +80,6 @@ resource "google_cloud_run_v2_service" "leader" {
}
}
}
depends_on = [
google_secret_manager_secret_version.account_creator_sk_data,
google_secret_manager_secret_version.fast_auth_partners_data,
google_secret_manager_secret_iam_member.account_creator_secret_access,
google_secret_manager_secret_iam_member.fast_auth_partners_secret_access
]
}

// Allow unauthenticated requests
Expand Down
28 changes: 14 additions & 14 deletions infra/modules/leader/variables.tf
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
variable "env" {
type = string
}

variable "project" {
type = string
}

variable "region" {
type = string
}

variable "zone" {
type = string
}

variable "service_account_email" {
type = string
}

variable "docker_image" {
type = string
}

# Application variables
Expand All @@ -22,28 +28,22 @@ variable "signer_node_urls" {
}

variable "near_rpc" {
type = string
}

variable "near_root_account" {
type = string
}

variable "account_creator_id" {
type = string
}

variable "fast_auth_partners" {
type = list(object({
oidc_provider = object({
issuer = string
audience = string
})
relayer = object({
url = string
api_key = string
})
}))
default = []
# Secrets
variable "account_creator_sk_secret_id" {
type = string
}

# Secrets
variable "account_creator_sk" {
variable "fast_auth_partners_secret_id" {
type = string
}
Loading

0 comments on commit b37dfb8

Please sign in to comment.