Skip to content

Commit

Permalink
Merge pull request #84 from GSA-TTS/easy-sandbox-deploy
Browse files Browse the repository at this point in the history
Easy sandbox deploy
  • Loading branch information
rahearn authored Dec 30, 2024
2 parents 7079518 + 674b7a3 commit c3723c1
Show file tree
Hide file tree
Showing 10 changed files with 202 additions and 23 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/deploy-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@ jobs:
access_key=${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
secret_key=${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
bucket=${{ secrets.TERRAFORM_STATE_BUCKET_NAME }}
key="terraform.tfstate.prod"
key=terraform.tfstate.production
2 changes: 1 addition & 1 deletion .github/workflows/deploy-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ jobs:
access_key=${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
secret_key=${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
bucket=${{ secrets.TERRAFORM_STATE_BUCKET_NAME }}
key=terraform.tfstate.stage
key=terraform.tfstate.staging
- name: Set restricted egress
uses: cloud-gov/cg-cli-tools@main
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/terraform-production.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,4 +42,4 @@ jobs:
access_key=${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
secret_key=${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
bucket=${{ secrets.TERRAFORM_STATE_BUCKET_NAME }}
key="terraform.tfstate.prod"
key=terraform.tfstate.production
2 changes: 1 addition & 1 deletion .github/workflows/terraform-staging.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,4 @@ jobs:
access_key=${{ secrets.TERRAFORM_STATE_ACCESS_KEY }}
secret_key=${{ secrets.TERRAFORM_STATE_SECRET_ACCESS_KEY }}
bucket=${{ secrets.TERRAFORM_STATE_BUCKET_NAME }}
key=terraform.tfstate.stage
key=terraform.tfstate.staging
9 changes: 8 additions & 1 deletion terraform/bootstrap/main.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
terraform {
required_version = "~> 1.7"
required_version = "~> 1.10"
required_providers {
cloudfoundry = {
source = "cloudfoundry/cloudfoundry"
Expand Down Expand Up @@ -148,3 +148,10 @@ resource "local_sensitive_file" "bot_secrets_file" {
password = local.sa_cf_password
})
}

output "mgmt_space_id" {
value = module.mgmt_space.space_id
}
output "mgmt_org_id" {
value = data.cloudfoundry_org.org.id
}
7 changes: 4 additions & 3 deletions terraform/providers.tf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
terraform {
required_version = "~> 1.7"
required_version = "~> 1.10"
required_providers {
cloudfoundry = {
source = "cloudfoundry/cloudfoundry"
Expand All @@ -12,8 +12,9 @@ terraform {
}

backend "s3" {
encrypt = "true"
region = "us-gov-west-1"
encrypt = true
use_lockfile = true
region = "us-gov-west-1"
}
}

Expand Down
17 changes: 17 additions & 0 deletions terraform/sandbox_bot/apply.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env bash

set -e

if [[ -z "$1" ]]; then
echo "You must pass the sandbox_name as the first argument"
echo "usage: $0 SANDBOX_NAME [TERRAFORM_CMD]"
exit 1
fi

cmd="apply"
if [[ -n "$2" ]]; then
cmd="$2"
fi

terraform init -backend-config="path=$1/terraform.tfstate" -reconfigure
terraform "$cmd" -var sandbox_name="$1"
75 changes: 75 additions & 0 deletions terraform/sandbox_bot/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
terraform {
required_version = "~> 1.10"
required_providers {
cloudfoundry = {
source = "cloudfoundry/cloudfoundry"
version = "1.1.0"
}
}

backend "local" {}
}
# empty config will let terraform borrow cf-cli's auth
provider "cloudfoundry" {}

variable "sandbox_name" {
type = string
description = "Name of the sandbox environment we're deploying into"
}

locals {
sa_service_name = "${var.sandbox_name}-local-deployer"
sa_key_name = "deployer-access-key"
sa_bot_credentials = jsondecode(data.cloudfoundry_service_credential_binding.runner_sa_key.credential_bindings.0.credential_binding).credentials
sa_cf_username = nonsensitive(local.sa_bot_credentials.username)
}

data "cloudfoundry_service_plans" "cg_service_account" {
name = "space-deployer"
service_offering_name = "cloud-gov-service-account"
}
data "terraform_remote_state" "bootstrap" {
backend = "local"
config = {
path = "${path.module}/../bootstrap/terraform.tfstate"
}
}
resource "cloudfoundry_service_instance" "runner_service_account" {
name = local.sa_service_name
type = "managed"
space = data.terraform_remote_state.bootstrap.outputs.mgmt_space_id
service_plan = data.cloudfoundry_service_plans.cg_service_account.service_plans.0.id
}

resource "cloudfoundry_service_credential_binding" "runner_sa_key" {
name = local.sa_key_name
service_instance = cloudfoundry_service_instance.runner_service_account.id
type = "key"
}
data "cloudfoundry_service_credential_binding" "runner_sa_key" {
name = local.sa_key_name
service_instance = cloudfoundry_service_instance.runner_service_account.id
depends_on = [cloudfoundry_service_credential_binding.runner_sa_key]
}

data "cloudfoundry_user" "sa_user" {
name = local.sa_cf_username
}
resource "cloudfoundry_org_role" "sa_org_manager" {
user = data.cloudfoundry_user.sa_user.users.0.id
type = "organization_manager"
org = data.terraform_remote_state.bootstrap.outputs.mgmt_org_id
}

resource "local_sensitive_file" "bot_secrets_file" {
filename = "${path.module}/../secrets.auto.tfvars"
file_permission = "0600"

content = <<-EOT
# "${local.sa_service_name}"/"${local.sa_key_name}" generated by sandbox_bot terraform module.
# Run `./apply ${var.sandbox_name} destroy` in that directory to clean up
cf_user = "${local.sa_cf_username}"
cf_password = "${local.sa_bot_credentials.password}"
EOT
}
94 changes: 94 additions & 0 deletions terraform/terraform.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
#!/usr/bin/env bash

rmk_file="../config/master.key"
cmd="plan"

usage="
$0: Run terraform commands against a given environment
Usage:
$0 -h
$0 -e <ENV NAME> [-k <RAILS_MASTER_KEY>] [-c <TERRAFORM-CMD>] [<EXTRA CMD ARGUMENTS>]
Options:
-h: show help and exit
-e ENV_NAME: The name of the environment to run terraform against
-k RAILS_MASTER_KEY: RAILS_MASTER_KEY value. Defaults to contents of $rmk_file
-c TERRAFORM-CMD: command to run. Defaults to $cmd
[<EXTRA CMD ARGUMENTS>]: arguments to pass as-is to terraform
"


rmk=`cat $rmk_file || echo -n ""`
env=""
args_to_shift=0

set -e
while getopts ":he:k:c:" opt; do
case "$opt" in
e)
env=${OPTARG}
args_to_shift=$((args_to_shift + 2))
;;
k)
rmk=${OPTARG}
args_to_shift=$((args_to_shift + 2))
;;
c)
cmd=${OPTARG}
args_to_shift=$((args_to_shift + 2))
;;
h)
echo "$usage"
exit 0
;;
esac
done

shift $args_to_shift

if [[ -z "$env" ]]; then
echo "-e <ENV_NAME> is required"
echo "$usage"
exit 1
fi

if [[ ! -f "$env.tfvars" ]]; then
echo "$env.tfvars file is missing"
exit 1
fi

# ensure we're logged in via cli
cf spaces &> /dev/null || cf login -a api.fr.cloud.gov --sso

tfm_needs_init=true
if [[ -f .terraform/terraform.tfstate ]]; then
backend_state_env=`cat .terraform/terraform.tfstate | jq -r ".backend.config.key" | cut -d '.' -f3`
if [[ "$backend_state_env" = "$env" ]]; then
tfm_needs_init=false
fi
fi

if [[ $tfm_needs_init = true ]]; then
if [[ ! -f secrets.backend.tfvars ]]; then
echo "=============================================================================================================="
echo "= Recreating backend config file. It is fine if this step wants to delete any local_sensitive_file resources"
echo "=============================================================================================================="
(cd bootstrap && ./apply.sh)
fi
terraform init -backend-config=secrets.backend.tfvars -backend-config="key=terraform.tfstate.$env" -reconfigure
fi

echo "=============================================================================================================="
echo "= Creating or finding a bot deployer for $env"
echo "=============================================================================================================="
if [[ "$env" = "staging" ]] || [[ "$env" = "production" ]]; then
(cd bootstrap && ./apply.sh -var create_bot_secrets_file=true)
else
(cd sandbox_bot && ./apply.sh "$env")
fi

echo "=============================================================================================================="
echo "= Calling $cmd on the application infrastructure"
echo "=============================================================================================================="
terraform "$cmd" -var-file="$env.tfvars" -var rails_master_key="$rmk" "$@"
15 changes: 0 additions & 15 deletions terraform/tfm_sandbox.sh

This file was deleted.

0 comments on commit c3723c1

Please sign in to comment.