aboutsummaryrefslogtreecommitdiff
path: root/infra
diff options
context:
space:
mode:
Diffstat (limited to 'infra')
-rw-r--r--infra/.terraform.lock.hcl67
-rw-r--r--infra/data.tf11
-rw-r--r--infra/keypair.tf4
-rw-r--r--infra/main.tf46
-rw-r--r--infra/output.tf29
-rw-r--r--infra/rds.tf58
-rw-r--r--infra/sg.tf38
-rw-r--r--infra/variables.tf58
-rw-r--r--infra/versions.tf17
-rw-r--r--infra/vpc.tf29
10 files changed, 357 insertions, 0 deletions
diff --git a/infra/.terraform.lock.hcl b/infra/.terraform.lock.hcl
new file mode 100644
index 0000000..0f121c1
--- /dev/null
+++ b/infra/.terraform.lock.hcl
@@ -0,0 +1,67 @@
1# This file is maintained automatically by "terraform init".
2# Manual edits may be lost in future updates.
3
4provider "registry.terraform.io/cloudflare/cloudflare" {
5 version = "3.33.1"
6 constraints = "~> 3.29"
7 hashes = [
8 "h1:yL+jBzX+P/VabdTwZ1V1+UjI1EH+S1UQtm3U+rZ4XtU=",
9 "zh:0387f5891f349fb0ef3b68cbbd212c4c1fabb921324cba4dfeda08ad3d91f338",
10 "zh:3c016161cb8de9fbf1cf7d0d6099fb9c1c0d1e7bcae36a6084285f7fa4726176",
11 "zh:43ea39ca52688c350fccc0207ae49a88835f8c56bbc437999acc7feb04d365fd",
12 "zh:6d184850613b26956634ea5a34c7a0dec775747ef400f83dad54ba48d060218e",
13 "zh:73236e553775b59af1987f6857c68a7c274aea85c21da9e0e8ad6e67ab5318a7",
14 "zh:753e07cbda96d020d5a1fe09beb322e8efeb2d11450c71d956f1ee03d923410c",
15 "zh:7e35d6437fd3add22ebecfe457bfe2f46a2ae58358e59f7ccdb22c13a49fce07",
16 "zh:878d479802ff633e5cc13da6a3b9eb41e572e1320b3ce45662390c8e97167c80",
17 "zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f",
18 "zh:950a7489e0394470fd0589121d1a0602c57164c854229fedb3319b717d9c2e23",
19 "zh:a2c3a4b14d4686042e8418860cd59a5f9876c56a755ca9530757307b9b9195cf",
20 "zh:a4dc55555cb79488a8dff002acf4e98061099721571e290b467872f7c30a897f",
21 "zh:b6148bbc97d375f185a2ab05243a4d45da82f0c67033a461179f8090bb8bfbd4",
22 "zh:c0d720c316f580a382d9bc2d00a78217b62fbd28e186dc814bc8d75482540ec2",
23 "zh:dd42c50c4fb93ec390871234f5a52e21aebf91765365c728f3f237c4db4f4748",
24 ]
25}
26
27provider "registry.terraform.io/hashicorp/aws" {
28 version = "4.52.0"
29 constraints = ">= 3.73.0, ~> 4.46"
30 hashes = [
31 "h1:Ofm8syFCBU8MFOiU+zg+vnTWkSdozpmvaA9xukNvcBg=",
32 "zh:00c865de3a0e7643f4e2e5c8d4ba91eee94a46d41090eb134baca6b58c107172",
33 "zh:1430682e26eba25d8ace19fa780361187f474153e455545235b4fe30637fdcc2",
34 "zh:1b9a4e5c889bd2022bd59fb924dc78e189f1b7a4fd718fcacda0f0a4cb74d6eb",
35 "zh:2485260141608f1d386d0f68934092bbf68a27d96f0d83c73222d0382aee02f5",
36 "zh:2fe67ee94e2df7dabee7e474356f8e907e7c8011533f9d71df8702d59f9060b2",
37 "zh:37babd1b7ff96ff1f42aa56d7575cacabda6f9f460ff651d70662bfd90076341",
38 "zh:54aa8d39f22ecab6613169f49d37d2ccfaf417e59dd7a8c8fc6bf92600c3384f",
39 "zh:5bf4a84b962a8d2da8f4ccf2a7de56fb6c7a1f566e8393b563977fc7872a8740",
40 "zh:8cb4a51f209a3cc497e53f09188c15c6675697587fe2ea14a6c7fff10c8c8476",
41 "zh:91f6bdcbb1e36471140982e9048b7ced437d3290b2cc21079e5429cc84fed2fd",
42 "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425",
43 "zh:9f8c01c3f677bc64ddefa41e59c6fc98860c11875d7f148af55969d3e3847f77",
44 "zh:b6b4fc0bd6f3c0adcd9531da3ccf8c25787ccd6ccc568f13ebbff1336d71a9e1",
45 "zh:d52a428bd92cc319088685ecac63b9f7d12d4cd6725604edb20d0c4f37a9936e",
46 "zh:e20252a851a0d38548a3c01a006bfc59ee1fc84217bf9eb95b22724769601b2b",
47 ]
48}
49
50provider "registry.terraform.io/hashicorp/random" {
51 version = "3.4.3"
52 hashes = [
53 "h1:xZGZf18JjMS06pFa4NErzANI98qi59SEcBsOcS2P2yQ=",
54 "zh:41c53ba47085d8261590990f8633c8906696fa0a3c4b384ff6a7ecbf84339752",
55 "zh:59d98081c4475f2ad77d881c4412c5129c56214892f490adf11c7e7a5a47de9b",
56 "zh:686ad1ee40b812b9e016317e7f34c0d63ef837e084dea4a1f578f64a6314ad53",
57 "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3",
58 "zh:84103eae7251384c0d995f5a257c72b0096605048f757b749b7b62107a5dccb3",
59 "zh:8ee974b110adb78c7cd18aae82b2729e5124d8f115d484215fd5199451053de5",
60 "zh:9dd4561e3c847e45de603f17fa0c01ae14cae8c4b7b4e6423c9ef3904b308dda",
61 "zh:bb07bb3c2c0296beba0beec629ebc6474c70732387477a65966483b5efabdbc6",
62 "zh:e891339e96c9e5a888727b45b2e1bb3fcbdfe0fd7c5b4396e4695459b38c8cb1",
63 "zh:ea4739860c24dfeaac6c100b2a2e357106a89d18751f7693f3c31ecf6a996f8d",
64 "zh:f0c76ac303fd0ab59146c39bc121c5d7d86f878e9a69294e29444d4c653786f8",
65 "zh:f143a9a5af42b38fed328a161279906759ff39ac428ebcfe55606e05e1518b93",
66 ]
67}
diff --git a/infra/data.tf b/infra/data.tf
new file mode 100644
index 0000000..2102273
--- /dev/null
+++ b/infra/data.tf
@@ -0,0 +1,11 @@
1data "aws_ami" "debian" {
2 most_recent = true
3 owners = ["136693071363"]
4
5 filter {
6 name = "name"
7 values = ["debian-11-amd64-*"]
8 }
9}
10
11data "aws_availability_zones" "available" {}
diff --git a/infra/keypair.tf b/infra/keypair.tf
new file mode 100644
index 0000000..a73a0af
--- /dev/null
+++ b/infra/keypair.tf
@@ -0,0 +1,4 @@
1resource "aws_key_pair" "framework" {
2 key_name = "framework"
3 public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILS2i5/x9r+cv2j2/SUZ2x2fgQeGnJP1I7PUHC0UdWN6 framework"
4}
diff --git a/infra/main.tf b/infra/main.tf
new file mode 100644
index 0000000..77b8571
--- /dev/null
+++ b/infra/main.tf
@@ -0,0 +1,46 @@
1locals {
2 name = var.name
3}
4
5data "aws_subnet" "ec2" {
6 filter {
7 name = "availability-zone"
8 values = [aws_db_instance.mastodon.availability_zone]
9 }
10 filter {
11 name = "subnet-id"
12 values = module.vpc.public_subnets
13 }
14}
15
16resource "aws_instance" "mastodon" {
17 ami = data.aws_ami.debian.id
18 instance_type = var.ec2_instance_type
19
20 subnet_id = data.aws_subnet.ec2.id
21 key_name = "framework"
22
23 vpc_security_group_ids = [aws_security_group.backend.id]
24
25 root_block_device {
26 volume_type = "gp3"
27 // how to resize partition and file system after resizing ebs volume
28 // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html
29 volume_size = "30"
30 tags = {
31 Name = "${local.name}-root"
32 }
33 }
34
35 tags = {
36 Name = local.name
37 }
38
39 lifecycle {
40 ignore_changes = [ami]
41 }
42}
43
44resource "aws_eip" "mastodon" {
45 instance = aws_instance.mastodon.id
46}
diff --git a/infra/output.tf b/infra/output.tf
new file mode 100644
index 0000000..d0d90fa
--- /dev/null
+++ b/infra/output.tf
@@ -0,0 +1,29 @@
1output "rds_hostname" {
2 description = "RDS instance hostname"
3 value = aws_db_instance.mastodon.address
4}
5
6output "rds_port" {
7 description = "RDS instance port"
8 value = aws_db_instance.mastodon.port
9}
10
11output "rds_username" {
12 description = "RDS instance username"
13 value = aws_db_instance.mastodon.username
14}
15
16output "rds_password" {
17 description = "RDS instance password"
18 value = random_password.rds_password.result
19 sensitive = true
20}
21
22output "instance" {
23 description = "The main EC2 instance."
24 value = {
25 arn = aws_instance.mastodon.arn
26 public_ip = aws_eip.mastodon.public_ip
27 private_ip = aws_instance.mastodon.private_ip
28 }
29}
diff --git a/infra/rds.tf b/infra/rds.tf
new file mode 100644
index 0000000..d9ba204
--- /dev/null
+++ b/infra/rds.tf
@@ -0,0 +1,58 @@
1resource "aws_db_parameter_group" "mastodon" {
2 name = var.name
3 family = var.rds_parameter_group
4}
5
6resource "aws_db_instance" "mastodon" {
7 identifier = var.name
8 instance_class = var.rds_instance_class
9 allocated_storage = var.rds_storage_size
10 engine = var.rds_engine
11 engine_version = var.rds_engine_version
12 username = var.rds_username
13 password = random_password.rds_password.result
14 port = var.rds_port
15 db_subnet_group_name = aws_db_subnet_group.mastodon.name
16 vpc_security_group_ids = [aws_security_group.rds.id]
17 parameter_group_name = aws_db_parameter_group.mastodon.name
18 publicly_accessible = true
19 skip_final_snapshot = true
20
21 backup_retention_period = 7
22 performance_insights_enabled = true
23}
24
25resource "random_password" "rds_password" {
26 length = 16
27 special = false
28}
29
30resource "aws_ssm_parameter" "rds_host" {
31 name = "/${var.name}/rds/host"
32 type = "String"
33 value = aws_db_instance.mastodon.address
34}
35
36resource "aws_ssm_parameter" "rds_port" {
37 name = "/${var.name}/rds/port"
38 type = "String"
39 value = aws_db_instance.mastodon.port
40}
41
42resource "aws_ssm_parameter" "mastodon_db_name" {
43 name = "/${local.name}/rds/name"
44 type = "String"
45 value = aws_db_instance.mastodon.db_name
46}
47
48resource "aws_ssm_parameter" "mastodon_db_user" {
49 name = "/${local.name}/rds/username"
50 type = "String"
51 value = aws_db_instance.mastodon.username
52}
53
54resource "aws_ssm_parameter" "mastodon_db_password" {
55 name = "/${local.name}/rds/password"
56 type = "SecureString"
57 value = random_password.rds_password.result
58}
diff --git a/infra/sg.tf b/infra/sg.tf
new file mode 100644
index 0000000..48d5406
--- /dev/null
+++ b/infra/sg.tf
@@ -0,0 +1,38 @@
1# EC 2
2resource "aws_security_group" "backend" {
3 name = local.name
4 vpc_id = module.vpc.vpc_id
5}
6
7resource "aws_security_group_rule" "backend_ingress_ssh" {
8 security_group_id = aws_security_group.backend.id
9 type = "ingress"
10 protocol = "tcp"
11 from_port = 22
12 to_port = 22
13 cidr_blocks = ["0.0.0.0/0"]
14}
15
16resource "aws_security_group_rule" "backend_egress_all" {
17 security_group_id = aws_security_group.backend.id
18 type = "egress"
19 protocol = "all"
20 from_port = 0
21 to_port = 0
22 cidr_blocks = ["0.0.0.0/0"]
23}
24
25# RDS
26resource "aws_security_group" "rds" {
27 name = "${local.name}-db"
28 vpc_id = module.vpc.vpc_id
29}
30
31resource "aws_security_group_rule" "rds_ingress_backend" {
32 security_group_id = aws_security_group.rds.id
33 type = "ingress"
34 protocol = "tcp"
35 from_port = var.rds_port
36 to_port = var.rds_port
37 source_security_group_id = aws_security_group.backend.id
38}
diff --git a/infra/variables.tf b/infra/variables.tf
new file mode 100644
index 0000000..66c6e5c
--- /dev/null
+++ b/infra/variables.tf
@@ -0,0 +1,58 @@
1provider "aws" {
2 region = var.region
3}
4
5variable "name" {
6 description = "Name of the service. It will be used to name EC2, and RDS instances."
7 default = "mastodon"
8}
9
10variable "region" {
11 default = "us-west-2"
12 description = "AWS region"
13}
14
15# RDS
16variable "rds_instance_class" {
17 default = "db.t3.micro"
18}
19
20variable "rds_storage_size" {
21 default = 20
22}
23
24variable "rds_username" {
25 default = "mastodon"
26}
27
28variable "rds_engine" {
29 default = "postgres"
30}
31
32variable "rds_engine_version" {
33 default = "13.7"
34}
35
36variable "rds_parameter_group" {
37 default = "default.postgres13"
38}
39
40variable "rds_port" {
41 default = 33060
42}
43
44# EC 2
45variable "ec2_instance_type" {
46 default = "t3a.medium"
47}
48
49variable "site_domain" {
50 type = string
51 default = "m.jinwei.me"
52}
53
54variable "cloudflare_account_id" {
55 description = "The Cloudflare UUID for the Account the Zone lives in."
56 type = string
57 sensitive = true
58}
diff --git a/infra/versions.tf b/infra/versions.tf
new file mode 100644
index 0000000..62b3386
--- /dev/null
+++ b/infra/versions.tf
@@ -0,0 +1,17 @@
1terraform {
2 required_providers {
3 aws = {
4 source = "hashicorp/aws"
5 version = "~> 4.46"
6 }
7 cloudflare = {
8 source = "cloudflare/cloudflare"
9 version = "~> 3.29"
10 }
11 }
12}
13
14provider "aws" {
15 alias = "us-east-1"
16 region = "us-east-1"
17}
diff --git a/infra/vpc.tf b/infra/vpc.tf
new file mode 100644
index 0000000..6941a06
--- /dev/null
+++ b/infra/vpc.tf
@@ -0,0 +1,29 @@
1locals {
2 cidr_block = "10.32.0.0/16"
3 subnets = cidrsubnets(local.cidr_block, 4, 4, 4, 4, 4, 4)
4 subnet_groups = chunklist(local.subnets, 3)
5}
6
7module "vpc" {
8 source = "terraform-aws-modules/vpc/aws"
9 version = "3.18.1"
10
11 name = local.name
12 cidr = local.cidr_block
13 azs = data.aws_availability_zones.available.names
14 private_subnets = local.subnet_groups[0]
15 public_subnets = local.subnet_groups[1]
16 enable_dns_hostnames = true
17 enable_dns_support = true
18 enable_nat_gateway = false
19 single_nat_gateway = true
20}
21
22resource "aws_db_subnet_group" "mastodon" {
23 name = var.name
24 subnet_ids = module.vpc.public_subnets
25
26 tags = {
27 Name = var.name
28 }
29}
Powered by cgit v1.2.3 (git 2.41.0)