1-
21variable "domain_name_zone" {
32}
43variable "domain_name" {
54}
5+ variable "content_security_policy" {
6+ type = map (list (string ))
7+ default = {
8+ default- src : [
9+ " *" ,
10+ " 'unsafe-eval'" ,
11+ " 'wasm-unsafe-eval'" ,
12+ " 'unsafe-inline'" ,
13+ " data:" ,
14+ " mediastream:" ,
15+ " blob:" ,
16+ " filesystem:" ,
17+ " about:" ,
18+ " ws:" ,
19+ " wss:" ,
20+ ]
21+ frame- src : [
22+ " *" ,
23+ " data:" ,
24+ " blob:" ,
25+ ]
26+ form- action : [
27+ " *"
28+ ]
29+ frame- ancestors : [
30+ " *" ,
31+ " data:" ,
32+ " blob:" ,
33+ ]
34+ }
35+ }
636variable "geo_restrictions_mode" {
7- type = string
37+ type = string
838 default = " none"
939 validation {
1040 condition = contains ([
@@ -20,7 +50,7 @@ variable "geo_restrictions_list" {
2050 default = []
2151}
2252variable "react_mode" {
23- type = bool
53+ type = bool
2454 default = false
2555}
2656
@@ -29,7 +59,7 @@ data "aws_route53_zone" "main" {
2959}
3060
3161resource "aws_acm_certificate" "web" {
32- provider = aws. acm
62+ provider = aws. acm
3363 domain_name = var. domain_name
3464 validation_method = " DNS"
3565}
@@ -41,8 +71,8 @@ resource "aws_route53_record" "web" {
4171 ttl = " 300"
4272}
4373resource "aws_acm_certificate_validation" "web" {
44- provider = aws. acm
45- certificate_arn = aws_acm_certificate. web . arn
74+ provider = aws. acm
75+ certificate_arn = aws_acm_certificate. web . arn
4676 validation_record_fqdns = [aws_route53_record . web . fqdn ]
4777}
4878resource "aws_route53_record" "web_cloudfront" {
@@ -64,7 +94,7 @@ resource "aws_cloudfront_origin_access_identity" "oai" {
6494resource "aws_cloudfront_distribution" "main" {
6595 depends_on = [aws_s3_bucket . files ]
6696 enabled = true
67- aliases = [var . domain_name ]
97+ aliases = [var . domain_name ]
6898 default_root_object = " index.html"
6999
70100 origin {
@@ -78,13 +108,14 @@ resource "aws_cloudfront_distribution" "main" {
78108 }
79109 }
80110 default_cache_behavior {
81- allowed_methods = [" GET" , " HEAD" , " OPTIONS" , " PUT" , " POST" , " PATCH" , " DELETE" ]
82- cached_methods = [" GET" , " HEAD" , " OPTIONS" ]
83- target_origin_id = " origin-${ var . domain_name } "
111+ allowed_methods = [" GET" , " HEAD" , " OPTIONS" , " PUT" , " POST" , " PATCH" , " DELETE" ]
112+ cached_methods = [" GET" , " HEAD" , " OPTIONS" ]
113+ target_origin_id = " origin-${ var . domain_name } "
84114 viewer_protocol_policy = " redirect-to-https" # other options - https only, http
115+ response_headers_policy_id = aws_cloudfront_response_headers_policy. webapp_security_headers . id
85116
86117 forwarded_values {
87- headers = []
118+ headers = []
88119 query_string = true
89120
90121 cookies {
@@ -107,7 +138,7 @@ resource "aws_cloudfront_distribution" "main" {
107138 restrictions {
108139 geo_restriction {
109140 restriction_type = var. geo_restrictions_mode
110- locations = var. geo_restrictions_list
141+ locations = var. geo_restrictions_list
111142 }
112143 }
113144
@@ -116,4 +147,39 @@ resource "aws_cloudfront_distribution" "main" {
116147 ssl_support_method = " sni-only"
117148 minimum_protocol_version = " TLSv1.2_2018"
118149 }
150+ }
151+
152+ resource "aws_cloudfront_response_headers_policy" "webapp_security_headers" {
153+ name = " webapp-security-headers-${ replace (var. domain_name , " /[^a-zA-Z0-9\\ -]/" , " -" )} "
154+ security_headers_config {
155+ content_type_options {
156+ override = true
157+ }
158+ frame_options {
159+ frame_option = " DENY"
160+ override = true
161+ }
162+ referrer_policy {
163+ referrer_policy = " same-origin"
164+ override = true
165+ }
166+ xss_protection {
167+ mode_block = true
168+ protection = true
169+ override = true
170+ }
171+ strict_transport_security {
172+ access_control_max_age_sec = " 63072000"
173+ include_subdomains = true
174+ preload = true
175+ override = true
176+ }
177+ content_security_policy {
178+ content_security_policy = join (" ; " , [
179+ for key , value in var . content_security_policy : " ${ key } ${ join (" " , value)} "
180+ ])
181+ # content_security_policy = "frame-ancestors 'self'; default-src 'self'; img-src ${var.external_media_sources}; media-src ${var.external_media_sources}; script-src 'self' ${var.external_script_sources}; style-src 'self' 'unsafe-inline'; object-src 'none'; connect-src ${var.external_connections}"
182+ override = true
183+ }
184+ }
119185}
0 commit comments