From 5edff452c91580978013949423b0b088d8a36a58 Mon Sep 17 00:00:00 2001 From: Byungjin Park Date: Thu, 21 Sep 2023 15:51:10 +0900 Subject: [PATCH] Support conditions for lattice-service-listeners --- modules/lattice-service-listener/README.md | 4 +- modules/lattice-service-listener/main.tf | 25 +++++++---- modules/lattice-service-listener/outputs.tf | 40 ++++++++++++----- modules/lattice-service-listener/variables.tf | 43 ++++++++++++++++--- modules/lattice-service/README.md | 2 +- modules/lattice-service/variables.tf | 15 +++++++ 6 files changed, 101 insertions(+), 28 deletions(-) diff --git a/modules/lattice-service-listener/README.md b/modules/lattice-service-listener/README.md index aa6e217..88d3df7 100644 --- a/modules/lattice-service-listener/README.md +++ b/modules/lattice-service-listener/README.md @@ -46,7 +46,7 @@ This module creates following resources. | [resource\_group\_description](#input\_resource\_group\_description) | (Optional) The description of Resource Group. | `string` | `"Managed by Terraform."` | no | | [resource\_group\_enabled](#input\_resource\_group\_enabled) | (Optional) Whether to create Resource Group to find and group AWS resources which are created by this module. | `bool` | `true` | no | | [resource\_group\_name](#input\_resource\_group\_name) | (Optional) The name of Resource Group. A Resource Group name can have a maximum of 127 characters, including letters, numbers, hyphens, dots, and underscores. The name cannot start with `AWS` or `aws`. | `string` | `""` | no | -| [rules](#input\_rules) | (Optional) The configuration for the parameters of the default routing action. `default_action_parameters` block as defined below.
(Optional) `status_code` - The status code of HTTP response. Valid values are `2XX`, `4XX`, or `5XX`. Defaults to `503`. Only supported if `default_action_type` is `FIXED_RESPONSE`.
(Required) `targets` - A list of target configurations to route traffic. To route to a single target group, use `default_action_type` as `FORWARD`. Only supported if `default_action_type` is `WEIGHTED_FORWARD`. Each item of `targets` block as defined below.
(Required) `target_group` - The ARN of the target group to which to route traffic.
(Optional) `weight` - The weight to use routing traffic to `target_group`. Valid value is `0` to `999`. Defaults to `1`. |
list(object({
priority = number
name = optional(string)

action_type = string
action_parameters = optional(object({
status_code = optional(number, 404)
destinations = optional(list(object({
target_group = string
weight = optional(number, 100)
})), [])
}), {})
}))
| `[]` | no | +| [rules](#input\_rules) | (Optional) A list of rules to enable content-based routing to the target groups that make up the service. Each rule consists of a priority, one or more actions, and one or more conditions.
Each block of `rules` block as defined below.
(Required) `priority` - The priority assigned to the rule. Each rule for a specific listener must have a unique priority. The lower the priority number the higher the priority.
(Optional) `name` - A rule name can describe the purpose of the rule or the type of traffic it is intended to handle. Rule names can't be changed after creation. Defaults to `$(service)-$(priority)`.
(Required) `conditions` - The rule conditions. `conditions` block as defined below.
(Optional) `method` - The condition of HTTP request method. Valid values are `GET`, `HEAD`, `POST`, `PUT`, `DELETE`, `CONNECT`, `OPTIONS`, `TRACE`, `PATCH`.
(Required) `path` - The condition of HTTP request path. `path` block as defined below.
(Required) `value` - The path pattern. The pattern must start with `/`.
(Optional) `operator` - The operator that you want to use to determine whether an HTTP request path matches the conditions. Valid values are `EXACT`, `PREFIX`. Defaults to `PREFIX`.
(Optional) `case_sensitive` - Whether to match the `value` condition using a case-sensitive match. Defaults to `false`.
(Optional) `headers` - The condition of HTTP request headers. Each block of `headers` as defined below.
(Required) `name` - The name of the HTTP header field.
(Required) `value` - The value of the HTTP header field.
(Optional) `operator` - The operator that you want to use to determine whether an HTTP header matches the conditions. Valid values are `EXACT`, `PREFIX`, `CONTAINS`. Defaults to `EXACT`.
(Optional) `case_sensitive` - Whether to match the `value` condition using a case-sensitive match. Defaults to `false`.
(Required) `action_type` - The action type for the rule of the service. Valid values are `FORWARD`, `FIXED_RESPONSE`.
(Optional) `action_parameters` - The configuration for the parameters of the routing action. `action_parameters` block as defined below.
(Optional) `status_code` - Custom HTTP status code to drop client requests and return a custom HTTP response. Valid values are `404`. Only supported if `action_type` is `FIXED_RESPONSE`.
(Optional) `destinations` - A list of one or more target groups to route traffic. Only supported if `action_type` is `FORWARD`. Each item of `destinations` block as defined below.
(Required) `target_group` - The ID or ARN of the target group to which to route traffic.
(Optional) `weight` - The weight to use routing traffic to `target_group`. how requests are distributed to the target group. Only required if you specify multiple target groups for a forward action. For example, if you specify two target groups, one with a weight of 10 and the other with a weight of 20, the target group with a weight of 20 receives twice as many requests as the other target group. Valid value is `0` to `999`. Defaults to `100`. |
list(object({
priority = number
name = optional(string)

conditions = object({
method = optional(string)
path = object({
value = string
operator = optional(string, "PREFIX")
case_sensitive = optional(bool, false)
})
headers = optional(list(object({
name = string
value = string
operator = optional(string, "EXACT")
case_sensitive = optional(bool, false)
})), [])
})

action_type = string
action_parameters = optional(object({
status_code = optional(number, 404)
destinations = optional(list(object({
target_group = string
weight = optional(number, 100)
})), [])
}), {})
}))
| `[]` | no | | [tags](#input\_tags) | (Optional) A map of tags to add to all resources. | `map(string)` | `{}` | no | ## Outputs @@ -60,7 +60,7 @@ This module creates following resources. | [name](#output\_name) | The name of the service listener. | | [port](#output\_port) | The number of port on which the listener of the service is listening. | | [protocol](#output\_protocol) | The protocol for the service listener. | -| [rules](#output\_rules) | The configuration for default routing action of the service listener.
`type` - The type of default routing action.
`parameters` - The configuration for the parameters of the default routing action. `default_action_parameters` block as defined below. | +| [rules](#output\_rules) | The list of rules to enable content-based routing to the target groups that make up the service.
`id` - Unique identifier for the listener rule.
`arn` - The ARN for the listener rule.
`priority` - The priority assigned to the listener rule.
`name` - The rule name to describe the purpose of the listener rule.
`conditions` - The rule conditions.
`method` - The condition of HTTP request method.
`path` - The condition of HTTP request path.
`headers` - The condition of HTTP request headers.
`action` - The action for the listener rule.
`type` - The action type for the rule of the service.
`parameters` - The configuration for the parameters of the routing action. | | [service](#output\_service) | The associated VPC Lattice service. | | [updated\_at](#output\_updated\_at) | Date and time that the listener was last updated, specified in ISO-8601 format. | diff --git a/modules/lattice-service-listener/main.tf b/modules/lattice-service-listener/main.tf index 41c18fd..9552eb3 100644 --- a/modules/lattice-service-listener/main.tf +++ b/modules/lattice-service-listener/main.tf @@ -94,22 +94,31 @@ resource "aws_vpclattice_listener_rule" "this" { match { http_match { + method = each.value.conditions.method - header_matches { - name = "example-header" - case_sensitive = false + path_match { + case_sensitive = each.value.conditions.path.case_sensitive match { - exact = "example-contains" + exact = each.value.conditions.path.operator == "EXACT" ? each.value.conditions.path.value : null + prefix = each.value.conditions.path.operator == "PREFIX" ? each.value.conditions.path.value : null } } - path_match { - case_sensitive = true - match { - prefix = "/example-path" + dynamic "header_matches" { + for_each = each.value.conditions.headers + + content { + name = header_matches.value.name + case_sensitive = header_matches.value.case_sensitive + + match { + exact = header_matches.value.operator == "EXACT" ? header_matches.value.value : null + prefix = header_matches.value.operator == "PREFIX" ? header_matches.value.value : null + } } } + } } diff --git a/modules/lattice-service-listener/outputs.tf b/modules/lattice-service-listener/outputs.tf index 50860e6..ea19e34 100644 --- a/modules/lattice-service-listener/outputs.tf +++ b/modules/lattice-service-listener/outputs.tf @@ -48,13 +48,20 @@ output "default_action" { } } -# TODO: Update Docs -# TODO: Support Match output "rules" { description = < v - if !contains(["name", "priority", "rule_id", "id", "arn", "listener_identifier", "service_identifier", "tags", "tags_all", "timeouts", "action"], k) - } } } } diff --git a/modules/lattice-service-listener/variables.tf b/modules/lattice-service-listener/variables.tf index 264392f..0d00ad1 100644 --- a/modules/lattice-service-listener/variables.tf +++ b/modules/lattice-service-listener/variables.tf @@ -84,20 +84,49 @@ variable "default_action_parameters" { } } -# TODO: Update Docs -# TODO: Support Match variable "rules" { description = < [auth\_type](#input\_auth\_type) | (Optional) The type of authentication and authorization that manages client access to the service. Valid values are `AWS_IAM` or `NONE`. Defaults to `NONE`.
`NONE` - Authentication and authorization is turned off at the service level. Access to this service remains subject to the service network policy, if present. If a policy is not present, all traffic from VPCs associated to the service network is allowed.
`AWS_IAM` - Applies an AWS IAM resource policy on the service giving service owners the ability to enforce authentication and write fine grained permissions. This policy is evaluated in addition to any policy present at the service network. | `string` | `"NONE"` | no | | [custom\_domain](#input\_custom\_domain) | (Optional) The configuration for a custom domain name to use in addition to the domain name that is generated by VPC Lattice. For HTTPS requests, you must also specify an SSL/TLS certificate that matches the custom domain name. If you specify a custom domain name, you must configure DNS routing after your service is created. This is to map DNS queries for the custom domain name to the VPC Lattice endpoint. If you’re using Route 53 as your DNS service, you can configure a CNAME record within the hosted zone that you own. `custom_domain` as defined below.
(Required) `name` - The name of the custom domain. The custom domain name will be used in addition to the domain name that VPC Lattice generates for the service. You can't change the custom domain name after the service is created. For a custom domain name change, you would need to create a new service.
(Optional) `tls_certificate` - The ARN (Amazon Resource Name) of the SSL/TLS certificate. The certificate will be required to process HTTPS requests for the custom domain name. |
object({
name = string
tls_certificate = optional(string)
})
| `null` | no | | [description](#input\_description) | (Optional) The description of the service. This creates a tag with a key of `Description` and a value that you specify. | `string` | `"Managed by Terraform."` | no | -| [listeners](#input\_listeners) | (Optional) The configuration to add one or more listeners for the service. Set up listeners and rules to define how network traffic is routed within the service. A listener is a process that checks for connection requests, using the protocol and port that you configure. Each listener has a default action, and you can optionally define rules to enable content-based routing to the target groups that make up your service. Each block of `listeners` as defined below.
(Required) `name` - The name of the service listener. The name must be unique within the service. The valid characters are a-z, 0-9, and hyphens (-). You can't use a hyphen as the first or last character, or immediately after another hyphen.
(Optional) `port` - The number of port on which the listener of the service is listening. Valid values are from `1` to `65535`. If `port` is not specified and `protocol` is `HTTP`, the value will default to `80`. If `port` is not specified and `protocol` is `HTTPS`, the value will default to `443`.
(Required) `protocol` - The protocol for the service listener. Valid values are `HTTP` and `HTTPS`.
(Required) `default_action_type` - The type of default routing action. Default action apply to traffic that does not meet the conditions of rules on your listener. Rules can be configured after the listener is created. Valid values are `FORWARD`, `FIXED_RESPONSE`.
(Optional) `default_action_parameters` - The configuration for the parameters of the default routing action. `default_action_parameters` block as defined below.
(Optional) `status_code` - Custom HTTP status code to drop client requests and return a custom HTTP response. Valid values are `404`. Only supported if `default_action_type` is `FIXED_RESPONSE`.
(Optional) `destinations` - A list of one or more target groups to route traffic. Only supported if `default_action_type` is `FORWARD`. Each item of `destinations` block as defined below.
(Required) `target_group` - The ID or ARN of the target group to which to route traffic.
(Optional) `weight` - The weight to use routing traffic to `target_group`. how requests are distributed to the target group. Only required if you specify multiple target groups for a forward action. For example, if you specify two target groups, one with a weight of 10 and the other with a weight of 20, the target group with a weight of 20 receives twice as many requests as the other target group. Valid value is `0` to `999`. Defaults to `100`.
(Optional) `rules` -
(Optional) `tags` - A map of tags to add to the service listeners. |
list(object({
name = string
port = optional(number)
protocol = string

default_action_type = string
default_action_parameters = optional(object({
status_code = optional(number, 404)
destinations = optional(list(object({
target_group = string
weight = optional(number, 100)
})), [])
}), {})

rules = optional(list(object({
priority = number
name = optional(string)

action_type = string
action_parameters = optional(object({
status_code = optional(number, 404)
destinations = optional(list(object({
target_group = string
weight = optional(number, 100)
})), [])
}), {})
})), [])

tags = optional(map(string), {})
}))
| `[]` | no | +| [listeners](#input\_listeners) | (Optional) The configuration to add one or more listeners for the service. Set up listeners and rules to define how network traffic is routed within the service. A listener is a process that checks for connection requests, using the protocol and port that you configure. Each listener has a default action, and you can optionally define rules to enable content-based routing to the target groups that make up your service. Each block of `listeners` as defined below.
(Required) `name` - The name of the service listener. The name must be unique within the service. The valid characters are a-z, 0-9, and hyphens (-). You can't use a hyphen as the first or last character, or immediately after another hyphen.
(Optional) `port` - The number of port on which the listener of the service is listening. Valid values are from `1` to `65535`. If `port` is not specified and `protocol` is `HTTP`, the value will default to `80`. If `port` is not specified and `protocol` is `HTTPS`, the value will default to `443`.
(Required) `protocol` - The protocol for the service listener. Valid values are `HTTP` and `HTTPS`.
(Required) `default_action_type` - The type of default routing action. Default action apply to traffic that does not meet the conditions of rules on your listener. Rules can be configured after the listener is created. Valid values are `FORWARD`, `FIXED_RESPONSE`.
(Optional) `default_action_parameters` - The configuration for the parameters of the default routing action. `default_action_parameters` block as defined below.
(Optional) `status_code` - Custom HTTP status code to drop client requests and return a custom HTTP response. Valid values are `404`. Only supported if `default_action_type` is `FIXED_RESPONSE`.
(Optional) `destinations` - A list of one or more target groups to route traffic. Only supported if `default_action_type` is `FORWARD`. Each item of `destinations` block as defined below.
(Required) `target_group` - The ID or ARN of the target group to which to route traffic.
(Optional) `weight` - The weight to use routing traffic to `target_group`. how requests are distributed to the target group. Only required if you specify multiple target groups for a forward action. For example, if you specify two target groups, one with a weight of 10 and the other with a weight of 20, the target group with a weight of 20 receives twice as many requests as the other target group. Valid value is `0` to `999`. Defaults to `100`.
(Optional) `rules` -
(Optional) `tags` - A map of tags to add to the service listeners. |
list(object({
name = string
port = optional(number)
protocol = string

default_action_type = string
default_action_parameters = optional(object({
status_code = optional(number, 404)
destinations = optional(list(object({
target_group = string
weight = optional(number, 100)
})), [])
}), {})

rules = optional(list(object({
priority = number
name = optional(string)

conditions = object({
method = optional(string)
path = object({
value = string
operator = optional(string, "PREFIX")
case_sensitive = optional(bool, false)
})
headers = optional(list(object({
name = string
value = string
operator = optional(string, "EXACT")
case_sensitive = optional(bool, false)
})), [])
})

action_type = string
action_parameters = optional(object({
status_code = optional(number, 404)
destinations = optional(list(object({
target_group = string
weight = optional(number, 100)
})), [])
}), {})
})), [])

tags = optional(map(string), {})
}))
| `[]` | no | | [logging\_to\_cloudwatch](#input\_logging\_to\_cloudwatch) | (Optional) The configuration to enable access logs to be sent to Amazon CloudWatch Log Group. The service owner can use the access logs to audit the services in the network. The service owner will only see access logs from clients and services that are associated with their service. Access log entries represent traffic originated from VPCs associated with that network. `logging_to_cloudwatch` as defined below.
(Optional) `enabled` - Whether to enable access logs to be sent to Amazon CloudWatch Log Group.
(Optional) `log_group` - The ARN (Amazon Resource Name) of the CloudWatch Log Group. |
object({
enabled = optional(bool, false)
log_group = optional(string, "")
})
| `{}` | no | | [logging\_to\_kinesis\_data\_firehose](#input\_logging\_to\_kinesis\_data\_firehose) | (Optional) The configuration to enable access logs to be sent to Amazon Kinesis Data Firehose. The service owner can use the access logs to audit the services in the network. The service owner will only see access logs from clients and services that are associated with their service. Access log entries represent traffic originated from VPCs associated with that network. `logging_to_kinesis_data_firehose` as defined below.
(Optional) `enabled` - Whether to enable access logs to be sent to Amazon Kinesis Data
Firehose.
(Optional) `delivery_stream` - The ARN (Amazon Resource Name) of the Kinesis Data Firehose
delivery stream. |
object({
enabled = optional(bool, false)
delivery_stream = optional(string, "")
})
| `{}` | no | | [logging\_to\_s3](#input\_logging\_to\_s3) | (Optional) The configuration to enable access logs to be sent to Amazon S3 Bucket. The service owner can use the access logs to audit the services in the network. The service owner will only see access logs from clients and services that are associated with their service. Access log entries represent traffic originated from VPCs associated with that network. `logging_to_s3` as defined below.
(Optional) `enabled` - Whether to enable access logs to be sent to Amazon S3 Bucket.
(Optional) `bucket` - The ARN (Amazon Resource Name) of the S3 Bucket. |
object({
enabled = optional(bool, false)
bucket = optional(string, "")
})
| `{}` | no | diff --git a/modules/lattice-service/variables.tf b/modules/lattice-service/variables.tf index f9efe05..10e4ad1 100644 --- a/modules/lattice-service/variables.tf +++ b/modules/lattice-service/variables.tf @@ -125,6 +125,21 @@ variable "listeners" { priority = number name = optional(string) + conditions = object({ + method = optional(string) + path = object({ + value = string + operator = optional(string, "PREFIX") + case_sensitive = optional(bool, false) + }) + headers = optional(list(object({ + name = string + value = string + operator = optional(string, "EXACT") + case_sensitive = optional(bool, false) + })), []) + }) + action_type = string action_parameters = optional(object({ status_code = optional(number, 404)