Skip to content

Commit

Permalink
fix: make synthetics use additional_hostnames (#2944)
Browse files Browse the repository at this point in the history
* fix: make synthetics use additional_hostnames

* refactor skip ports for linkerd

* commit from ci -- ran terraform-docs and pushed

* synthetics

* docs

* follow redirects

* follow redirects

* commit from ci -- ran terraform-docs and pushed

* skip ports

* we don't actually want follow redirect

* reset typical app

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
jakeyheath and github-actions[bot] authored Jan 12, 2024
1 parent 55d2436 commit 12ce1b8
Show file tree
Hide file tree
Showing 7 changed files with 35 additions and 5 deletions.
1 change: 1 addition & 0 deletions terraform/modules/happy-service-eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
| <a name="input_init_containers"></a> [init\_containers](#input\_init\_containers) | Map of init containers to bootstrap the service | <pre>map(object({<br> image : string<br> tag : string<br> cmd : optional(list(string), [])<br> }))</pre> | `{}` | no |
| <a name="input_initial_delay_seconds"></a> [initial\_delay\_seconds](#input\_initial\_delay\_seconds) | The initial delay in seconds for the liveness and readiness probes. | `number` | `30` | no |
| <a name="input_k8s_namespace"></a> [k8s\_namespace](#input\_k8s\_namespace) | K8S namespace for this service | `string` | n/a | yes |
| <a name="input_linkerd_additional_skip_ports"></a> [linkerd\_additional\_skip\_ports](#input\_linkerd\_additional\_skip\_ports) | Additional ports to skip protocol analysis on for outbound traffic. Defaults include [25, 587, 3306, 4444, 4567, 4568, 5432, 6379, 9300, 11211] | `set(number)` | `[]` | no |
| <a name="input_liveness_timeout_seconds"></a> [liveness\_timeout\_seconds](#input\_liveness\_timeout\_seconds) | Timeout for liveness probe. | `number` | `30` | no |
| <a name="input_max_count"></a> [max\_count](#input\_max\_count) | The maximum number of instances of this task that should be running across our cluster | `number` | `2` | no |
| <a name="input_max_unavailable_count"></a> [max\_unavailable\_count](#input\_max\_unavailable\_count) | The maximum number or percentage of pods that can be unavailable during a rolling update. For example: `1` or `20%` | `string` | `"1"` | no |
Expand Down
18 changes: 15 additions & 3 deletions terraform/modules/happy-service-eks/main.tf
Original file line number Diff line number Diff line change
@@ -1,8 +1,20 @@
data "aws_region" "current" {}

locals {
tags_string = join(",", [for key, val in local.routing_tags : "${key}=${val}"])
service_type = (var.routing.service_type == "PRIVATE" || var.routing.service_mesh) ? "ClusterIP" : "NodePort"
base_default_skip_ports = [
# Database: Mysql, Postgres, Redis, Elasticsearch, Memcached
3306, 5432, 6379, 9300, 11211,

# IBM databases?
4444, 4567, 4568,

# Email: SMTP, SMTPS, SES
587, 25, 2525, 465, 2465,
]
skip_ports = toset(concat(local.base_default_skip_ports, tolist(var.linkerd_additional_skip_ports)))
skip_ports_str = join(",", local.skip_ports)
tags_string = join(",", [for key, val in local.routing_tags : "${key}=${val}"])
service_type = (var.routing.service_type == "PRIVATE" || var.routing.service_mesh) ? "ClusterIP" : "NodePort"
match_labels = {
app = var.routing.service_name
}
Expand Down Expand Up @@ -92,7 +104,7 @@ resource "kubernetes_deployment_v1" "deployment" {
"linkerd.io/inject" = "enabled"
"config.linkerd.io/default-inbound-policy" = "all-authenticated"
//Skipping all ports listed here https://linkerd.io/2.13/features/protocol-detection/
"config.linkerd.io/skip-outbound-ports" = "25,587,3306,4444,4567,4568,5432,6379,9300,11211"
"config.linkerd.io/skip-outbound-ports" = local.skip_ports_str
} : {})
}

Expand Down
6 changes: 6 additions & 0 deletions terraform/modules/happy-service-eks/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -396,3 +396,9 @@ variable "max_unavailable_count" {
description = "The maximum number or percentage of pods that can be unavailable during a rolling update. For example: `1` or `20%`"
default = "1"
}

variable "linkerd_additional_skip_ports" {
type = set(number)
description = "Additional ports to skip protocol analysis on for outbound traffic. Defaults include [25, 587, 3306, 4444, 4567, 4568, 5432, 6379, 9300, 11211]"
default = []
}
2 changes: 1 addition & 1 deletion terraform/modules/happy-stack-eks/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
| <a name="input_image_tags"></a> [image\_tags](#input\_image\_tags) | Override image tag for each docker image | `map(string)` | `{}` | no |
| <a name="input_k8s_namespace"></a> [k8s\_namespace](#input\_k8s\_namespace) | K8S namespace for this stack | `string` | n/a | yes |
| <a name="input_routing_method"></a> [routing\_method](#input\_routing\_method) | Traffic routing method for this stack. Valid options are 'DOMAIN', when every service gets a unique domain name, or a 'CONTEXT' when all services share the same domain name, and routing is done by request path. | `string` | `"DOMAIN"` | no |
| <a name="input_services"></a> [services](#input\_services) | The services you want to deploy as part of this stack. | <pre>map(object({<br> name : string,<br> service_type : optional(string, "INTERNAL"),<br> allow_mesh_services : optional(list(object({<br> service : optional(string, null),<br> stack : optional(string, null),<br> service_account_name : optional(string, null)<br> })), null),<br> ingress_security_groups : optional(list(string), []), // Only used for VPC service_type<br> alb : optional(object({<br> name : string,<br> listener_port : number,<br> }), null), // Only used for TARGET_GROUP_ONLY<br> desired_count : optional(number, 2),<br> max_count : optional(number, 5),<br> max_unavailable_count : optional(string, "1"),<br> scaling_cpu_threshold_percentage : optional(number, 80),<br> port : optional(number, 80),<br> scheme : optional(string, "HTTP"),<br> cmd : optional(list(string), []),<br> args : optional(list(string), []),<br> image_pull_policy : optional(string, "IfNotPresent"), // Supported values: IfNotPresent, Always, Never<br> tag_mutability : optional(bool, true),<br> scan_on_push : optional(bool, false),<br> service_port : optional(number, null),<br> service_scheme : optional(string, "HTTP"),<br> memory : optional(string, "500Mi"),<br> memory_requests : optional(string, "200Mi"),<br> cpu : optional(string, "1"),<br> cpu_requests : optional(string, "500m"),<br> gpu : optional(number, null), // Whole number of GPUs to request, 0 will schedule all available GPUs. Requires GPU-enabled nodes in the cluster, `k8s-device-plugin` installed, platform_architecture = "amd64", and additional_node_selectors = { "nvidia.com/gpu.present" = "true" } present.<br> health_check_path : optional(string, "/"),<br> aws_iam : optional(object({<br> policy_json : optional(string, ""),<br> service_account_name : optional(string, null),<br> }), {}),<br> path : optional(string, "/*"), // Only used for CONTEXT and TARGET_GROUP_ONLY routing<br> priority : optional(number, 0), // Only used for CONTEXT and TARGET_GROUP_ONLY routing<br> success_codes : optional(string, "200-499"),<br> synthetics : optional(bool, false),<br> initial_delay_seconds : optional(number, 30),<br> alb_idle_timeout : optional(number, 60) // in seconds<br> period_seconds : optional(number, 3),<br> liveness_timeout_seconds : optional(number, 30),<br> readiness_timeout_seconds : optional(number, 30),<br> platform_architecture : optional(string, "amd64"), // Supported values: amd64, arm64; GPU nodes are amd64 only.<br> additional_node_selectors : optional(map(string), {}), // For GPU use: { "nvidia.com/gpu.present" = "true" }<br> bypasses : optional(map(object({ // Only used for INTERNAL service_type<br> paths = optional(set(string), [])<br> methods = optional(set(string), [])<br> })), {})<br> sidecars : optional(map(object({<br> image : string<br> tag : string<br> cmd : optional(list(string), [])<br> args : optional(list(string), [])<br> port : optional(number, 80)<br> scheme : optional(string, "HTTP")<br> memory : optional(string, "200Mi")<br> cpu : optional(string, "500m")<br> image_pull_policy : optional(string, "IfNotPresent") // Supported values: IfNotPresent, Always, Never<br> health_check_path : optional(string, "/")<br> initial_delay_seconds : optional(number, 30)<br> period_seconds : optional(number, 3)<br> liveness_timeout_seconds : optional(number, 30)<br> readiness_timeout_seconds : optional(number, 30)<br> })), {})<br> init_containers : optional(map(object({<br> image : string<br> tag : string<br> cmd : optional(list(string), []),<br> })), {})<br> additional_env_vars : optional(map(string), {}),<br> }))</pre> | n/a | yes |
| <a name="input_services"></a> [services](#input\_services) | The services you want to deploy as part of this stack. | <pre>map(object({<br> name : string,<br> service_type : optional(string, "INTERNAL"),<br> allow_mesh_services : optional(list(object({<br> service : optional(string, null),<br> stack : optional(string, null),<br> service_account_name : optional(string, null)<br> })), null),<br> ingress_security_groups : optional(list(string), []), // Only used for VPC service_type<br> alb : optional(object({<br> name : string,<br> listener_port : number,<br> }), null), // Only used for TARGET_GROUP_ONLY<br> desired_count : optional(number, 2),<br> max_count : optional(number, 5),<br> max_unavailable_count : optional(string, "1"),<br> scaling_cpu_threshold_percentage : optional(number, 80),<br> port : optional(number, 80),<br> scheme : optional(string, "HTTP"),<br> cmd : optional(list(string), []),<br> args : optional(list(string), []),<br> image_pull_policy : optional(string, "IfNotPresent"), // Supported values: IfNotPresent, Always, Never<br> tag_mutability : optional(bool, true),<br> scan_on_push : optional(bool, false),<br> service_port : optional(number, null),<br> service_scheme : optional(string, "HTTP"),<br> linkerd_additional_skip_ports : optional(set(number), []),<br> memory : optional(string, "500Mi"),<br> memory_requests : optional(string, "200Mi"),<br> cpu : optional(string, "1"),<br> cpu_requests : optional(string, "500m"),<br> gpu : optional(number, null), // Whole number of GPUs to request, 0 will schedule all available GPUs. Requires GPU-enabled nodes in the cluster, `k8s-device-plugin` installed, platform_architecture = "amd64", and additional_node_selectors = { "nvidia.com/gpu.present" = "true" } present.<br> health_check_path : optional(string, "/"),<br> aws_iam : optional(object({<br> policy_json : optional(string, ""),<br> service_account_name : optional(string, null),<br> }), {}),<br> path : optional(string, "/*"), // Only used for CONTEXT and TARGET_GROUP_ONLY routing<br> priority : optional(number, 0), // Only used for CONTEXT and TARGET_GROUP_ONLY routing<br> success_codes : optional(string, "200-499"),<br> synthetics : optional(bool, false),<br> initial_delay_seconds : optional(number, 30),<br> alb_idle_timeout : optional(number, 60) // in seconds<br> period_seconds : optional(number, 3),<br> liveness_timeout_seconds : optional(number, 30),<br> readiness_timeout_seconds : optional(number, 30),<br> platform_architecture : optional(string, "amd64"), // Supported values: amd64, arm64; GPU nodes are amd64 only.<br> additional_node_selectors : optional(map(string), {}), // For GPU use: { "nvidia.com/gpu.present" = "true" }<br> bypasses : optional(map(object({ // Only used for INTERNAL service_type<br> paths = optional(set(string), [])<br> methods = optional(set(string), [])<br> })), {})<br> sidecars : optional(map(object({<br> image : string<br> tag : string<br> cmd : optional(list(string), [])<br> args : optional(list(string), [])<br> port : optional(number, 80)<br> scheme : optional(string, "HTTP")<br> memory : optional(string, "200Mi")<br> cpu : optional(string, "500m")<br> image_pull_policy : optional(string, "IfNotPresent") // Supported values: IfNotPresent, Always, Never<br> health_check_path : optional(string, "/")<br> initial_delay_seconds : optional(number, 30)<br> period_seconds : optional(number, 3)<br> liveness_timeout_seconds : optional(number, 30)<br> readiness_timeout_seconds : optional(number, 30)<br> })), {})<br> init_containers : optional(map(object({<br> image : string<br> tag : string<br> cmd : optional(list(string), []),<br> })), {})<br> additional_env_vars : optional(map(string), {}),<br> }))</pre> | n/a | yes |
| <a name="input_skip_config_injection"></a> [skip\_config\_injection](#input\_skip\_config\_injection) | Skip injecting app configs into the services / tasks | `bool` | `false` | no |
| <a name="input_stack_name"></a> [stack\_name](#input\_stack\_name) | Happy Path stack name | `string` | n/a | yes |
| <a name="input_stack_prefix"></a> [stack\_prefix](#input\_stack\_prefix) | Do bucket storage paths and db schemas need to be prefixed with the stack name? (Usually '/{stack\_name}' for dev stacks, and '' for staging/prod stacks) | `string` | `""` | no |
Expand Down
1 change: 1 addition & 0 deletions terraform/modules/happy-stack-eks/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ module "services" {
sidecars = each.value.sidecars
init_containers = each.value.init_containers
ingress_security_groups = each.value.ingress_security_groups
linkerd_additional_skip_ports = each.value.linkerd_additional_skip_ports

routing = {
method = var.routing_method
Expand Down
11 changes: 10 additions & 1 deletion terraform/modules/happy-stack-eks/synthetics.tf
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,18 @@ locals {
# this is making an assumption that the health check path is accessible to the internet
# if this is a non-prod OIDC protected stack, make sure to allow the health check endpoint
# through the OIDC proxy.
synthetics = { for k, v in local.service_definitions : v.service_name =>
base_synthetics = { for k, v in local.service_definitions : v.service_name =>
var.routing_method == "DOMAIN" ? "https://${v.service_name}.${local.external_dns}${v.health_check_path}" : "https://${var.stack_name}.${local.external_dns}${v.health_check_path}"
if v.synthetics && (v.service_type == "EXTERNAL" || v.service_type == "INTERNAL")
}
# If you are using a custom domain, you can add additional_hostnames. This will make only 1 synthetic per additonal_hostname per service
# and no synthetics to the internal URLs created for the services.
additional_hosts_synthetics = merge([for k, v in local.service_definitions :
{ for domain in var.additional_hostnames : v.service_name => "https://${domain}${v.health_check_path}" }
]...)


synthetics = length(var.additional_hostnames) == 0 ? local.base_synthetics : local.additional_hosts_synthetics
opsgenie_owner = "${local.secret["tags"]["project"]}-${local.secret["tags"]["env"]}-${local.secret["tags"]["service"]}"
}

Expand All @@ -15,6 +23,7 @@ resource "datadog_synthetics_test" "test_api" {
for_each = local.synthetics
type = "api"
subtype = "http"

request_definition {
method = "GET"
url = each.value
Expand Down
1 change: 1 addition & 0 deletions terraform/modules/happy-stack-eks/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ variable "services" {
scan_on_push : optional(bool, false),
service_port : optional(number, null),
service_scheme : optional(string, "HTTP"),
linkerd_additional_skip_ports : optional(set(number), []),
memory : optional(string, "500Mi"),
memory_requests : optional(string, "200Mi"),
cpu : optional(string, "1"),
Expand Down

0 comments on commit 12ce1b8

Please sign in to comment.