Skip to content

Commit 848f660

Browse files
committed
NDR-213 Add mTLS api gateway
1 parent a866b9c commit 848f660

File tree

4 files changed

+173
-0
lines changed

4 files changed

+173
-0
lines changed

infrastructure/acm_certificate.tf

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
resource "aws_acm_certificate" "mtls_api_gateway_cert" {
2+
domain_name = local.mtls_api_gateway_full_domain_name
3+
validation_method = "DNS"
4+
5+
lifecycle {
6+
create_before_destroy = true
7+
}
8+
}
9+
10+
# Record used by ACM for DNS Validation
11+
resource "aws_route53_record" "validation" {
12+
for_each = {
13+
for dvo in aws_acm_certificate.mtls_api_gateway_cert.domain_validation_options : dvo.domain_name => {
14+
name = dvo.resource_record_name
15+
record = dvo.resource_record_value
16+
type = dvo.resource_record_type
17+
}
18+
}
19+
20+
allow_overwrite = true
21+
name = each.value.name
22+
records = [each.value.record]
23+
ttl = 60
24+
type = each.value.type
25+
zone_id = module.route53_fargate_ui.zone_id #todo change to mtls rute 53
26+
}
27+
28+
29+
resource "aws_acm_certificate_validation" "mtls_api_gateway_cert" {
30+
certificate_arn = aws_acm_certificate.mtls_api_gateway_cert.arn
31+
validation_record_fqdns = [for record in aws_route53_record.validation : record.fqdn]
32+
}

infrastructure/api_mtls.tf

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
# New API Gateway for mTLS
2+
resource "aws_api_gateway_rest_api" "ndr_doc_store_api_mtls" {
3+
name = "${terraform.workspace}-DocStoreAPI-mTLS"
4+
description = "Docuemnt store API with mTLS enabled"
5+
6+
tags = {
7+
Name = "${terraform.workspace}-docstore-api-mtls"
8+
Owner = var.owner
9+
Environment = var.environment
10+
Workspace = terraform.workspace
11+
}
12+
}
13+
14+
resource "aws_api_gateway_domain_name" "custom_api_domain_mtls" {
15+
domain_name = local.mtls_api_gateway_full_domain_name
16+
regional_certificate_arn = aws_acm_certificate_validation.mtls_api_gateway_cert.certificate_arn
17+
security_policy = "TLS_1_2"
18+
19+
endpoint_configuration {
20+
types = ["REGIONAL"]
21+
}
22+
23+
mutual_tls_authentication {
24+
truststore_uri = "s3://${terraform.workspace}-${var.truststore_bucket_name}/${var.ca_pem_filename}"
25+
}
26+
}
27+
28+
resource "aws_api_gateway_base_path_mapping" "api_mapping_mtls" {
29+
api_id = aws_api_gateway_rest_api.ndr_doc_store_api_mtls.id
30+
stage_name = var.environment
31+
domain_name = aws_api_gateway_domain_name.custom_api_domain_mtls.domain_name
32+
33+
depends_on = [aws_api_gateway_deployment.ndr_api_deploy_mtls]
34+
}
35+
36+
resource "aws_api_gateway_deployment" "ndr_api_deploy_mtls" {
37+
rest_api_id = aws_api_gateway_rest_api.ndr_doc_store_api_mtls.id
38+
39+
depends_on = [
40+
aws_api_gateway_rest_api.ndr_doc_store_api_mtls,
41+
]
42+
43+
lifecycle {
44+
create_before_destroy = true
45+
}
46+
47+
variables = {
48+
deployed_at = timestamp()
49+
}
50+
}
51+
52+
resource "aws_api_gateway_stage" "ndr_api_mtls" {
53+
deployment_id = aws_api_gateway_deployment.ndr_api_deploy_mtls.id
54+
rest_api_id = aws_api_gateway_rest_api.ndr_doc_store_api_mtls.id
55+
stage_name = var.environment
56+
xray_tracing_enabled = var.enable_xray_tracing
57+
}
58+
59+
resource "aws_cloudwatch_log_group" "mtls_api_gateway_stage" {
60+
name = "API-Gateway-Execution-Logs_${aws_api_gateway_rest_api.ndr_doc_store_api_mtls.id}/${var.environment}"
61+
retention_in_days = 0
62+
depends_on = [
63+
aws_api_gateway_account.logging
64+
]
65+
}
66+
67+
resource "aws_api_gateway_method_settings" "mtls_api_gateway_stage" {
68+
rest_api_id = aws_api_gateway_rest_api.ndr_doc_store_api_mtls.id
69+
stage_name = aws_api_gateway_stage.ndr_api_mtls.stage_name
70+
method_path = "*/*"
71+
72+
settings {
73+
logging_level = "INFO"
74+
metrics_enabled = true
75+
data_trace_enabled = true
76+
}
77+
}
78+
79+
resource "aws_api_gateway_gateway_response" "unauthorised_response_mtls" {
80+
rest_api_id = aws_api_gateway_rest_api.ndr_doc_store_api_mtls.id
81+
response_type = "DEFAULT_4XX"
82+
83+
response_templates = {
84+
"application/json" = "{\"message\":$context.error.messageString}"
85+
}
86+
87+
response_parameters = {
88+
"gatewayresponse.header.Access-Control-Allow-Origin" = contains(["prod"], terraform.workspace) ? "'https://${var.domain}'" : "'https://${terraform.workspace}.${var.domain}'"
89+
"gatewayresponse.header.Access-Control-Allow-Methods" = "'*'"
90+
"gatewayresponse.header.Access-Control-Allow-Headers" = "'Content-Type,X-Amz-Date,Authorization,X-Auth,X-Api-Key,X-Amz-Security-Token,X-Auth-Cookie,Accept'"
91+
"gatewayresponse.header.Access-Control-Allow-Credentials" = "'true'"
92+
}
93+
}
94+
95+
resource "aws_api_gateway_gateway_response" "bad_gateway_response_mtls" {
96+
rest_api_id = aws_api_gateway_rest_api.ndr_doc_store_api_mtls.id
97+
response_type = "DEFAULT_5XX"
98+
99+
response_templates = {
100+
"application/json" = "{\"message\":$context.error.messageString}"
101+
}
102+
103+
response_parameters = {
104+
"gatewayresponse.header.Access-Control-Allow-Origin" = contains(["prod"], terraform.workspace) ? "'https://${var.domain}'" : "'https://${terraform.workspace}.${var.domain}'"
105+
"gatewayresponse.header.Access-Control-Allow-Methods" = "'*'"
106+
"gatewayresponse.header.Access-Control-Allow-Headers" = "'Content-Type,X-Amz-Date,Authorization,X-Auth,X-Api-Key,X-Amz-Security-Token,X-Auth-Cookie,Accept'"
107+
"gatewayresponse.header.Access-Control-Allow-Credentials" = "'true'"
108+
}
109+
}
110+
111+
module "mtls_api_endpoint_url_ssm_parameter" {
112+
source = "./modules/ssm_parameter"
113+
name = "api_endpoint_mtls"
114+
description = "mTLS api endpoint URL for ${var.environment}"
115+
resource_depends_on = aws_api_gateway_deployment.ndr_api_deploy_mtls
116+
value = "https://${aws_api_gateway_base_path_mapping.api_mapping_mtls.domain_name}"
117+
type = "SecureString"
118+
owner = var.owner
119+
environment = var.environment
120+
}

infrastructure/route53.tf

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,15 @@ module "route53_fargate_ui" {
1010
api_gateway_full_domain_name = aws_api_gateway_domain_name.custom_api_domain.regional_domain_name
1111
api_gateway_zone_id = aws_api_gateway_domain_name.custom_api_domain.regional_zone_id
1212
}
13+
14+
resource "aws_route53_record" "ndr_mtls_api_record" {
15+
name = local.mtls_api_gateway_full_domain_name
16+
type = "A"
17+
zone_id = module.route53_fargate_ui.zone_id
18+
19+
alias {
20+
name = aws_api_gateway_domain_name.custom_api_domain_mtls.regional_domain_name
21+
zone_id = aws_api_gateway_domain_name.custom_api_domain_mtls.regional_zone_id
22+
evaluate_target_health = true
23+
}
24+
}

infrastructure/variable.tf

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,12 @@ variable "truststore_bucket_name" {
6363
default = "ndr-truststore"
6464
}
6565

66+
variable "ca_pem_filename" {
67+
type = string
68+
description = "Filename of the CA Truststore pem file stored in the core Truststore s3 bucket"
69+
default = "ndr-truststore.pem"
70+
}
71+
6672
# DynamoDB Table Variables
6773

6874
variable "pdm_dynamodb_table_name" {
@@ -219,6 +225,9 @@ locals {
219225
api_gateway_subdomain_name = contains(["prod"], terraform.workspace) ? "${var.certificate_subdomain_name_prefix}" : "${var.certificate_subdomain_name_prefix}${terraform.workspace}"
220226
api_gateway_full_domain_name = contains(["prod"], terraform.workspace) ? "${var.certificate_subdomain_name_prefix}${var.domain}" : "${var.certificate_subdomain_name_prefix}${terraform.workspace}.${var.domain}"
221227

228+
mtls_api_gateway_subdomain_name = contains(["prod"], terraform.workspace) ? "mtls.${var.certificate_subdomain_name_prefix}" : "mtls.${var.certificate_subdomain_name_prefix}${terraform.workspace}"
229+
mtls_api_gateway_full_domain_name = contains(["prod"], terraform.workspace) ? "mtls.${var.domain}" : "mtls.${terraform.workspace}.${var.domain}"
230+
222231
current_region = data.aws_region.current.name
223232
current_account_id = data.aws_caller_identity.current.account_id
224233

0 commit comments

Comments
 (0)