Skip to content

Commit

Permalink
- Added prod env for deploying infra to prod
Browse files Browse the repository at this point in the history
- Add default env value=dev when GHA is triggered via PR merge where environment becomes blank
- Removed wildcard for IAM
  • Loading branch information
Ronaldo Macapobre committed Dec 18, 2024
1 parent 2cd8b3b commit de73a0d
Show file tree
Hide file tree
Showing 9 changed files with 401 additions and 13 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/build-infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ on:
- prod

env:
WORKING_DIRECTORY: "./infrastructure/cloud/environments/${{ inputs.environment }}"
WORKING_DIRECTORY: "./infrastructure/cloud/environments/${{ inputs.environment || 'dev' }}"

jobs:
build:
Expand All @@ -48,7 +48,6 @@ jobs:
echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_ENV
else
echo "environment=dev" >> $GITHUB_ENV
echo "WORKING_DIRECTORY=${{ env.WORKING_DIRECTORY }}/dev" >> $GITHUB_ENV
fi
- name: Checkout repository
Expand Down
9 changes: 4 additions & 5 deletions .github/workflows/publish-infra.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ on:
- prod

env:
WORKING_DIRECTORY: "./infrastructure/cloud/environments/${{ inputs.environment }}"
WORKING_DIRECTORY: "./infrastructure/cloud/environments/${{ inputs.environment || 'dev' }}"
DUMMY_IMAGE_NAME: dummy-image
GITHUB_IMAGE_REPO: ghcr.io/bcgov/jasper
APP_ECR_REPO_URL: ${{ vars.AWS_ACCOUNT }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com/${{ vars.APP_NAME }}-app-repo-${{ inputs.environment }}
LAMBDA_ECR_REPO_URL: ${{ vars.AWS_ACCOUNT }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com/${{ vars.APP_NAME }}-lambda-repo-${{ inputs.environment }}
APP_ECR_REPO_URL: ${{ vars.AWS_ACCOUNT }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com/${{ vars.APP_NAME }}-app-repo-${{ inputs.environment || 'dev' }}
LAMBDA_ECR_REPO_URL: ${{ vars.AWS_ACCOUNT }}.dkr.ecr.${{ vars.AWS_REGION }}.amazonaws.com/${{ vars.APP_NAME }}-lambda-repo-${{ inputs.environment || 'dev' }}

jobs:
deploy:
Expand All @@ -53,7 +53,6 @@ jobs:
echo "environment=${{ github.event.inputs.environment }}" >> $GITHUB_ENV
else
echo "environment=dev" >> $GITHUB_ENV
echo "WORKING_DIRECTORY=${{ env.WORKING_DIRECTORY }}/dev" >> $GITHUB_ENV
fi
- name: Checkout repository
Expand All @@ -64,7 +63,7 @@ jobs:
with:
sarif_file: tfsec.sarif
working_directory: ${{ env.WORKING_DIRECTORY }}
tfsec_args: "--tfvars-file=${{ env.WORKING_DIRECTORY }}/${{ inputs.environment }}.tfvars"
tfsec_args: "--tfvars-file=${{ env.WORKING_DIRECTORY }}/${{ env.environment }}.tfvars"

- name: Upload SARIF file
uses: github/codeql-action/upload-sarif@v3
Expand Down
4 changes: 4 additions & 0 deletions infrastructure/cloud/environments/prod/backend.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
bucket = "terraform-remote-state-b5e4f5-prod"
dynamodb_table = "terraform-remote-state-lock-b5e4f5"
key = "terraform.tfstate"
region = "ca-central-1"
281 changes: 281 additions & 0 deletions infrastructure/cloud/environments/prod/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,281 @@
#
# "initial" stack containing resources that main stack depends on (e.g. ECR, KMS, openshiftuser)
#
module "initial" {
source = "../../modules/initial"
openshift_iam_user = var.openshift_iam_user
iam_user_table_name = var.iam_user_table_name
test_s3_bucket_name = var.test_s3_bucket_name
region = var.region
kms_key_name = var.kms_key_name
app_name = var.app_name
environment = var.environment
}

#
# The "main" stack
#
data "aws_caller_identity" "current" {}

# VPC
data "aws_vpc" "vpc" {
id = var.vpc_id
}

# Security Groups
data "aws_security_group" "web_sg" {
name = "Web_sg"
}

data "aws_security_group" "app_sg" {
name = "App_sg"
}

data "aws_security_group" "data_sg" {
name = "Data_sg"
}

#
# Modules
#

# Create Secrets placeholder for Secrets Manager
module "secrets_manager" {
source = "../../modules/SecretsManager"
environment = var.environment
app_name = var.app_name
region = var.region
kms_key_arn = module.initial.kms_key_arn
rotate_key_lambda_arn = module.lambda.lambda_functions["rotate-key"].arn
}

# Create RDS Database
module "rds" {
source = "../../modules/RDS"
environment = var.environment
app_name = var.app_name
db_username = module.secrets_manager.db_username
db_password = module.secrets_manager.db_password
data_sg_id = data.aws_security_group.data_sg.id
vpc_id = data.aws_vpc.vpc.id
kms_key_arn = module.initial.kms_key_arn
rds_db_ca_cert = var.rds_db_ca_cert
all_subnet_ids = module.subnets.all_subnet_ids
}

# Create IAM Roles/Policies
module "iam" {
source = "../../modules/IAM"
environment = var.environment
app_name = var.app_name
kms_key_arn = module.initial.kms_key_arn
app_ecr_repo_arn = module.initial.app_ecr.ecr_repo_arn
openshift_iam_user = var.openshift_iam_user
iam_user_table_name = var.iam_user_table_name
secrets_arn_list = module.secrets_manager.secrets_arn_list
account_id = data.aws_caller_identity.current.account_id
kms_key_id = module.initial.kms_key_arn
region = var.region
}

# Parse Subnets
module "subnets" {
source = "../../modules/Subnets"
web_subnet_names = var.web_subnet_names
app_subnet_names = var.app_subnet_names
data_subnet_names = var.data_subnet_names
vpc_id = data.aws_vpc.vpc.id
}

# Create Target Groups
module "tg_web" {
source = "../../modules/TargetGroup"
environment = var.environment
app_name = var.app_name
name = "web"
port = 8080
health_check_path = "/"
vpc_id = data.aws_vpc.vpc.id
protocol = "HTTPS"
}

module "tg_api" {
source = "../../modules/TargetGroup"
environment = var.environment
app_name = var.app_name
name = "api"
port = 5000
health_check_path = "/api/test/headers"
vpc_id = data.aws_vpc.vpc.id
protocol = "HTTP"
}

# Setup ALB Listeners
module "alb" {
source = "../../modules/ALB"
environment = var.environment
app_name = var.app_name
lb_name = var.lb_name
cert_domain_name = var.cert_domain_name
tg_web_arn = module.tg_web.tg_arn
tg_api_arn = module.tg_api.tg_arn
}

# Create Lambda Functions
module "lambda" {
source = "../../modules/Lambda"
environment = var.environment
app_name = var.app_name
lambda_role_arn = module.iam.lambda_role_arn
apigw_execution_arn = module.apigw.apigw_execution_arn
lambda_ecr_repo_url = module.initial.lambda_ecr.ecr_repo_url
mtls_secret_name = module.secrets_manager.mtls_secret_name
lambda_memory_size = var.lambda_memory_size
functions = {
"authorizer" = {
http_method = "*"
resource_path = ""
env_variables = {
VERIFY_SECRET_NAME = module.secrets_manager.api_authorizer_secret.name
}
},
"rotate-key" = {
http_method = "POST"
resource_path = "/*"
statement_id_prefix = "AllowSecretsManagerInvoke"
source_arn = module.secrets_manager.api_authorizer_secret.arn
principal = "secretsmanager.amazonaws.com"
env_variables = {
VERIFY_SECRET_NAME = module.secrets_manager.api_authorizer_secret.name
CLUSTER_NAME = module.ecs_cluster.ecs_cluster.name
}
}
}
}

# Create Cloudwatch LogGroups
module "ecs_api_td_log_group" {
source = "../../modules/Cloudwatch/LogGroup"
environment = var.environment
app_name = var.app_name
kms_key_arn = module.initial.kms_key_arn
resource_name = "ecs"
name = "api-td"
}

module "ecs_web_td_log_group" {
source = "../../modules/Cloudwatch/LogGroup"
environment = var.environment
app_name = var.app_name
kms_key_arn = module.initial.kms_key_arn
resource_name = "ecs"
name = "web-td"
}

module "apigw_api_log_group" {
source = "../../modules/Cloudwatch/LogGroup"
environment = var.environment
app_name = var.app_name
kms_key_arn = module.initial.kms_key_arn
resource_name = "apigateway"
name = "api"
}

# Create API Gateway
module "apigw" {
source = "../../modules/APIGateway"
environment = var.environment
app_name = var.app_name
region = var.region
account_id = data.aws_caller_identity.current.account_id
lambda_functions = module.lambda.lambda_functions
ecs_execution_role_arn = module.iam.ecs_execution_role_arn
log_group_arn = module.apigw_api_log_group.log_group.arn
apigw_logging_role_arn = module.iam.apigw_logging_role_arn
}

# Create ECS Cluster
module "ecs_cluster" {
source = "../../modules/ECS/Cluster"
environment = var.environment
app_name = var.app_name
name = "app"
}

# Create Web ECS Task Definition
module "ecs_web_td" {
source = "../../modules/ECS/TaskDefinition"
environment = var.environment
app_name = var.app_name
name = "web"
region = var.region
ecs_execution_role_arn = module.iam.ecs_execution_role_arn
ecr_repository_url = module.initial.app_ecr.ecr_repo_url
port = 8080
secret_env_variables = module.secrets_manager.web_secrets
kms_key_arn = module.initial.kms_key_arn
log_group_name = module.ecs_web_td_log_group.log_group.name
}

# Create API ECS Task Definition
module "ecs_api_td" {
source = "../../modules/ECS/TaskDefinition"
environment = var.environment
app_name = var.app_name
name = "api"
region = var.region
ecs_execution_role_arn = module.iam.ecs_execution_role_arn
ecr_repository_url = module.initial.app_ecr.ecr_repo_url
port = 5000
env_variables = [
{
name = "CORS_DOMAIN"
value = module.alb.default_lb_dns_name
},
{
name = "AWS_API_GATEWAY_URL"
value = module.apigw.apigw_invoke_url
}
]
secret_env_variables = module.secrets_manager.api_secrets
kms_key_arn = module.initial.kms_key_arn
log_group_name = module.ecs_api_td_log_group.log_group.name
}

# Create Web ECS Service
module "ecs_web_service" {
source = "../../modules/ECS/Service"
environment = var.environment
app_name = var.app_name
name = "web"
ecs_cluster_id = module.ecs_cluster.ecs_cluster.id
ecs_td_arn = module.ecs_web_td.ecs_td_arn
tg_arn = module.tg_web.tg_arn
sg_id = data.aws_security_group.app_sg.id
subnet_ids = module.subnets.web_subnets_ids
port = module.ecs_web_td.port
}

# Create Api ECS Service
module "ecs_api_service" {
source = "../../modules/ECS/Service"
environment = var.environment
app_name = var.app_name
name = "api"
ecs_cluster_id = module.ecs_cluster.ecs_cluster.id
ecs_td_arn = module.ecs_api_td.ecs_td_arn
tg_arn = module.tg_api.tg_arn
sg_id = data.aws_security_group.app_sg.id
subnet_ids = module.subnets.app_subnets_ids
port = module.ecs_api_td.port
}

# WAF
module "waf" {
source = "../../modules/WAF"
environment = var.environment
app_name = var.app_name
region = var.region
allowed_ip_ranges = module.secrets_manager.allowed_ip_ranges
default_lb_arn = module.alb.default_lb_arn
}
10 changes: 10 additions & 0 deletions infrastructure/cloud/environments/prod/prod.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
region = "ca-central-1"
test_s3_bucket_name = "jasper-test-s3-bucket-test"
web_subnet_names = ["Web_Prod_aza_net", "Web_Prod_azb_net"]
app_subnet_names = ["App_Prod_aza_net", "App_Prod_azb_net"]
data_subnet_names = ["Data_Prod_aza_net", "Data_Prod_azb_net"]
openshift_iam_user = "openshiftuserprod"
iam_user_table_name = "BCGOV_IAM_USER_TABLE"
lb_name = "default"
rds_db_ca_cert = "rds-ca-rsa2048-g1"
cert_domain_name = "*.example.ca"
21 changes: 21 additions & 0 deletions infrastructure/cloud/environments/prod/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
terraform {
required_version = "~> 1.10.2"
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.81.0"
}

tls = {
source = "hashicorp/tls"
version = "4.0.6"
}
}

backend "s3" {
}
}

provider "aws" {
region = var.region
}
Loading

0 comments on commit de73a0d

Please sign in to comment.