Skip to content
This repository was archived by the owner on May 19, 2026. It is now read-only.

Commit 51f66b9

Browse files
committed
TF Config for s3 hosting
1 parent 65e5064 commit 51f66b9

6 files changed

Lines changed: 252 additions & 1 deletion

File tree

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,10 @@ doc/
2525

2626
# Vagrant artifacts
2727
ubuntu-*-console.log
28+
29+
# OpenTofu / Terraform
30+
infra/.terraform/
31+
infra/.terraform.lock.hcl
32+
infra/terraform.tfstate
33+
infra/terraform.tfstate.backup
34+
infra/terraform.tfvars

.ruby-version

Lines changed: 0 additions & 1 deletion
This file was deleted.

infra/buildspec.yml

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
version: 0.2
2+
3+
phases:
4+
install:
5+
runtime-versions:
6+
ruby: 3.3
7+
commands:
8+
- gem install bundler --no-document
9+
- bundle install --jobs 4 --retry 3
10+
build:
11+
commands:
12+
- bundle exec middleman build --clean --watcher-disable
13+
post_build:
14+
commands:
15+
- aws s3 sync build/ s3://$S3_BUCKET/ --delete

infra/main.tf

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
terraform {
2+
required_providers {
3+
aws = {
4+
source = "hashicorp/aws"
5+
version = "~> 5.0"
6+
}
7+
}
8+
}
9+
10+
provider "aws" {
11+
region = "us-east-1"
12+
}
13+
14+
# S3 bucket for the static site
15+
resource "aws_s3_bucket" "site" {
16+
bucket = var.domain
17+
}
18+
19+
resource "aws_s3_bucket_website_configuration" "site" {
20+
bucket = aws_s3_bucket.site.id
21+
22+
index_document {
23+
suffix = "index.html"
24+
}
25+
}
26+
27+
resource "aws_s3_bucket_public_access_block" "site" {
28+
bucket = aws_s3_bucket.site.id
29+
30+
block_public_acls = false
31+
block_public_policy = false
32+
ignore_public_acls = false
33+
restrict_public_buckets = false
34+
}
35+
36+
resource "aws_s3_bucket_policy" "site" {
37+
bucket = aws_s3_bucket.site.id
38+
depends_on = [aws_s3_bucket_public_access_block.site]
39+
40+
policy = jsonencode({
41+
Version = "2012-10-17"
42+
Statement = [{
43+
Effect = "Allow"
44+
Principal = "*"
45+
Action = "s3:GetObject"
46+
Resource = "${aws_s3_bucket.site.arn}/*"
47+
}]
48+
})
49+
}
50+
51+
# Artifact bucket for CodePipeline (private)
52+
resource "aws_s3_bucket" "artifacts" {
53+
bucket = "${var.domain}-pipeline-artifacts"
54+
}
55+
56+
resource "aws_s3_bucket_lifecycle_configuration" "artifacts" {
57+
bucket = aws_s3_bucket.artifacts.id
58+
59+
rule {
60+
id = "expire"
61+
status = "Enabled"
62+
filter {}
63+
expiration {
64+
days = 7
65+
}
66+
}
67+
}
68+
69+
# CodeBuild
70+
resource "aws_iam_role" "codebuild" {
71+
name = "api-docs-codebuild"
72+
73+
assume_role_policy = jsonencode({
74+
Version = "2012-10-17"
75+
Statement = [{
76+
Effect = "Allow"
77+
Principal = { Service = "codebuild.amazonaws.com" }
78+
Action = "sts:AssumeRole"
79+
}]
80+
})
81+
}
82+
83+
resource "aws_iam_role_policy" "codebuild" {
84+
role = aws_iam_role.codebuild.id
85+
86+
policy = jsonencode({
87+
Version = "2012-10-17"
88+
Statement = [
89+
{
90+
Effect = "Allow"
91+
Action = ["logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents"]
92+
Resource = "*"
93+
},
94+
{
95+
Effect = "Allow"
96+
Action = ["s3:PutObject", "s3:DeleteObject", "s3:ListBucket"]
97+
Resource = [aws_s3_bucket.site.arn, "${aws_s3_bucket.site.arn}/*"]
98+
},
99+
{
100+
Effect = "Allow"
101+
Action = ["s3:GetObject", "s3:GetObjectVersion", "s3:PutObject"]
102+
Resource = "${aws_s3_bucket.artifacts.arn}/*"
103+
},
104+
{
105+
Effect = "Allow"
106+
Action = "codestar-connections:UseConnection"
107+
Resource = var.github_connection_arn
108+
}
109+
]
110+
})
111+
}
112+
113+
resource "aws_codebuild_project" "site" {
114+
name = "api-docs"
115+
service_role = aws_iam_role.codebuild.arn
116+
117+
artifacts {
118+
type = "CODEPIPELINE"
119+
}
120+
121+
environment {
122+
compute_type = "BUILD_GENERAL1_SMALL"
123+
image = "aws/codebuild/standard:7.0"
124+
type = "LINUX_CONTAINER"
125+
126+
environment_variable {
127+
name = "S3_BUCKET"
128+
value = aws_s3_bucket.site.bucket
129+
}
130+
}
131+
132+
source {
133+
type = "CODEPIPELINE"
134+
buildspec = "infra/buildspec.yml"
135+
}
136+
}
137+
138+
# CodePipeline
139+
resource "aws_iam_role" "codepipeline" {
140+
name = "api-docs-codepipeline"
141+
142+
assume_role_policy = jsonencode({
143+
Version = "2012-10-17"
144+
Statement = [{
145+
Effect = "Allow"
146+
Principal = { Service = "codepipeline.amazonaws.com" }
147+
Action = "sts:AssumeRole"
148+
}]
149+
})
150+
}
151+
152+
resource "aws_iam_role_policy" "codepipeline" {
153+
role = aws_iam_role.codepipeline.id
154+
155+
policy = jsonencode({
156+
Version = "2012-10-17"
157+
Statement = [
158+
{
159+
Effect = "Allow"
160+
Action = ["s3:GetObject", "s3:GetObjectVersion", "s3:PutObject", "s3:ListBucket"]
161+
Resource = [aws_s3_bucket.artifacts.arn, "${aws_s3_bucket.artifacts.arn}/*"]
162+
},
163+
{
164+
Effect = "Allow"
165+
Action = ["codebuild:BatchGetBuilds", "codebuild:StartBuild"]
166+
Resource = aws_codebuild_project.site.arn
167+
},
168+
{
169+
Effect = "Allow"
170+
Action = "codestar-connections:UseConnection"
171+
Resource = var.github_connection_arn
172+
}
173+
]
174+
})
175+
}
176+
177+
resource "aws_codepipeline" "site" {
178+
name = "api-docs"
179+
role_arn = aws_iam_role.codepipeline.arn
180+
181+
artifact_store {
182+
location = aws_s3_bucket.artifacts.bucket
183+
type = "S3"
184+
}
185+
186+
stage {
187+
name = "Source"
188+
action {
189+
name = "Source"
190+
category = "Source"
191+
owner = "AWS"
192+
provider = "CodeStarSourceConnection"
193+
version = "1"
194+
output_artifacts = ["source"]
195+
configuration = {
196+
ConnectionArn = var.github_connection_arn
197+
FullRepositoryId = "jetbuilt/jetbuilt-api-docs"
198+
BranchName = "main"
199+
OutputArtifactFormat = "CODEBUILD_CLONE_REF"
200+
DetectChanges = "true"
201+
}
202+
}
203+
}
204+
205+
stage {
206+
name = "Build"
207+
action {
208+
name = "Build"
209+
category = "Build"
210+
owner = "AWS"
211+
provider = "CodeBuild"
212+
version = "1"
213+
input_artifacts = ["source"]
214+
configuration = {
215+
ProjectName = aws_codebuild_project.site.name
216+
}
217+
}
218+
}
219+
}

infra/outputs.tf

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
output "site_endpoint" {
2+
description = "S3 website endpoint — use this as the Cloudflare origin"
3+
value = aws_s3_bucket_website_configuration.site.website_endpoint
4+
}

infra/variables.tf

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
variable "domain" {
2+
default = "api.jetbuilt.com"
3+
}
4+
5+
variable "github_connection_arn" {
6+
description = "ARN of the existing CodeStar connection for GitHub"
7+
}

0 commit comments

Comments
 (0)