Skip to content

Releases: navapbc/template-infra

v0.6.1

12 Dec 22:46
d7fa769
Compare
Choose a tag to compare

Summary

Layer Has changes Needs migration
Account
Network 🚚 (optional)
Build repository
Database
Service

Enhancements

  • Add has_external_non_aws_vpc app setting which creates NAT gateway by @lorenyu in #502

Fixes

  • Add route table associations to fix S3 Gateway VPC endpoint and remove NAT gateway by @lorenyu in #499

Tech debt

  • Move VPC endpoints into network module by @lorenyu in #502
  • Filter has_database setting to applications in the network (relevant for multi-app projects) by @lorenyu in #502

Documentation

None of these are breaking changes, but you can have a smoother upgrade by following the migration notes below, which moves resources rather than destroying and recreating them.

Migration notes

First initialize the network you want to migrate/update

terraform -chdir=infra/networks init -reconfigure -backend-config=<NETWORK_NAME>.s3.tfbackend

Then move the VPC endpoints over to where they now reside

terraform -chdir=infra/networks state mv 'aws_security_group.aws_services[0]' 'module.network.aws_security_group.aws_services'
terraform -chdir=infra/networks state mv 'aws_vpc_endpoint.aws_service["ecr.api"]' 'module.network.aws_vpc_endpoint.interface["ecr.api"]'
terraform -chdir=infra/networks state mv 'aws_vpc_endpoint.aws_service["ecr.dkr"]' 'module.network.aws_vpc_endpoint.interface["ecr.dkr"]'
terraform -chdir=infra/networks state mv 'aws_vpc_endpoint.aws_service["kms"]' 'module.network.aws_vpc_endpoint.interface["kms"]'
terraform -chdir=infra/networks state mv 'aws_vpc_endpoint.aws_service["logs"]' 'module.network.aws_vpc_endpoint.interface["logs"]'
terraform -chdir=infra/networks state mv 'aws_vpc_endpoint.aws_service["secretsmanager"]' 'module.network.aws_vpc_endpoint.interface["secretsmanager"]'
terraform -chdir=infra/networks state mv 'aws_vpc_endpoint.aws_service["ssm"]' 'module.network.aws_vpc_endpoint.interface["ssm"]'
terraform -chdir=infra/networks state mv 'aws_vpc_endpoint.aws_service["s3"]' 'module.network.aws_vpc_endpoint.gateway["s3"]'

Then apply the rest of the terraform changes

make infra-update-network NETWORK_NAME=<NETWORK_NAME>

Full Changelog: v0.6.0...v0.6.1

v.0.6.0 🚨 Breaking changes

08 Dec 23:28
fdb6e34
Compare
Choose a tag to compare
Layer Has changes Needs migration
Account
Network
Build repository
Database 🚚
Service 🚚

🚨 Breaking changes

  • Create non-default VPC in network layer by @lorenyu in #496

See migration notes below for how to migrate from v0.5.0

Infra layers with changes that need to be applied

  • Network

New and updated functionality

Tech debt

Documentation

New Contributors

Migration notes

The following migration steps causes downtime. You will want to set a maintenance window of a few hours in which to perform these operations. It may be possible to do a zero-downtime migration but it will likely be much more complex. If that is required, please consult @lorenyu to discuss.

1. Creating your VPC

Configure and create a new non-default VPC for your application environment

make infra-configure-network NETWORK_NAME=<NETWORK_NAME>
make infra-update-network NETWORK_NAME=<NETWORK_NAME>

The plan will list 38 resources, including the VPC itself, public and private subnets, a NAT gateway, route table entries for the NAT gateway, and VPC endpoints for a variety of AWS services, including at the minimum ECR, S3, CloudWatch Logs, and if you have a database layer it will also include KMS, SSM, and Secrets Manager VPC endpoints.

Now you can move on to migrating the application environments to the new VPC. Note that the build repository layer is not associated with a VPC and therefore does not need to be migrated.

2. Migrating the database layer to the new VPC

(You can skip this step if you don't have a database)

Before you do this step, make sure you have database backups if you want to keep your data.

First manually delete the role manager lambda function, and tell terraform to "forget" the role manager security group. The reason is because the security group can only be deleted after the elastic network interfaces associated with the role manager lambda function have been deleted, which takes a few hours for AWS to automatically delete once the lambda function has been deleted, and can theoretically take up to 24 hours. To expedite the migration, you'll want to do these steps and then delete the orphaned security group in the future.

  1. Get the role manager function name then delete it:

    ROLE_MANAGER_FUNCTION_NAME=$(terraform -chdir=infra/<APP_NAME>/database show -json | jq -r '.values.root_module.child_modules[] | .resources[] | select(.address == "module.database.aws_lambda_function.role_manager").values.function_name')
    aws lambda delete-function --function-name "$ROLE_MANAGER_FUNCTION_NAME"
    
  2. Get the security group id for the role manager

    ROLE_MANAGER_SECURITY_GROUP_ID=$(terraform -chdir=infra/app/database show -json | jq -r '.values.root_module.child_modules[] | .resources[] | select(.address == "module.database.aws_security_group.role_manager").values.id')
    echo "$ROLE_MANAGER_SECURITY_GROUP_ID"
    
  3. Now tell terraform to forget about this security group

    terraform -chdir=infra/<APP_NAME>/database state rm module.database.aws_security_group.role_manager
    

You now need to modify the database to disable deletion protection since the database needs to be recreated.

  1. Disable deletion protection on database cluster

    DB_CLUSTER_ID=$(terraform -chdir=infra/app/database show -json | jq -r '.values.root_module.child_modules[] | .resources[] | select(.address == "module.database.aws_rds_cluster.db").values.id')
    aws --no-cli-pager rds modify-db-cluster --db-cluster-identifier "$DB_CLUSTER_ID" --no-deletion-protection --apply-immediately
    
  2. Now apply the remaining changes to the database layer. This will delete your cluster.

    make infra-update-app-database APP_NAME=<APP_NAME> ENVIRONMENT=<ENVIRONMENT>
    
  3. Eventually, in a few hours or the following day, delete the orphaned security group

    aws ec2 delete-security-group --group-id "$ROLE_MANAGER_SECURITY_GROUP_ID"
    
  4. Now that your cluster is created, run the role manager to create the roles in the new database

    make infra-update-app-database-roles APP_NAME=<APP_NAME> ENVIRONMENT=<ENVIRONMENT>
    
  5. Then check that the roles were created successfully

    make infra-check-app-database-roles APP_NAME=<APP_NAME> ENVIRONMENT=<ENVIRONMENT>
    
  6. If you need to load from backups now could be a good time.

3. Migrating the service layer to the new VPC

  1. Manually delete the application load balancer through the AWS Console before applying changes to the service layer. Otherwise you get an error where it fails to attach the security group from the new VPC onto the load balancer which is still in the old VPC.

    LOAD_BALANCER_ARN=$(terraform -chdir=infra/app/service show -json | jq -r '.values.root_module.child_modules[] | .resources[] | select(.address == "module.service.aws_lb.alb").values.arn')
    aws elbv2 delete-load-balancer --load-balancer-arn "$LOAD_BALANCER_ARN"
    
  2. Then apply the rest of the service layer changes

    make infra-update-app-service APP_NAME=<APP_NAME> ENVIRONMENT=<ENVIRONMENT>
    

This is a lot so if you run into trouble don't hesitate to reach out for help.

Full Changelog: v0.5.0...v0.6.0

v0.5.0

01 Dec 19:40
3b84b73
Compare
Choose a tag to compare

Summary

Layer Has changes Needs migration
Account
Network
Build repository
Database
Service

New functionality

  • Add feature flag system by @lorenyu in #483
  • Add ability to pass in extra environment variables to the service by @lorenyu in #483
  • Add ability to pass in extra IAM policies to be attached to the service by @lorenyu in #483
  • Enable db query logging by @lorenyu in #479

Documentation

Full Changelog: v0.4.0...v0.5.0

v.0.4.0 🚨 Breaking changes

22 Nov 00:15
5dedfb0
Compare
Choose a tag to compare

Summary

Layer Has changes Needs migration
Account
Network
Build repository
Database 🚚
Service

🚨 Breaking changes

See migration notes below for how to migrate from v0.3.0

New and updated functionality

Fixes

  • Add concurrency limit to build and publish workflow to @charles-nava in #451 — Fixes race condition when multiple runs of workflow run on same branch
  • Install role manager dependencies on every terraform apply by @charles-nava in #452 — Fixes missing dependencies in deployed role manager lambda function when a second engineer deploys without modifying requirements.txt
  • Shorten database IAM role name prefixes due to character limits by @rocketnova in #472 — Fixes errors with database layer when using long app names, environment names, and/or workspace names

Tech debt

  • Refactor env configs into separate blocks by @lorenyu in #437
  • Replace terraform refresh (deprecated) with terraform apply -refresh-only by @charles-nava in #449
  • Remove redundant comment by @rocketnova in #450
  • Rename ci-app-vulnerability-scans.yml.yml to ci-app-vulnerability-scans.yml by @daphnegold in #465

Documentation

  • Add ADR documenting rationale for separating app infra layers by @lorenyu in #438

Migration notes

If the database cluster already exists and has manage_master_user_password set to false, the running terraform plan on the database layer will fail with the following error:

image

In order to migrate, perform the following steps:

  1. First do a targeted apply of the aws_rds_cluster by running the
    following command (replace ENVIRONMENT_NAME with the correct
    environment)

    TF_CLI_ARGS_apply='-target="module.database.aws_rds_cluster.db"' make infra-update-app-database APP_NAME=app ENVIRONMENT=<ENVIRONMENT_NAME>
    

    Your plan should look like this:
    image

  2. Then you can apply the rest of the changes normally with make infra-update-app-database APP_NAME=app ENVIRONMENT=<ENVIRONMENT_NAME>

Full Changelog: v0.3.0...v0.4.0

v0.3.0 🚨 Breaking changes

13 Sep 17:18
f10c0a0
Compare
Choose a tag to compare

Summary

Layer Has changes Needs migration
Account
Network
Build repository
Database 🚚
Service 🚚

🚨 Breaking changes

  • Separate database access policy into separate policies for application (which has read/write access) and migrations (which has create access) by @charles-nava and @lorenyu in #422, #411, #426, #429, #434, #440, #442, #443, #444 (Note: This change only affects applications that have has_database set to true)

See migration notes below for how to migrate from v0.2.0

Architecture design changes

Note: With this architecture change, you can now delete infra/<APP_NAME>/database/*.tfvars and infra/<APP_NAME>/service/*.tfvars files (see /docs/decisions/infra/0008-consolidate-infra-config-from-tfvars-files-into-config-module.md for more info)

New and updated functionality

Tech debt and maintenance

  • Update Makefile .PHONY list by @lorenyu in #410
  • Bump github.com/hashicorp/go-getter from 1.6.1 to 1.7.0 in /infra/test by @dependabot in #225
  • Use v3 of aws-actions/configure-aws-credentials by @lorenyu in #417
  • Group logs in infra CI service tests by @lorenyu in #430
  • Remove cd.yml and ci-infra.yml from update-template exclude list by @lorenyu in #414

Documentation

  • Fix broken link; improve template application usage instructions by @NavaTim in #395
  • Add update template instructions by @lorenyu in #409
  • Fix hadolint typo in vulnerability-management.md by @yoomlam in #396

Migration notes

Instructions for migrating from v0.2.0

Do the following for each environment:

Step 1: Create new database policies

Do a targeted terraform apply to create the two new policies for the application service's access to the database and the migrator's access to the database. Replace <APP_NAME> and <ENVIRONMENT> with the name of your app and the environment you are updating.

TF_CLI_ARGS_apply='-target module.database.aws_iam_policy.app_db_access -target module.database.aws_iam_policy.migrator_db_access' make infra-update-app-database APP_NAME="<APP_NAME>" ENVIRONMENT="<ENVIRONMENT>"

Verify that the roles and policies are properly configured by running the database role check:

make infra-check-app-database-roles APP_NAME="<APP_NAME>" ENVIRONMENT="<ENVIRONMENT>"

Note: If the lambda function times out, try running it a second time.

Step 2: Update the service layer to use the new policies

make infra-update-app-service APP_NAME="<APP_NAME>" ENVIRONMENT="<ENVIRONMENT>"

Note: If you see the following error, try re-running make infra-update-app-service

│ Error: creating IAM Role (portal-dev-migrator): EntityAlreadyExists: Role with name portal-dev-migrator already exists.
│   status code: 409, request id: 729ac1c2-4972-4da6-b88a-6d2aab546b7c
│
│   with module.service.aws_iam_role.migrator_task[0],
│   on ../../modules/service/access-control.tf line 15, in resource "aws_iam_role" "migrator_task":
│   15: resource "aws_iam_role" "migrator_task" {
│

Verify that the service is still healthy in AWS console.

Verify that the migrator can still run migrations by running database migrations

make release-run-database-migrations APP_NAME="<APP_NAME>" ENVIRONMENT="<ENVIRONMENT>"

Note: This step assumes that you have deployed using the current commit, which doesn't work if you are testing on an a yet-to-be-deployed branch. You can fix this by passing in the IMAGE_TAG argument with the latest tag in ECR:

make release-run-database-migrations APP_NAME="<APP_NAME>" ENVIRONMENT="<ENVIRONMENT>" IMAGE_TAG="<latest tag in ECR>"

Step 3: Apply the rest of the database layer changes to remove the old policy

make infra-update-app-database APP_NAME="<APP_NAME>" ENVIRONMENT="<ENVIRONMENT>"

New Contributors

Full Changelog: v0.2.0...v0.3.0

v0.2.0 🚨 Breaking changes

28 Aug 20:59
e84baf5
Compare
Choose a tag to compare

🚨 Breaking changes

  • Migrate VPC endpoints to separate networks module by @lorenyu in #405 and #407

See migration notes below for how to migrate from v0.1.0

New and updated functionality

Fixes

  • Fix support for multiple environments on projects that has a database (Moving VPC endpoints from database module to network module fixes this)

Tech debt

  • Organize the database module into logical tf files by @aplybeah in #384
  • Organize the service module into logical tf files by @aplybeah in #386
  • Refactor infra tests to prepare for db tests by @lorenyu in #388

Documentation

Migration notes

Instructions for migrating from v0.1.0

Step 0: Initialize the terraform module to work with the correct environment

First, initialize the correct backend for the environment you are working with. If you are working with the dev environment do

terraform -chdir=infra/app/database init -backend-config=dev.s3.tfbackend

Step 1: configure the new network module and initialize terraform

make infra-configure-network
terraform -chdir=infra/networks init -backend-config=default.s3.tfbackend

at this point you may check in the tfbackend file

git add infra/networks/default.s3.tfbackend
git commit

Step 2: get the vpc endpoint ids from the database module

KMS_VPC_ENDPOINT_ID=$(terraform -chdir=infra/app/database show -json | jq -r '.values.root_module.child_modules[] | .resources[] | select(.address == "module.database.aws_vpc_endpoint.kms").values.id')
echo $KMS_VPC_ENDPOINT_ID
SSM_VPC_ENDPOINT_ID=$(terraform -chdir=infra/app/database show -json | jq -r '.values.root_module.child_modules[] | .resources[] | select(.address == "module.database.aws_vpc_endpoint.ssm").values.id')
echo $SSM_VPC_ENDPOINT_ID

Step 3: import the vpc endpoint ids into the network module

terraform -chdir=infra/networks import 'aws_vpc_endpoint.aws_service["kms"]' $KMS_VPC_ENDPOINT_ID
terraform -chdir=infra/networks import 'aws_vpc_endpoint.aws_service["ssm"]' $SSM_VPC_ENDPOINT_ID

Step 4: finally create the rest of the network resources i.e. the vpc_enpoints security group

make infra-update-network

Step 5: remove the VPC endpoints from the database module's state file now that it has been migrated to the network module

terraform -chdir=infra/app/database state rm module.database.aws_vpc_endpoint.kms
terraform -chdir=infra/app/database state rm module.database.aws_vpc_endpoint.ssm

Step 6: apply the rest of the changes to the database module, but first updating the egress rule to no longer reference the vpc endpoints security group so that we can destroy it properly

terraform -chdir=infra/app/database apply -var-file=dev.tfvars -target=module.database.aws_vpc_security_group_egress_rule.role_manager_egress_to_vpc_endpoints
make infra-update-app-database APP_NAME=app ENVIRONMENT=dev

For reference, these are the PRs that introduced this change:

New Contributors

Full Changelog: v0.1.0...v0.2.0

v0.1.0

18 Aug 14:45
10fd3f0
Compare
Choose a tag to compare

New functionality

Documentation

Fixes

New Contributors

Full Changelog: 2023-08-08...2023-08-18

2023-08-08

08 Aug 14:26
d382b79
Compare
Choose a tag to compare

New features

  • Support github action workflows for apps with multiple AWS accounts by @lorenyu in #319

Fixes

Enhancements

Full Changelog: 2023-08-03...2023-08-08

2023-08-03

03 Aug 21:29
ea20b99
Compare
Choose a tag to compare

Notable recent changes

New Contributors

Full Changelog: https://github.com/navapbc/template-infra/commits/2023-08-03