Skip to content

Commit

Permalink
AUTH-2655 -initial cloud front resource creation (#1577)
Browse files Browse the repository at this point in the history
* initial cloud front resource creation on staging


Co-authored-by: Ethan Mills <[email protected]>
  • Loading branch information
pskushwaha1 and ethanmills authored Apr 25, 2024
1 parent 2d79d43 commit c223bc8
Show file tree
Hide file tree
Showing 11 changed files with 835 additions and 3 deletions.
40 changes: 40 additions & 0 deletions ci/terraform/cloudfront.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
resource "aws_cloudformation_stack" "cloudfront" {
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
name = "${var.environment}-auth-fe-cloudfront"
#using fixed version of template for now
template_url = "https://template-storage-templatebucket-1upzyw6v9cs42.s3.amazonaws.com/cloudfront-distribution/template.yaml?versionId=EKk9m9vMv10qF5vHzWZogFLnQQw6_Yjc"

capabilities = ["CAPABILITY_NAMED_IAM"]

parameters = {
AddWWWPrefix = var.Add_WWWPrefix
ApplyCloakingHeaderWAFToOrigin = var.Apply_CloakingHeader_WAFToOrigin
CloudFrontCertArn = aws_acm_certificate.cloudfront_frontend_certificate[0].arn
CloudfrontWafAcl = aws_wafv2_web_acl.frontend_cloudfront_waf_web_acl[0].arn
DistributionAlias = local.frontend_fqdn
FraudHeaderEnabled = var.Fraud_Header_Enabled
OriginCloakingHeader = var.auth_origin_cloakingheader
OriginResourceArn = aws_lb.frontend_alb.id
OriginWafAcl = "none"
PreviousOriginCloakingHeader = var.previous_auth_origin_cloakingheader
StandardLoggingEnabled = true
}
tags = local.default_tags
}

resource "aws_cloudformation_stack" "cloudfront-monitoring" {
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
provider = aws.cloudfront
name = "${var.environment}-auth-fe-cloudfront-monitoring"
template_url = "https://template-storage-templatebucket-1upzyw6v9cs42.s3.amazonaws.com/cloudfront-monitoring-alarm/template.yaml?z=${timestamp()}"

capabilities = ["CAPABILITY_NAMED_IAM"]

parameters = {
CacheHitAlarmSNSTopicARN = aws_sns_topic.slack_events[0].arn
CloudFrontAdditionaldMetricsEnabled = true
CloudfrontDistribution = aws_cloudformation_stack.cloudfront[0].outputs["DistributionId"]
}
depends_on = [aws_cloudformation_stack.cloudfront]
tags = local.default_tags
}
7 changes: 4 additions & 3 deletions ci/terraform/dns.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ locals {

account_management_fqdn = var.environment == "production" ? "home.account.gov.uk" : "home.${var.environment}.account.gov.uk"

frontend_fqdn = "signin.${local.service_domain}"
frontend_api_fqdn = "auth.${local.service_domain}"
oidc_api_fqdn = "oidc.${local.service_domain}"
frontend_fqdn = "signin.${local.service_domain}"
frontend_api_fqdn = "auth.${local.service_domain}"
oidc_api_fqdn = "oidc.${local.service_domain}"
frontend_fqdn_origin = "origin.signin.${local.service_domain}"
}

data "aws_route53_zone" "service_domain" {
Expand Down
55 changes: 55 additions & 0 deletions ci/terraform/route53.tf
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,58 @@ resource "aws_acm_certificate_validation" "frontend_acm_alb_certificate_validati
output "signin_nameservers" {
value = aws_route53_zone.zone.name_servers
}

#DNS Record for cloufront origin Domain & TLS certificate

resource "aws_route53_record" "Cloudfront_frontend_record" {
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
name = local.frontend_fqdn_origin
type = "A"
zone_id = aws_route53_zone.zone.zone_id

alias {
evaluate_target_health = false
name = "dualstack.${aws_lb.frontend_alb.dns_name}"
zone_id = aws_lb.frontend_alb.zone_id
}
}

resource "aws_acm_certificate" "cloudfront_frontend_certificate" {
provider = aws.cloudfront
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
domain_name = aws_route53_record.frontend.name
validation_method = "DNS"

tags = local.default_tags

lifecycle {
create_before_destroy = true
}
}

resource "aws_route53_record" "cloudfront_frontend_certificate_validation" {
provider = aws.cloudfront
for_each = var.cloudfront_auth_frontend_enabled ? {
for dvo in aws_acm_certificate.cloudfront_frontend_certificate[0].domain_validation_options : dvo.domain_name => {
name = dvo.resource_record_name
record = dvo.resource_record_value
type = dvo.resource_record_type
}
} : {}

allow_overwrite = true
name = each.value.name
records = [each.value.record]
ttl = 60
type = each.value.type
zone_id = aws_route53_zone.zone.zone_id
depends_on = [aws_acm_certificate.cloudfront_frontend_certificate]
}

resource "aws_acm_certificate_validation" "frontend_acm_cloudfront_certificate_validation" {
provider = aws.cloudfront
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
certificate_arn = aws_acm_certificate.cloudfront_frontend_certificate[0].arn
validation_record_fqdns = [for record in aws_route53_record.cloudfront_frontend_certificate_validation : record.fqdn]
depends_on = [aws_route53_record.cloudfront_frontend_certificate_validation]
}
5 changes: 5 additions & 0 deletions ci/terraform/sandpit.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ aws_region = "eu-west-2"
account_management_fqdn = "acc-mgmt-fg.sandpit.auth.ida.digital.cabinet-office.gov.uk"
oidc_api_fqdn = "oidc.sandpit.account.gov.uk"
frontend_fqdn = "signin.sandpit.account.gov.uk"
frontend_fqdn_origin = "origin.signin.sandpit.account.gov.uk"
frontend_api_fqdn = "auth.sandpit.account.gov.uk"
service_domain = "sandpit.account.gov.uk"
zone_id = "Z1031735QZMC84WYW1TP"
Expand All @@ -14,10 +15,14 @@ support_authorize_controller = "1"
support_account_interventions = "1"
support_2fa_b4_password_reset = "1"


frontend_task_definition_cpu = 256
frontend_task_definition_memory = 512
frontend_auto_scaling_v2_enabled = true

#cloudfront enabled flag
cloudfront_auth_frontend_enabled = true

alb_idle_timeout = 30

url_for_support_links = "https://home.build.account.gov.uk/contact-gov-uk-one-login"
Expand Down
10 changes: 10 additions & 0 deletions ci/terraform/site.tf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,16 @@ provider "aws" {
}
}

provider "aws" {
alias = "cloudfront"

region = "us-east-1"

assume_role {
role_arn = var.deployer_role_arn
}
}

data "aws_availability_zones" "available" {}

data "aws_caller_identity" "current" {}
Expand Down
131 changes: 131 additions & 0 deletions ci/terraform/sns.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#This is SNS topic created in us-east-1 region for cloudwatch Alarm for Cloudfront

resource "aws_sns_topic" "slack_events" {
provider = aws.cloudfront
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
name = "${var.environment}-cloudfront-alerts"
lambda_failure_feedback_role_arn = aws_iam_role.sns_logging_iam_role[0].arn

tags = local.default_tags
}

data "aws_iam_policy_document" "sns_topic_policy" {
version = "2012-10-17"
provider = aws.cloudfront
count = var.cloudfront_auth_frontend_enabled ? 1 : 0

statement {
actions = [
"SNS:Subscribe",
"SNS:SetTopicAttributes",
"SNS:RemovePermission",
"SNS:Receive",
"SNS:Publish",
"SNS:ListSubscriptionsByTopic",
"SNS:GetTopicAttributes",
"SNS:DeleteTopic",
"SNS:AddPermission",
]

effect = "Allow"

principals {
type = "Service"
identifiers = ["cloudwatch.amazonaws.com"]
}

condition {
test = "StringEquals"
values = [data.aws_caller_identity.current.account_id]
variable = "aws:SourceAccount"
}

resources = [
aws_sns_topic.slack_events[0].arn,
]
}
}

resource "aws_sns_topic_policy" "sns_alert_policy" {
provider = aws.cloudfront
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
arn = aws_sns_topic.slack_events[0].arn

policy = data.aws_iam_policy_document.sns_topic_policy[0].json
}

resource "aws_iam_role" "sns_logging_iam_role" {
provider = aws.cloudfront
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
name_prefix = "sns-failed-slack-alerts-role"
path = "/${var.environment}/"
assume_role_policy = data.aws_iam_policy_document.sns_can_assume_policy[0].json

tags = local.default_tags
}

data "aws_iam_policy_document" "sns_can_assume_policy" {
version = "2012-10-17"
provider = aws.cloudfront
count = var.cloudfront_auth_frontend_enabled ? 1 : 0

statement {
effect = "Allow"
principals {
identifiers = [
"sns.amazonaws.com"
]
type = "Service"
}

actions = [
"sts:AssumeRole"
]
}
}

data "aws_iam_policy_document" "sns_logging_policy" {
version = "2012-10-17"
provider = aws.cloudfront
count = var.cloudfront_auth_frontend_enabled ? 1 : 0

statement {
effect = "Allow"
actions = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents",
]

resources = [
"arn:aws:logs:*:*:*",
]
}
}

resource "aws_iam_policy" "api_gateway_logging_policy" {
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
provider = aws.cloudfront
name_prefix = "sns-failed-alert-logging"
path = "/${var.environment}/"
description = "IAM policy for logging failed SNS alerts"

policy = data.aws_iam_policy_document.sns_logging_policy[0].json

lifecycle {
create_before_destroy = true
}

tags = local.default_tags
}

resource "aws_iam_role_policy_attachment" "api_gateway_logging_logs" {
provider = aws.cloudfront
count = var.cloudfront_auth_frontend_enabled ? 1 : 0
role = aws_iam_role.sns_logging_iam_role[0].name
policy_arn = aws_iam_policy.api_gateway_logging_policy[0].arn
}
3 changes: 3 additions & 0 deletions ci/terraform/staging.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ environment = "staging"
common_state_bucket = "di-auth-staging-tfstate"
redis_node_size = "cache.m4.xlarge"


cloudfront_auth_frontend_enabled = true

frontend_auto_scaling_v2_enabled = true
frontend_task_definition_cpu = 1024
frontend_task_definition_memory = 2048
Expand Down
43 changes: 43 additions & 0 deletions ci/terraform/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,46 @@ variable "rate_limited_endpoints_requests_per_period" {
type = number
default = 100000
}

#cloudfront varaible
variable "cloudfront_auth_frontend_enabled" {
type = bool
default = false
description = "Feature flag to control the creation cloudfront DNS record origin & Cloudfront Certificate"
}

variable "auth_origin_cloakingheader" {
type = string
sensitive = true
description = "This is header value for Cloufront to to verify requests are coming from the correct CloudFront distribution to ALB "
}

variable "previous_auth_origin_cloakingheader" {
type = string
sensitive = true
description = "This is previous header value when the value is rotated to ensure WAF will allow requests during rotation "
}

variable "Add_WWWPrefix" {
type = bool
default = false
description = "flag to to add subdomain (www) to the frontend url eg www.signin.sandpit.account.gov.uk"
}

variable "Apply_CloakingHeader_WAFToOrigin" {
type = bool
default = false
description = "flag to add a cloacking header WAf to ALB so only requiest comming from cloudfront are allowed "
}

variable "Fraud_Header_Enabled" {
type = bool
default = false
description = "flag to switch on Fraud header on cloudfront disturbution"
}

variable "Standard_Logging_Enabled" {
type = bool
default = false
description = "Enables Standard logging to push logs to S3 bucket"
}
Loading

0 comments on commit c223bc8

Please sign in to comment.