Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(terraform): allow traffic routing to be controlled by boolean #241

Merged
merged 3 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 60 additions & 0 deletions docs/infrastructure/terraform/vol-terraform-relationship.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
---
sidebar_position: 20
---

# Repositories

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](../../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

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`.
}
}
}
```
2 changes: 1 addition & 1 deletion infra/terraform/modules/service/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
| <a name="input_domain_name"></a> [domain\_name](#input\_domain\_name) | The domain name for the environment | `string` | n/a | yes |
| <a name="input_environment"></a> [environment](#input\_environment) | The environment to deploy to | `string` | n/a | yes |
| <a name="input_legacy_environment"></a> [legacy\_environment](#input\_legacy\_environment) | The legacy environment to deploy use | `string` | n/a | yes |
| <a name="input_services"></a> [services](#input\_services) | The services to deploy | <pre>map(object({<br> version = string<br> repository = string<br> cpu = number<br> memory = number<br> task_iam_role_statements = list(object({<br> effect = string<br> actions = list(string)<br> resources = list(string)<br> }))<br> add_cdn_url_to_env = optional(bool, false)<br> lb_listener_arn = string<br> listener_rule_priority = optional(number, 10)<br> listener_rule_host_header = optional(string, "*")<br> security_group_ids = list(string)<br> subnet_ids = list(string)<br> vpc_id = optional(string, null)<br> }))</pre> | `{}` | no |
| <a name="input_services"></a> [services](#input\_services) | The services to deploy | <pre>map(object({<br> version = string<br> repository = string<br> cpu = number<br> memory = number<br> task_iam_role_statements = list(object({<br> effect = string<br> actions = list(string)<br> resources = list(string)<br> }))<br> add_cdn_url_to_env = optional(bool, false)<br> lb_listener_arn = string<br> // The reason for this was to enable the parallel running of ECS and EC2 services.<br> // This boolean will control the flow of traffic. If `true`, traffic will go to ECS. If `false`, traffic will go to EC2.<br> // Can be removed when EC2 services are removed.<br> listener_rule_enable = optional(bool, true)<br> listener_rule_priority = optional(number, 10)<br> listener_rule_host_header = optional(string, "*")<br> security_group_ids = list(string)<br> subnet_ids = list(string)<br> vpc_id = optional(string, null)<br> }))</pre> | `{}` | no |
| <a name="input_vpc_id"></a> [vpc\_id](#input\_vpc\_id) | The VPC ID | `string` | n/a | yes |

## Outputs
Expand Down
5 changes: 4 additions & 1 deletion infra/terraform/modules/service/ecs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
8 changes: 6 additions & 2 deletions infra/terraform/modules/service/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -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, true)
listener_rule_priority = optional(number, 10)
listener_rule_host_header = optional(string, "*")
security_group_ids = list(string)
Expand Down
1 change: 1 addition & 0 deletions website/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ const config: Config = {
prism: {
theme: lightTheme,
darkTheme: darkTheme,
additionalLanguages: ["hcl"],
},
} satisfies Preset.ThemeConfig,

Expand Down