Skip to content

Commit

Permalink
Remove user-provided-service from egress_proxy's setup
Browse files Browse the repository at this point in the history
  • Loading branch information
rahearn committed Nov 25, 2024
1 parent d4c0e8a commit 7153e77
Show file tree
Hide file tree
Showing 5 changed files with 28 additions and 97 deletions.
6 changes: 2 additions & 4 deletions egress_proxy/acl.tftpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
%{ for app, dests in list ~}
%{ for dest in dests ~}
${ split(":", dest)[0] }
%{ endfor ~}
%{ for dest in list ~}
${ split(":", dest)[0] }
%{ endfor ~}
32 changes: 2 additions & 30 deletions egress_proxy/main.tf
Original file line number Diff line number Diff line change
@@ -1,14 +1,5 @@
locals {
# Generate Caddy-compatible allow and deny ACLs, one target per line.
#
# For now, there's just one consolidated allowlist and denylist, no matter
# what apps they were specified for. Future improvments could improve this,
# but it would mean also changing the proxy to be both more complex (in terms
# of how the Caddyfile is constructed) and more discriminating (in terms of
# recognizing client apps based on GUIDs supplied by Envoy in request headers,
# as well as the destination ports). However, adding these improvements won't
# require modifying the module's interface, since we're already collecting
# that refined information.
allowacl = templatefile("${path.module}/acl.tftpl", { list = var.allowlist })
denyacl = templatefile("${path.module}/acl.tftpl", { list = var.denylist })

Expand Down Expand Up @@ -61,31 +52,12 @@ resource "cloudfoundry_app" "egress_app" {
}
}

###
### Create a credential service for bound clients to use when make requests of the proxy
###
locals {
https_proxy = "https://${random_uuid.username.result}:${random_password.password.result}@${local.egress_route}:61443"
http_proxy = "http://${random_uuid.username.result}:${random_password.password.result}@${local.egress_route}:8080"
domain = local.egress_route
username = random_uuid.username.result
password = random_password.password.result
protocol = "https"
port = 61443
}

resource "cloudfoundry_service_instance" "credentials" {
for_each = var.cf_client_spaces
name = "${var.name}-credentials"
space = each.value
type = "user-provided"
credentials = jsonencode({
"uri" = local.https_proxy
"http_uri" = local.http_proxy
"domain" = local.domain
"username" = local.username
"password" = local.password
"protocol" = local.protocol
"port" = local.port
})
https_port = 61443
http_port = 8080
}
25 changes: 11 additions & 14 deletions egress_proxy/outputs.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,21 @@ output "https_proxy" {
sensitive = true
}

output "http_proxy" {
value = local.http_proxy
sensitive = true
}

output "domain" {
value = local.domain
}

output "port" {
value = local.port
output "http_port" {
value = local.http_port
}

output "https_port" {
value = local.https_port
}

output "username" {
Expand All @@ -20,18 +29,6 @@ output "password" {
sensitive = true
}

output "protocol" {
value = local.protocol
}

output "app_id" {
value = cloudfoundry_app.egress_app.id
}

output "credential_service_ids" {
value = { for k, v in cloudfoundry_service_instance.credentials : k => v.id }
}

output "credential_service_name" {
value = values(cloudfoundry_service_instance.credentials)[0].name
}
41 changes: 7 additions & 34 deletions egress_proxy/tests/creation.tftest.hcl
Original file line number Diff line number Diff line change
@@ -1,30 +1,13 @@
mock_provider "cloudfoundry" {
mock_data "cloudfoundry_domain" {
defaults = {
id = "fea49b46-907f-4fe9-8700-ff6e2b438cd3"
}
}
mock_resource "cloudfoundry_route" {
defaults = {
url = "egress-proxy.apps.internal"
}
}
mock_resource "cloudfoundry_app" {
defaults = {
id = "28329663-10fd-4c5d-9b6b-25e3fb108929"
}
}
}
mock_provider "cloudfoundry" {}

variables {
cf_org_name = "gsa-tts-devtools-prototyping"
cf_egress_space = {
id = "5178d8f5-d19a-4782-ad07-467822480c68"
name = "terraform-cloudgov-ci-tests-egress"
}
cf_client_spaces = { "client-space" = "e243575e-376a-4b70-b891-23c3fa1a0680" }
name = "terraform-egress-app"
allowlist = { "continuous_monitoring-staging" = ["raw.githubusercontent.com:443"] }
name = "terraform-egress-app"
allowlist = ["raw.githubusercontent.com:443"]
}

run "test_proxy_creation" {
Expand All @@ -48,28 +31,18 @@ run "test_proxy_creation" {
error_message = "Output password must come from the random_password resource"
}

assert {
condition = output.protocol == "https"
error_message = "protocol only supports https"
}

assert {
condition = output.app_id == cloudfoundry_app.egress_app.id
error_message = "Output app_id is the egress_app's ID"
}

assert {
condition = output.port == 61443
error_message = "port only supports 61443 internal https listener"
}

assert {
condition = output.credential_service_ids == { "client-space" = cloudfoundry_service_instance.credentials["client-space"].id }
error_message = "Output credential_service_ids is a map of client_space_ids to credential_instance_ids"
condition = output.https_port == 61443
error_message = "https_port only supports 61443 internal https listener"
}

assert {
condition = output.credential_service_name == "${var.name}-credentials"
error_message = "Output credential_service_name is the single name shared by all of the credential services"
condition = output.http_port == 8080
error_message = "http_port reports port 8080 for plaintext"
}
}
21 changes: 6 additions & 15 deletions egress_proxy/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,6 @@ variable "cf_egress_space" {
description = "cloud.gov space egress"
}

variable "cf_client_spaces" {
type = map(string)
description = "map of cloud.gov space names to spaces ids for client apps"
}

variable "name" {
type = string
description = "name of the egress proxy application"
Expand All @@ -41,23 +36,19 @@ variable "allowports" {
}

variable "allowlist" {
description = "Allowed egress for apps (applied first). A map where keys are app names, and the values are sets of acl strings."
description = "Allowed egress for apps (applied first). A set of allowed acl strings."
# See the upstream documentation for possible acl strings:
# https://github.com/caddyserver/forwardproxy/blob/caddy2/README.md#caddyfile-syntax-server-configuration
type = map(set(string))
default = {
# appname = [ "*.example.com:443", "example2.com:443" ]
}
type = set(string)
default = [] # [ "*.example.com:443", "example2.com:443" ]
}

variable "denylist" {
description = "Denied egress for apps (applied second). A map where keys are app names, and the values are sets of host:port strings."
description = "Denied egress for apps (applied second). A set of disallowed host:port strings."
# See the upstream documentation for possible acl strings:
# https://github.com/caddyserver/forwardproxy/blob/caddy2/README.md#caddyfile-syntax-server-configuration
type = map(set(string))
default = {
# appname = [ "bad.example.com:443" ]
}
type = set(string)
default = [] # [ "bad.example.com:443" ]
}

variable "instances" {
Expand Down

0 comments on commit 7153e77

Please sign in to comment.