From 2ac9a0e4e5bfa1f1311928e3eb5c41cbd273b033 Mon Sep 17 00:00:00 2001 From: JoshuaLicense Date: Wed, 14 Aug 2024 15:34:06 +0100 Subject: [PATCH 1/3] feat(terraform): allow traffic routing to be controlled by boolean --- .../terraform/vol-terraform-relationship.md | 60 +++++++++++++++++++ infra/terraform/modules/service/README.md | 2 +- infra/terraform/modules/service/ecs.tf | 5 +- infra/terraform/modules/service/variables.tf | 8 ++- website/docusaurus.config.ts | 1 + 5 files changed, 72 insertions(+), 4 deletions(-) create mode 100644 docs/infrastructure/terraform/vol-terraform-relationship.md diff --git a/docs/infrastructure/terraform/vol-terraform-relationship.md b/docs/infrastructure/terraform/vol-terraform-relationship.md new file mode 100644 index 0000000000..e6f82401da --- /dev/null +++ b/docs/infrastructure/terraform/vol-terraform-relationship.md @@ -0,0 +1,60 @@ +--- +sidebar_position: 20 +--- + +# Repositories + +The VOL infrastructure is divided into two repositories: `vol-app` and `vol-terraform`. + +The rationale for this split is explained in RFC-005. At a high level, this approach was the only identified feasible option for implementing the migration the VOL application to ECS and establishing CI/CD workflows. + +:::danger + +The `vol-app` repository depends on the `vol-terraform` repository. This relationship _must_ remain unidirectional to prevent circular dependencies. Circular dependencies can disrupt disaster recovery processes and complicate infrastructure re-creation. + +::: + +### Controlling Traffic Flow + +ECS-related resources created by `vol-app` were intentionally designed to coexist with the existing EC2 infrastructure provisioned by the `vol-terraform` repository. This approach ensures a smooth transition to the new infrastructure. Traffic flow can be managed by setting a listener rule with a higher priority (`0` being the highest priority). + +```mermaid +sequenceDiagram + actor User + participant Load Balancer + participant EC2 + participant ECS + User->>Load Balancer: Request + Load Balancer->>EC2: Route + EC2-->>User: Response + alt ECS listener rule added with higher priority + User->>Load Balancer: Request + Load Balancer->>ECS: Route + ECS-->>User: Response + end +``` + +:::tip + +The listener rule is controlled by the variable: `service.listener_rule_enable` variable. + +To push traffic to the ECS service, set `service.listener_rule_enable = true`. This can be controlled per environment _and_ service. + +```hcl showLineNumbers +# vol-app/infra/terraform/environments/[env]/main.tf + +module "service" { + source = "../../modules/service" + + # ... + + services = { + "service" = { + # ... + + // highlight-next-line + listener_rule_enable = true # default is `true`. + } + } +} +``` diff --git a/infra/terraform/modules/service/README.md b/infra/terraform/modules/service/README.md index 4c35cbda7e..e8c98fcdf6 100644 --- a/infra/terraform/modules/service/README.md +++ b/infra/terraform/modules/service/README.md @@ -49,7 +49,7 @@ | [domain\_name](#input\_domain\_name) | The domain name for the environment | `string` | n/a | yes | | [environment](#input\_environment) | The environment to deploy to | `string` | n/a | yes | | [legacy\_environment](#input\_legacy\_environment) | The legacy environment to deploy use | `string` | n/a | yes | -| [services](#input\_services) | The services to deploy |
map(object({
version = string
repository = string
cpu = number
memory = number
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
add_cdn_url_to_env = optional(bool, false)
lb_listener_arn = string
listener_rule_priority = optional(number, 10)
listener_rule_host_header = optional(string, "*")
security_group_ids = list(string)
subnet_ids = list(string)
vpc_id = optional(string, null)
}))
| `{}` | no | +| [services](#input\_services) | The services to deploy |
map(object({
version = string
repository = string
cpu = number
memory = number
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
add_cdn_url_to_env = optional(bool, false)
lb_listener_arn = string
// The reason for this was to enable the parallel running of ECS and EC2 services.
// This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2.
// Can be removed when EC2 services are removed.
listener_rule_enable = optional(bool, false)
listener_rule_priority = optional(number, 10)
listener_rule_host_header = optional(string, "*")
security_group_ids = list(string)
subnet_ids = list(string)
vpc_id = optional(string, null)
}))
| `{}` | no | | [vpc\_id](#input\_vpc\_id) | The VPC ID | `string` | n/a | yes | ## Outputs diff --git a/infra/terraform/modules/service/ecs.tf b/infra/terraform/modules/service/ecs.tf index 58972b254f..cea856d417 100644 --- a/infra/terraform/modules/service/ecs.tf +++ b/infra/terraform/modules/service/ecs.tf @@ -20,7 +20,10 @@ resource "aws_lb_target_group" "this" { } resource "aws_lb_listener_rule" "this" { - for_each = var.services + for_each = { + for service, config in var.services : service => config + if config.listener_rule_enable + } listener_arn = each.value.lb_listener_arn priority = each.value.listener_rule_priority diff --git a/infra/terraform/modules/service/variables.tf b/infra/terraform/modules/service/variables.tf index b3712eb9eb..3a716adce3 100644 --- a/infra/terraform/modules/service/variables.tf +++ b/infra/terraform/modules/service/variables.tf @@ -34,8 +34,12 @@ variable "services" { actions = list(string) resources = list(string) })) - add_cdn_url_to_env = optional(bool, false) - lb_listener_arn = string + add_cdn_url_to_env = optional(bool, false) + lb_listener_arn = string + // The reason for this was to enable the parallel running of ECS and EC2 services. + // This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2. + // Can be removed when EC2 services are removed. + listener_rule_enable = optional(bool, false) listener_rule_priority = optional(number, 10) listener_rule_host_header = optional(string, "*") security_group_ids = list(string) diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index be033560b3..f5b4ea969a 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -69,6 +69,7 @@ const config: Config = { prism: { theme: lightTheme, darkTheme: darkTheme, + additionalLanguages: ["hcl"], }, } satisfies Preset.ThemeConfig, From f2aacc389042d81ba822cba4187be16286af8974 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 14 Aug 2024 14:37:01 +0000 Subject: [PATCH 2/3] docs: update Terraform docs --- infra/terraform/modules/service/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/infra/terraform/modules/service/README.md b/infra/terraform/modules/service/README.md index e8c98fcdf6..40053bb479 100644 --- a/infra/terraform/modules/service/README.md +++ b/infra/terraform/modules/service/README.md @@ -49,7 +49,7 @@ | [domain\_name](#input\_domain\_name) | The domain name for the environment | `string` | n/a | yes | | [environment](#input\_environment) | The environment to deploy to | `string` | n/a | yes | | [legacy\_environment](#input\_legacy\_environment) | The legacy environment to deploy use | `string` | n/a | yes | -| [services](#input\_services) | The services to deploy |
map(object({
version = string
repository = string
cpu = number
memory = number
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
add_cdn_url_to_env = optional(bool, false)
lb_listener_arn = string
// The reason for this was to enable the parallel running of ECS and EC2 services.
// This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2.
// Can be removed when EC2 services are removed.
listener_rule_enable = optional(bool, false)
listener_rule_priority = optional(number, 10)
listener_rule_host_header = optional(string, "*")
security_group_ids = list(string)
subnet_ids = list(string)
vpc_id = optional(string, null)
}))
| `{}` | no | +| [services](#input\_services) | The services to deploy |
map(object({
version = string
repository = string
cpu = number
memory = number
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
add_cdn_url_to_env = optional(bool, false)
lb_listener_arn = string
// The reason for this was to enable the parallel running of ECS and EC2 services.
// This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2.
// Can be removed when EC2 services are removed.
listener_rule_enable = optional(bool, false)
listener_rule_priority = optional(number, 10)
listener_rule_host_header = optional(string, "*")
security_group_ids = list(string)
subnet_ids = list(string)
vpc_id = optional(string, null)
}))
| `{}` | no | | [vpc\_id](#input\_vpc\_id) | The VPC ID | `string` | n/a | yes | ## Outputs From 6094a086fcb81bc7d36d3aab53b7a62f50fea13b Mon Sep 17 00:00:00 2001 From: JoshuaLicense Date: Wed, 14 Aug 2024 15:42:19 +0100 Subject: [PATCH 3/3] docs: add links to references --- docs/infrastructure/terraform/vol-terraform-relationship.md | 4 ++-- infra/terraform/modules/service/README.md | 2 +- infra/terraform/modules/service/variables.tf | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/infrastructure/terraform/vol-terraform-relationship.md b/docs/infrastructure/terraform/vol-terraform-relationship.md index e6f82401da..fe566de04c 100644 --- a/docs/infrastructure/terraform/vol-terraform-relationship.md +++ b/docs/infrastructure/terraform/vol-terraform-relationship.md @@ -4,9 +4,9 @@ sidebar_position: 20 # Repositories -The VOL infrastructure is divided into two repositories: `vol-app` and `vol-terraform`. +The VOL infrastructure is divided into two repositories: [`vol-app`](https://github.com/dvsa/vol-app) and [`vol-terraform`](https://github.com/dvsa/vol-terraform). -The rationale for this split is explained in RFC-005. At a high level, this approach was the only identified feasible option for implementing the migration the VOL application to ECS and establishing CI/CD workflows. +The rationale for this split is explained in [RFC-005](../../rfc/rfc-005-add-terraform-to-mono-repository.md). At a high level, this approach was the only identified feasible option for implementing the migration the VOL application to ECS and establishing CI/CD workflows. :::danger diff --git a/infra/terraform/modules/service/README.md b/infra/terraform/modules/service/README.md index 40053bb479..065e46e745 100644 --- a/infra/terraform/modules/service/README.md +++ b/infra/terraform/modules/service/README.md @@ -49,7 +49,7 @@ | [domain\_name](#input\_domain\_name) | The domain name for the environment | `string` | n/a | yes | | [environment](#input\_environment) | The environment to deploy to | `string` | n/a | yes | | [legacy\_environment](#input\_legacy\_environment) | The legacy environment to deploy use | `string` | n/a | yes | -| [services](#input\_services) | The services to deploy |
map(object({
version = string
repository = string
cpu = number
memory = number
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
add_cdn_url_to_env = optional(bool, false)
lb_listener_arn = string
// The reason for this was to enable the parallel running of ECS and EC2 services.
// This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2.
// Can be removed when EC2 services are removed.
listener_rule_enable = optional(bool, false)
listener_rule_priority = optional(number, 10)
listener_rule_host_header = optional(string, "*")
security_group_ids = list(string)
subnet_ids = list(string)
vpc_id = optional(string, null)
}))
| `{}` | no | +| [services](#input\_services) | The services to deploy |
map(object({
version = string
repository = string
cpu = number
memory = number
task_iam_role_statements = list(object({
effect = string
actions = list(string)
resources = list(string)
}))
add_cdn_url_to_env = optional(bool, false)
lb_listener_arn = string
// The reason for this was to enable the parallel running of ECS and EC2 services.
// This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2.
// Can be removed when EC2 services are removed.
listener_rule_enable = optional(bool, true)
listener_rule_priority = optional(number, 10)
listener_rule_host_header = optional(string, "*")
security_group_ids = list(string)
subnet_ids = list(string)
vpc_id = optional(string, null)
}))
| `{}` | no | | [vpc\_id](#input\_vpc\_id) | The VPC ID | `string` | n/a | yes | ## Outputs diff --git a/infra/terraform/modules/service/variables.tf b/infra/terraform/modules/service/variables.tf index 3a716adce3..95adef0f61 100644 --- a/infra/terraform/modules/service/variables.tf +++ b/infra/terraform/modules/service/variables.tf @@ -39,7 +39,7 @@ variable "services" { // The reason for this was to enable the parallel running of ECS and EC2 services. // This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2. // Can be removed when EC2 services are removed. - listener_rule_enable = optional(bool, false) + listener_rule_enable = optional(bool, true) listener_rule_priority = optional(number, 10) listener_rule_host_header = optional(string, "*") security_group_ids = list(string)