Skip to content

Commit d0d3be9

Browse files
committed
بِسْمِ ٱللَّٰهِ ٱلرَّحْمَٰنِ ٱلرَّحِيمِ
1 parent ae458cf commit d0d3be9

File tree

11 files changed

+280
-0
lines changed

11 files changed

+280
-0
lines changed

.github/workflows/master.yaml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
name: Test & Tag
2+
3+
on:
4+
push:
5+
branches:
6+
- master
7+
8+
permissions:
9+
id-token: write
10+
contents: write
11+
12+
jobs:
13+
tag:
14+
name: Tag
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Checkout code
18+
uses: actions/checkout@v4
19+
20+
- name: Tag release
21+
uses: Klemensas/action-autotag@stable
22+
with:
23+
GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
24+
tag_prefix: 'v'

CHANGELOG.md

Whitespace-only changes.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"version": "0.0.1"
3+
}

static-site/acm.tf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
resource "aws_acm_certificate" "cloudfront_cert" {
2+
domain_name = var.domain_name
3+
validation_method = "DNS"
4+
tags = var.tags
5+
provider = aws.useast1
6+
}

static-site/cloudfront.tf

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
resource "aws_cloudfront_distribution" "static_site" {
2+
comment = "Distribution for ${var.domain_name}"
3+
aliases = [var.domain_name]
4+
enabled = true
5+
is_ipv6_enabled = true
6+
default_root_object = "index.html"
7+
8+
origin {
9+
domain_name = aws_s3_bucket.static_site.bucket_regional_domain_name
10+
origin_id = "S3-${aws_s3_bucket.static_site.bucket}"
11+
origin_access_control_id = aws_cloudfront_origin_access_control.oac.id
12+
}
13+
14+
restrictions {
15+
geo_restriction {
16+
restriction_type = "none"
17+
locations = []
18+
}
19+
}
20+
21+
default_cache_behavior {
22+
target_origin_id = "S3-${aws_s3_bucket.static_site.bucket}"
23+
response_headers_policy_id = aws_cloudfront_response_headers_policy.cloudfront.id
24+
25+
allowed_methods = ["GET", "HEAD"]
26+
cached_methods = ["GET", "HEAD"]
27+
28+
forwarded_values {
29+
query_string = false
30+
31+
cookies {
32+
forward = "none"
33+
}
34+
}
35+
36+
viewer_protocol_policy = "redirect-to-https"
37+
}
38+
39+
viewer_certificate {
40+
acm_certificate_arn = aws_acm_certificate.cloudfront_cert.arn
41+
ssl_support_method = "sni-only"
42+
minimum_protocol_version = var.minimum_protocol_version
43+
cloudfront_default_certificate = false
44+
}
45+
46+
# For SPAs this is needed for hard refresh on dynamic routes
47+
custom_error_response {
48+
response_page_path = "/index.html"
49+
response_code = 404
50+
error_code = 403
51+
error_caching_min_ttl = 0
52+
}
53+
54+
tags = var.tags
55+
}
56+
57+
resource "aws_cloudfront_origin_access_control" "oac" {
58+
name = "oac-for-${aws_s3_bucket.static_site.bucket}"
59+
description = "OAC for ${aws_s3_bucket.static_site.bucket}"
60+
origin_access_control_origin_type = "s3"
61+
signing_behavior = "always"
62+
signing_protocol = "sigv4"
63+
}
64+
65+
resource "aws_cloudfront_response_headers_policy" "cloudfront" {
66+
name = "cloudfront-response-headers-policy"
67+
comment = "Response headers policy for ${var.domain_name}"
68+
69+
security_headers_config {
70+
frame_options {
71+
frame_option = "DENY"
72+
override = true
73+
}
74+
75+
referrer_policy {
76+
referrer_policy = "strict-origin"
77+
override = true
78+
}
79+
80+
content_type_options {
81+
override = true
82+
}
83+
84+
strict_transport_security {
85+
access_control_max_age_sec = 15768000
86+
preload = false
87+
override = true
88+
}
89+
}
90+
}

static-site/data.tf

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
data "aws_iam_policy_document" "oidc" {
2+
statement {
3+
actions = ["sts:AssumeRoleWithWebIdentity"]
4+
5+
principals {
6+
type = "Federated"
7+
identifiers = [data.aws_iam_openid_connect_provider.github.arn]
8+
}
9+
10+
condition {
11+
test = "StringEquals"
12+
variable = "token.actions.githubusercontent.com:aud"
13+
values = ["sts.amazonaws.com"]
14+
}
15+
16+
condition {
17+
test = "StringLike"
18+
variable = "token.actions.githubusercontent.com:sub"
19+
values = ["repo:team-sufra/web:ref:refs/heads/master"]
20+
}
21+
}
22+
}
23+
24+
25+
data "aws_iam_policy_document" "static_site" {
26+
statement {
27+
actions = ["s3:GetObject"]
28+
resources = ["${aws_s3_bucket.static_site.arn}/*"]
29+
30+
principals {
31+
type = "Service"
32+
identifiers = ["cloudfront.amazonaws.com"]
33+
}
34+
35+
condition {
36+
test = "StringEquals"
37+
variable = "AWS:SourceArn"
38+
values = [
39+
aws_cloudfront_distribution.static_site.arn
40+
]
41+
}
42+
}
43+
}
44+
45+
data "aws_iam_policy_document" "deploy_web" {
46+
statement {
47+
actions = [
48+
"s3:ListBucket",
49+
"s3:GetBucketLocation",
50+
"s3:GetObject",
51+
"s3:PutObject",
52+
"s3:DeleteObject",
53+
"cloudfront:CreateInvalidation"
54+
]
55+
resources = [
56+
aws_s3_bucket.static_site.arn,
57+
"${aws_s3_bucket.static_site.arn}/*",
58+
aws_cloudfront_distribution.static_site.arn
59+
]
60+
}
61+
}
62+
63+
data "aws_route53_zone" "sufra_co_uk_hosted_zone" {
64+
name = "sufra.co.uk"
65+
}
66+
67+
data "aws_iam_openid_connect_provider" "github" {
68+
url = "https://token.actions.githubusercontent.com"
69+
}

static-site/iam.tf

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
###############################################
2+
# Sets up an IAM role which will allow deploying
3+
# your site via pipelines.
4+
###############################################
5+
6+
resource "aws_iam_role" "deploy_web" {
7+
name = var.role_name
8+
assume_role_policy = data.aws_iam_policy_document.oidc.json
9+
tags = var.tags
10+
}
11+
12+
resource "aws_iam_policy" "deploy_web" {
13+
name = var.role_name
14+
policy = data.aws_iam_policy_document.deploy_web.json
15+
tags = var.tags
16+
}
17+
18+
resource "aws_iam_role_policy_attachment" "deploy_web" {
19+
role = aws_iam_role.deploy_web.name
20+
policy_arn = aws_iam_policy.deploy_web.arn
21+
}

static-site/outputs.tf

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
output "bucket_name" {
2+
value = aws_s3_bucket.static_site.bucket
3+
}
4+
5+
output "cloudfront_dist_id" {
6+
value = aws_cloudfront_distribution.static_site.id
7+
}
8+
9+
output "cloudfront_dist_domain_name" {
10+
value = aws_cloudfront_distribution.static_site.domain_name
11+
}

static-site/route53.tf

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#############################################
2+
# Setup the A record for your custom domain
3+
#############################################
4+
5+
resource "aws_route53_record" "static_site_a_record" {
6+
zone_id = var.hosted_zone_id
7+
name = var.domain_name
8+
type = "A"
9+
10+
alias {
11+
name = aws_cloudfront_distribution.static_site.domain_name
12+
zone_id = aws_cloudfront_distribution.static_site.hosted_zone_id
13+
evaluate_target_health = false
14+
}
15+
}

static-site/s3.tf

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
resource "aws_s3_bucket" "static_site" {
2+
bucket = var.bucket_name
3+
force_destroy = true
4+
tags = var.tags
5+
}
6+
7+
resource "aws_s3_bucket_policy" "static_site_policy" {
8+
bucket = aws_s3_bucket.static_site.bucket
9+
policy = data.aws_iam_policy_document.static_site.json
10+
}

static-site/variables.tf

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
variable "bucket_name" {
2+
type = string
3+
description = "The name of the bucket which will hold your static site"
4+
}
5+
6+
variable "hosted_zone_id" {
7+
type = string
8+
description = "The hosted zone ID to attach the A record for your custom domain"
9+
}
10+
11+
variable "domain_name" {
12+
type = string
13+
description = "The custom domain for your CloudFront distribution"
14+
}
15+
16+
variable "minimum_protocol_version" {
17+
type = string
18+
description = "Set the minimum viewer certificate version for the CloudFront distribution"
19+
default = "TLSv1.2_2021"
20+
}
21+
22+
variable "role_name" {
23+
type = string
24+
description = "The name of the role and policy with the ability to deploy"
25+
default = "deploy-static-site"
26+
}
27+
28+
variable "tags" {
29+
type = map(string)
30+
description = "The tags to apply to all resources created"
31+
}

0 commit comments

Comments
 (0)