From 55bf0526c86c88f5ae0d20bad6587c72cd91e835 Mon Sep 17 00:00:00 2001 From: clarkzjw Date: Tue, 31 Jan 2023 14:24:47 -0800 Subject: add ec2, rds --- .gitignore | 3 +++ infra/.terraform.lock.hcl | 67 +++++++++++++++++++++++++++++++++++++++++++++++ infra/data.tf | 11 ++++++++ infra/keypair.tf | 4 +++ infra/main.tf | 46 ++++++++++++++++++++++++++++++++ infra/output.tf | 29 ++++++++++++++++++++ infra/rds.tf | 58 ++++++++++++++++++++++++++++++++++++++++ infra/sg.tf | 38 +++++++++++++++++++++++++++ infra/variables.tf | 58 ++++++++++++++++++++++++++++++++++++++++ infra/versions.tf | 17 ++++++++++++ infra/vpc.tf | 29 ++++++++++++++++++++ 11 files changed, 360 insertions(+) create mode 100644 infra/.terraform.lock.hcl create mode 100644 infra/data.tf create mode 100644 infra/keypair.tf create mode 100644 infra/main.tf create mode 100644 infra/output.tf create mode 100644 infra/rds.tf create mode 100644 infra/sg.tf create mode 100644 infra/variables.tf create mode 100644 infra/versions.tf create mode 100644 infra/vpc.tf diff --git a/.gitignore b/.gitignore index 7a3e2fd..845bc63 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +admin-rc +.idea/ + # Local .terraform directories **/.terraform/* 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 @@ +# This file is maintained automatically by "terraform init". +# Manual edits may be lost in future updates. + +provider "registry.terraform.io/cloudflare/cloudflare" { + version = "3.33.1" + constraints = "~> 3.29" + hashes = [ + "h1:yL+jBzX+P/VabdTwZ1V1+UjI1EH+S1UQtm3U+rZ4XtU=", + "zh:0387f5891f349fb0ef3b68cbbd212c4c1fabb921324cba4dfeda08ad3d91f338", + "zh:3c016161cb8de9fbf1cf7d0d6099fb9c1c0d1e7bcae36a6084285f7fa4726176", + "zh:43ea39ca52688c350fccc0207ae49a88835f8c56bbc437999acc7feb04d365fd", + "zh:6d184850613b26956634ea5a34c7a0dec775747ef400f83dad54ba48d060218e", + "zh:73236e553775b59af1987f6857c68a7c274aea85c21da9e0e8ad6e67ab5318a7", + "zh:753e07cbda96d020d5a1fe09beb322e8efeb2d11450c71d956f1ee03d923410c", + "zh:7e35d6437fd3add22ebecfe457bfe2f46a2ae58358e59f7ccdb22c13a49fce07", + "zh:878d479802ff633e5cc13da6a3b9eb41e572e1320b3ce45662390c8e97167c80", + "zh:890df766e9b839623b1f0437355032a3c006226a6c200cd911e15ee1a9014e9f", + "zh:950a7489e0394470fd0589121d1a0602c57164c854229fedb3319b717d9c2e23", + "zh:a2c3a4b14d4686042e8418860cd59a5f9876c56a755ca9530757307b9b9195cf", + "zh:a4dc55555cb79488a8dff002acf4e98061099721571e290b467872f7c30a897f", + "zh:b6148bbc97d375f185a2ab05243a4d45da82f0c67033a461179f8090bb8bfbd4", + "zh:c0d720c316f580a382d9bc2d00a78217b62fbd28e186dc814bc8d75482540ec2", + "zh:dd42c50c4fb93ec390871234f5a52e21aebf91765365c728f3f237c4db4f4748", + ] +} + +provider "registry.terraform.io/hashicorp/aws" { + version = "4.52.0" + constraints = ">= 3.73.0, ~> 4.46" + hashes = [ + "h1:Ofm8syFCBU8MFOiU+zg+vnTWkSdozpmvaA9xukNvcBg=", + "zh:00c865de3a0e7643f4e2e5c8d4ba91eee94a46d41090eb134baca6b58c107172", + "zh:1430682e26eba25d8ace19fa780361187f474153e455545235b4fe30637fdcc2", + "zh:1b9a4e5c889bd2022bd59fb924dc78e189f1b7a4fd718fcacda0f0a4cb74d6eb", + "zh:2485260141608f1d386d0f68934092bbf68a27d96f0d83c73222d0382aee02f5", + "zh:2fe67ee94e2df7dabee7e474356f8e907e7c8011533f9d71df8702d59f9060b2", + "zh:37babd1b7ff96ff1f42aa56d7575cacabda6f9f460ff651d70662bfd90076341", + "zh:54aa8d39f22ecab6613169f49d37d2ccfaf417e59dd7a8c8fc6bf92600c3384f", + "zh:5bf4a84b962a8d2da8f4ccf2a7de56fb6c7a1f566e8393b563977fc7872a8740", + "zh:8cb4a51f209a3cc497e53f09188c15c6675697587fe2ea14a6c7fff10c8c8476", + "zh:91f6bdcbb1e36471140982e9048b7ced437d3290b2cc21079e5429cc84fed2fd", + "zh:9b12af85486a96aedd8d7984b0ff811a4b42e3d88dad1a3fb4c0b580d04fa425", + "zh:9f8c01c3f677bc64ddefa41e59c6fc98860c11875d7f148af55969d3e3847f77", + "zh:b6b4fc0bd6f3c0adcd9531da3ccf8c25787ccd6ccc568f13ebbff1336d71a9e1", + "zh:d52a428bd92cc319088685ecac63b9f7d12d4cd6725604edb20d0c4f37a9936e", + "zh:e20252a851a0d38548a3c01a006bfc59ee1fc84217bf9eb95b22724769601b2b", + ] +} + +provider "registry.terraform.io/hashicorp/random" { + version = "3.4.3" + hashes = [ + "h1:xZGZf18JjMS06pFa4NErzANI98qi59SEcBsOcS2P2yQ=", + "zh:41c53ba47085d8261590990f8633c8906696fa0a3c4b384ff6a7ecbf84339752", + "zh:59d98081c4475f2ad77d881c4412c5129c56214892f490adf11c7e7a5a47de9b", + "zh:686ad1ee40b812b9e016317e7f34c0d63ef837e084dea4a1f578f64a6314ad53", + "zh:78d5eefdd9e494defcb3c68d282b8f96630502cac21d1ea161f53cfe9bb483b3", + "zh:84103eae7251384c0d995f5a257c72b0096605048f757b749b7b62107a5dccb3", + "zh:8ee974b110adb78c7cd18aae82b2729e5124d8f115d484215fd5199451053de5", + "zh:9dd4561e3c847e45de603f17fa0c01ae14cae8c4b7b4e6423c9ef3904b308dda", + "zh:bb07bb3c2c0296beba0beec629ebc6474c70732387477a65966483b5efabdbc6", + "zh:e891339e96c9e5a888727b45b2e1bb3fcbdfe0fd7c5b4396e4695459b38c8cb1", + "zh:ea4739860c24dfeaac6c100b2a2e357106a89d18751f7693f3c31ecf6a996f8d", + "zh:f0c76ac303fd0ab59146c39bc121c5d7d86f878e9a69294e29444d4c653786f8", + "zh:f143a9a5af42b38fed328a161279906759ff39ac428ebcfe55606e05e1518b93", + ] +} 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 @@ +data "aws_ami" "debian" { + most_recent = true + owners = ["136693071363"] + + filter { + name = "name" + values = ["debian-11-amd64-*"] + } +} + +data "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 @@ +resource "aws_key_pair" "framework" { + key_name = "framework" + public_key = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILS2i5/x9r+cv2j2/SUZ2x2fgQeGnJP1I7PUHC0UdWN6 framework" +} 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 @@ +locals { + name = var.name +} + +data "aws_subnet" "ec2" { + filter { + name = "availability-zone" + values = [aws_db_instance.mastodon.availability_zone] + } + filter { + name = "subnet-id" + values = module.vpc.public_subnets + } +} + +resource "aws_instance" "mastodon" { + ami = data.aws_ami.debian.id + instance_type = var.ec2_instance_type + + subnet_id = data.aws_subnet.ec2.id + key_name = "framework" + + vpc_security_group_ids = [aws_security_group.backend.id] + + root_block_device { + volume_type = "gp3" + // how to resize partition and file system after resizing ebs volume + // https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/recognize-expanded-volume-linux.html + volume_size = "30" + tags = { + Name = "${local.name}-root" + } + } + + tags = { + Name = local.name + } + + lifecycle { + ignore_changes = [ami] + } +} + +resource "aws_eip" "mastodon" { + instance = aws_instance.mastodon.id +} 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 @@ +output "rds_hostname" { + description = "RDS instance hostname" + value = aws_db_instance.mastodon.address +} + +output "rds_port" { + description = "RDS instance port" + value = aws_db_instance.mastodon.port +} + +output "rds_username" { + description = "RDS instance username" + value = aws_db_instance.mastodon.username +} + +output "rds_password" { + description = "RDS instance password" + value = random_password.rds_password.result + sensitive = true +} + +output "instance" { + description = "The main EC2 instance." + value = { + arn = aws_instance.mastodon.arn + public_ip = aws_eip.mastodon.public_ip + private_ip = aws_instance.mastodon.private_ip + } +} 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 @@ +resource "aws_db_parameter_group" "mastodon" { + name = var.name + family = var.rds_parameter_group +} + +resource "aws_db_instance" "mastodon" { + identifier = var.name + instance_class = var.rds_instance_class + allocated_storage = var.rds_storage_size + engine = var.rds_engine + engine_version = var.rds_engine_version + username = var.rds_username + password = random_password.rds_password.result + port = var.rds_port + db_subnet_group_name = aws_db_subnet_group.mastodon.name + vpc_security_group_ids = [aws_security_group.rds.id] + parameter_group_name = aws_db_parameter_group.mastodon.name + publicly_accessible = true + skip_final_snapshot = true + + backup_retention_period = 7 + performance_insights_enabled = true +} + +resource "random_password" "rds_password" { + length = 16 + special = false +} + +resource "aws_ssm_parameter" "rds_host" { + name = "/${var.name}/rds/host" + type = "String" + value = aws_db_instance.mastodon.address +} + +resource "aws_ssm_parameter" "rds_port" { + name = "/${var.name}/rds/port" + type = "String" + value = aws_db_instance.mastodon.port +} + +resource "aws_ssm_parameter" "mastodon_db_name" { + name = "/${local.name}/rds/name" + type = "String" + value = aws_db_instance.mastodon.db_name +} + +resource "aws_ssm_parameter" "mastodon_db_user" { + name = "/${local.name}/rds/username" + type = "String" + value = aws_db_instance.mastodon.username +} + +resource "aws_ssm_parameter" "mastodon_db_password" { + name = "/${local.name}/rds/password" + type = "SecureString" + value = random_password.rds_password.result +} 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 @@ +# EC 2 +resource "aws_security_group" "backend" { + name = local.name + vpc_id = module.vpc.vpc_id +} + +resource "aws_security_group_rule" "backend_ingress_ssh" { + security_group_id = aws_security_group.backend.id + type = "ingress" + protocol = "tcp" + from_port = 22 + to_port = 22 + cidr_blocks = ["0.0.0.0/0"] +} + +resource "aws_security_group_rule" "backend_egress_all" { + security_group_id = aws_security_group.backend.id + type = "egress" + protocol = "all" + from_port = 0 + to_port = 0 + cidr_blocks = ["0.0.0.0/0"] +} + +# RDS +resource "aws_security_group" "rds" { + name = "${local.name}-db" + vpc_id = module.vpc.vpc_id +} + +resource "aws_security_group_rule" "rds_ingress_backend" { + security_group_id = aws_security_group.rds.id + type = "ingress" + protocol = "tcp" + from_port = var.rds_port + to_port = var.rds_port + source_security_group_id = aws_security_group.backend.id +} 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 @@ +provider "aws" { + region = var.region +} + +variable "name" { + description = "Name of the service. It will be used to name EC2, and RDS instances." + default = "mastodon" +} + +variable "region" { + default = "us-west-2" + description = "AWS region" +} + +# RDS +variable "rds_instance_class" { + default = "db.t3.micro" +} + +variable "rds_storage_size" { + default = 20 +} + +variable "rds_username" { + default = "mastodon" +} + +variable "rds_engine" { + default = "postgres" +} + +variable "rds_engine_version" { + default = "13.7" +} + +variable "rds_parameter_group" { + default = "default.postgres13" +} + +variable "rds_port" { + default = 33060 +} + +# EC 2 +variable "ec2_instance_type" { + default = "t3a.medium" +} + +variable "site_domain" { + type = string + default = "m.jinwei.me" +} + +variable "cloudflare_account_id" { + description = "The Cloudflare UUID for the Account the Zone lives in." + type = string + sensitive = true +} 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 @@ +terraform { + required_providers { + aws = { + source = "hashicorp/aws" + version = "~> 4.46" + } + cloudflare = { + source = "cloudflare/cloudflare" + version = "~> 3.29" + } + } +} + +provider "aws" { + alias = "us-east-1" + region = "us-east-1" +} 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 @@ +locals { + cidr_block = "10.32.0.0/16" + subnets = cidrsubnets(local.cidr_block, 4, 4, 4, 4, 4, 4) + subnet_groups = chunklist(local.subnets, 3) +} + +module "vpc" { + source = "terraform-aws-modules/vpc/aws" + version = "3.18.1" + + name = local.name + cidr = local.cidr_block + azs = data.aws_availability_zones.available.names + private_subnets = local.subnet_groups[0] + public_subnets = local.subnet_groups[1] + enable_dns_hostnames = true + enable_dns_support = true + enable_nat_gateway = false + single_nat_gateway = true +} + +resource "aws_db_subnet_group" "mastodon" { + name = var.name + subnet_ids = module.vpc.public_subnets + + tags = { + Name = var.name + } +} -- cgit v1.2.3