Created
December 29, 2021 20:49
-
-
Save akiraak/9c4cb34528cab6abab837d6d76488106 to your computer and use it in GitHub Desktop.
Terraform で AWS の普通のインフラ構築
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| variable "main" { | |
| default = { | |
| "aws_account_ids" = ["XXXXXXXXXX"] | |
| "app_name" = "XXXX" | |
| "region" = "ap-northeast-1" | |
| "az_1" = "ap-northeast-1a" | |
| "az_2" = "ap-northeast-1c" | |
| "acm_certificate_arn" = "arn:aws:acm:ap-northeast-1:XXXXXXXXX:certificate/XXXXXXXXXXXXXXXXXXXXXXXXXXXX" | |
| "app_public_key_path" = "XXXX.pub" | |
| "management_public_key_path" = "XXXX.pub" | |
| } | |
| } | |
| provider "aws" { | |
| region = var.main.region | |
| allowed_account_ids = var.main.aws_account_ids | |
| } | |
| /* | |
| module "aws" { | |
| source = "./modules" | |
| app_name = var.main.app_name | |
| az_1 = var.main.az_1 | |
| az_2 = var.main.az_2 | |
| } | |
| */ | |
| variable "vpc" { | |
| default = { | |
| "vpc_cidr_block" = "10.0.0.0/16" | |
| "subnet_public_management_1_cidr_block" = "10.0.240.0/24" | |
| "subnet_public_management_2_cidr_block" = "10.0.241.0/24" | |
| "subnet_public_app_alb_1_cidr_block" = "10.0.0.0/24" | |
| "subnet_public_app_alb_2_cidr_block" = "10.0.1.0/24" | |
| "subnet_private_app_1_cidr_block" = "10.0.8.0/24" | |
| "subnet_private_app_2_cidr_block" = "10.0.9.0/24" | |
| "subnet_private_app_db_1_cidr_block" = "10.0.16.0/24" | |
| "subnet_private_app_db_2_cidr_block" = "10.0.17.0/24" | |
| } | |
| } | |
| # ================================================ | |
| # VPC | |
| # ================================================ | |
| resource "aws_vpc" "main" { | |
| cidr_block = var.vpc.vpc_cidr_block | |
| enable_dns_support = true | |
| enable_dns_hostnames = true | |
| tags = { | |
| Name = "${var.main.app_name}-vpc" | |
| } | |
| } | |
| # ================================================ | |
| # Internet gateway & Root table to internet | |
| # ================================================ | |
| resource "aws_internet_gateway" "igw" { | |
| vpc_id = aws_vpc.main.id | |
| tags = { | |
| Name = "${var.main.app_name}-igw" | |
| } | |
| } | |
| resource "aws_route_table" "to_internet" { | |
| vpc_id = aws_vpc.main.id | |
| tags = { | |
| Name = "${var.main.app_name}-rt-to-internet" | |
| } | |
| } | |
| resource "aws_route" "to_internet" { | |
| route_table_id = aws_route_table.to_internet.id | |
| destination_cidr_block = "0.0.0.0/0" | |
| gateway_id = aws_internet_gateway.igw.id | |
| } | |
| # ================================================ | |
| # Subnet: Public management | |
| # ================================================ | |
| resource "aws_subnet" "public_management_1" { | |
| vpc_id = aws_vpc.main.id | |
| cidr_block = var.vpc.subnet_public_management_1_cidr_block | |
| availability_zone = var.main.az_1 | |
| tags = { | |
| Name = "${var.main.app_name}-su-public-management-1" | |
| } | |
| } | |
| resource "aws_subnet" "public_management_2" { | |
| vpc_id = aws_vpc.main.id | |
| cidr_block = var.vpc.subnet_public_management_2_cidr_block | |
| availability_zone = var.main.az_2 | |
| tags = { | |
| Name = "${var.main.app_name}-sn-public-management-2" | |
| } | |
| } | |
| resource "aws_route_table_association" "public_management_1" { | |
| subnet_id = aws_subnet.public_management_1.id | |
| route_table_id = aws_route_table.to_internet.id | |
| } | |
| resource "aws_route_table_association" "public_management_2" { | |
| subnet_id = aws_subnet.public_management_2.id | |
| route_table_id = aws_route_table.to_internet.id | |
| } | |
| # ================================================ | |
| # Subnet: Public app alb | |
| # ================================================ | |
| resource "aws_subnet" "public_app_alb_1" { | |
| vpc_id = aws_vpc.main.id | |
| cidr_block = var.vpc.subnet_public_app_alb_1_cidr_block | |
| availability_zone = var.main.az_1 | |
| tags = { | |
| Name = "${var.main.app_name}-sn-public-app-alb-1" | |
| } | |
| } | |
| resource "aws_subnet" "public_app_alb_2" { | |
| vpc_id = aws_vpc.main.id | |
| cidr_block = var.vpc.subnet_public_app_alb_2_cidr_block | |
| availability_zone = var.main.az_2 | |
| tags = { | |
| Name = "${var.main.app_name}-sn-public-app-alb-2" | |
| } | |
| } | |
| resource "aws_route_table_association" "public_app_alb_1" { | |
| subnet_id = aws_subnet.public_app_alb_1.id | |
| route_table_id = aws_route_table.to_internet.id | |
| } | |
| resource "aws_route_table_association" "public_app_alb_2" { | |
| subnet_id = aws_subnet.public_app_alb_2.id | |
| route_table_id = aws_route_table.to_internet.id | |
| } | |
| # ================================================ | |
| # Subnet: Private app | |
| # ================================================ | |
| resource "aws_subnet" "private_app_1" { | |
| vpc_id = aws_vpc.main.id | |
| cidr_block = var.vpc.subnet_private_app_1_cidr_block | |
| availability_zone = var.main.az_1 | |
| tags = { | |
| Name = "${var.main.app_name}-sn-private-app-1" | |
| } | |
| } | |
| resource "aws_subnet" "private_app_2" { | |
| vpc_id = aws_vpc.main.id | |
| cidr_block = var.vpc.subnet_private_app_2_cidr_block | |
| availability_zone = var.main.az_2 | |
| tags = { | |
| Name = "${var.main.app_name}-sn-private-app-2" | |
| } | |
| } | |
| # ================================================ | |
| # Subnet: Private app db | |
| # ================================================ | |
| resource "aws_subnet" "private_app_db_1" { | |
| vpc_id = aws_vpc.main.id | |
| cidr_block = var.vpc.subnet_private_app_db_1_cidr_block | |
| availability_zone = var.main.az_1 | |
| tags = { | |
| Name = "${var.main.app_name}-sn-private-app-db-1" | |
| } | |
| } | |
| resource "aws_subnet" "private_app_db_2" { | |
| vpc_id = aws_vpc.main.id | |
| cidr_block = var.vpc.subnet_private_app_db_2_cidr_block | |
| availability_zone = var.main.az_2 | |
| tags = { | |
| Name = "${var.main.app_name}-sn-private-app-db-2" | |
| } | |
| } | |
| # ================================================ | |
| # Security group: management | |
| # ================================================ | |
| resource "aws_security_group" "management" { | |
| name = "${var.main.app_name}-management" | |
| vpc_id = aws_vpc.main.id | |
| revoke_rules_on_delete = false | |
| egress { | |
| from_port = 0 | |
| to_port = 0 | |
| protocol = "-1" | |
| cidr_blocks = ["0.0.0.0/0"] | |
| } | |
| tags = { | |
| Name = "${var.main.app_name}-sg-management" | |
| } | |
| } | |
| # ssh | |
| resource "aws_security_group_rule" "app_permit_ssh" { | |
| security_group_id = aws_security_group.management.id | |
| cidr_blocks = ["0.0.0.0/0"] | |
| type = "ingress" | |
| protocol = "tcp" | |
| from_port = "22" | |
| to_port = "22" | |
| } | |
| # ================================================ | |
| # Security group: app alb | |
| # ================================================ | |
| resource "aws_security_group" "app_alb" { | |
| name = "${var.main.app_name}-app-alb" | |
| vpc_id = aws_vpc.main.id | |
| revoke_rules_on_delete = false | |
| egress { | |
| from_port = 0 | |
| to_port = 0 | |
| protocol = "-1" | |
| cidr_blocks = ["0.0.0.0/0"] | |
| } | |
| tags = { | |
| Name = "${var.main.app_name}-sg-app-alb" | |
| } | |
| } | |
| # http | |
| resource "aws_security_group_rule" "alb_permit_from_internet_http" { | |
| security_group_id = aws_security_group.app_alb.id | |
| cidr_blocks = ["0.0.0.0/0"] | |
| description = "permit from internet for http." | |
| type = "ingress" | |
| protocol = "tcp" | |
| from_port = "80" | |
| to_port = "80" | |
| } | |
| # https | |
| resource "aws_security_group_rule" "alb_permit_from_internet_https" { | |
| security_group_id = aws_security_group.app_alb.id | |
| cidr_blocks = ["0.0.0.0/0"] | |
| description = "permit from internet for https." | |
| type = "ingress" | |
| protocol = "tcp" | |
| from_port = "443" | |
| to_port = "443" | |
| } | |
| # ================================================ | |
| # Security group: app | |
| # ================================================ | |
| resource "aws_security_group" "app" { | |
| name = "${var.main.app_name}-app" | |
| vpc_id = aws_vpc.main.id | |
| revoke_rules_on_delete = false | |
| egress { | |
| from_port = 0 | |
| to_port = 0 | |
| protocol = "-1" | |
| cidr_blocks = ["0.0.0.0/0"] | |
| } | |
| tags = { | |
| Name = "${var.main.app_name}-sg-app" | |
| } | |
| } | |
| # http | |
| resource "aws_security_group_rule" "app_permit_from_app_alb_http" { | |
| security_group_id = aws_security_group.app.id | |
| source_security_group_id = aws_security_group.app_alb.id | |
| description = "permit from alb." | |
| type = "ingress" | |
| protocol = "tcp" | |
| from_port = "80" | |
| to_port = "80" | |
| } | |
| # ssh | |
| resource "aws_security_group_rule" "app_permit_from_management_ssh" { | |
| security_group_id = aws_security_group.app.id | |
| source_security_group_id = aws_security_group.management.id | |
| description = "permit from management." | |
| type = "ingress" | |
| protocol = "tcp" | |
| from_port = "22" | |
| to_port = "22" | |
| } | |
| # ================================================ | |
| # Security group: app db | |
| # ================================================ | |
| resource "aws_security_group" "app_db" { | |
| name = "${var.main.app_name}-app-db" | |
| vpc_id = aws_vpc.main.id | |
| revoke_rules_on_delete = false | |
| tags = { | |
| Name = "${var.main.app_name}-sg-app-db" | |
| } | |
| } | |
| resource "aws_security_group_rule" "app-db-sg-rule-mysql-from-app" { | |
| security_group_id = aws_security_group.app_db.id | |
| type = "ingress" | |
| from_port = 3306 | |
| to_port = 3306 | |
| protocol = "tcp" | |
| source_security_group_id = aws_security_group.app.id | |
| } | |
| resource "aws_security_group_rule" "app-db-sg-rule-mysql-from-management" { | |
| security_group_id = aws_security_group.app_db.id | |
| type = "ingress" | |
| from_port = 3306 | |
| to_port = 3306 | |
| protocol = "tcp" | |
| source_security_group_id = aws_security_group.management.id | |
| } | |
| # ALBアカウントIDを取得するために使用 | |
| data "aws_elb_service_account" "main" {} | |
| # ================================================ | |
| # ログ格納用バケットポリシー | |
| # ================================================ | |
| data "aws_iam_policy_document" "logging_bucket" { | |
| statement { | |
| sid = "" | |
| effect = "Allow" | |
| principals { | |
| identifiers = [ | |
| data.aws_elb_service_account.main.arn | |
| ] | |
| type = "AWS" | |
| } | |
| actions = [ | |
| "s3:PutObject" | |
| ] | |
| resources = [ | |
| "arn:aws:s3:::${var.main.app_name}-logging", | |
| "arn:aws:s3:::${var.main.app_name}-logging/*" | |
| ] | |
| } | |
| } | |
| # ================================================ | |
| # ログ格納用バケット | |
| # ================================================ | |
| resource "aws_s3_bucket" "logging" { | |
| bucket = "${var.main.app_name}-logging" | |
| policy = data.aws_iam_policy_document.logging_bucket.json ## iam.tfで設定したポリシーを使用。 | |
| force_destroy = true | |
| versioning { | |
| enabled = true | |
| mfa_delete = false | |
| } | |
| ## オブジェクトのライフサイクル設定。 | |
| lifecycle_rule { | |
| id = "assets" | |
| enabled = true | |
| ## オブジェクトの保存期限。 | |
| expiration { | |
| days = "365" ## 1年 | |
| } | |
| ## 現在のオブジェクトの移行設定。 | |
| transition { | |
| ## オブジェクトが作成されてから移行するまでの日数。 | |
| days = "93" ## 3ヶ月 | |
| storage_class = "STANDARD_IA" | |
| } | |
| ## オブジェクトの以前のバージョンの保存期限。 | |
| noncurrent_version_expiration { | |
| days = "1095" ## 3年 | |
| } | |
| ## 古いのオブジェクトの移行設定。 | |
| noncurrent_version_transition { | |
| ## オブジェクトが古いバージョンになってから移行するまでの日数。 | |
| days = "365" ## 1年 | |
| storage_class = "GLACIER" | |
| } | |
| } | |
| request_payer = "BucketOwner" | |
| } | |
| # S3 Public Access Block | |
| ## パブリックアクセスはしないため全て有効にする。 | |
| resource "aws_s3_bucket_public_access_block" "logging" { | |
| bucket = aws_s3_bucket.logging.bucket | |
| block_public_acls = true | |
| block_public_policy = true | |
| ignore_public_acls = true | |
| restrict_public_buckets = true | |
| } | |
| # ================================================ | |
| # ALB Target group: app | |
| # ================================================ | |
| resource "aws_lb_target_group" "app" { | |
| name = "${var.main.app_name}-tg-app" | |
| port = 80 | |
| protocol = "HTTP" | |
| target_type = "ip" | |
| vpc_id = aws_vpc.main.id | |
| # 登録解除を実行するまでの待機時間。 | |
| deregistration_delay = 300 # 処理中のリクエストの完了するのを待つためにデフォルト値を採用。 | |
| # 登録された後にリクエストを開始する猶予時間 | |
| slow_start = 0 # 登録されたらすぐに開始してよいので無効。 | |
| load_balancing_algorithm_type = "round_robin" # ラウンドロビンで平均的にリクエストを分散。 | |
| stickiness { | |
| type = "lb_cookie" | |
| cookie_duration = 86400 # 要件が決まっていないのでとりあえず1日を設定。 | |
| enabled = true | |
| } | |
| health_check { | |
| enabled = true | |
| interval = 30 | |
| path = "/" | |
| port = "traffic-port" # トラフィックを受信するポートを使用。デフォルト。 | |
| protocol = "HTTP" | |
| timeout = 5 | |
| healthy_threshold = 3 | |
| unhealthy_threshold = 3 | |
| matcher = "200-299" | |
| } | |
| } | |
| # ================================================ | |
| # ALB Listener: app | |
| # ================================================ | |
| # https | |
| resource "aws_lb_listener" "https" { | |
| load_balancer_arn = aws_lb.app.arn | |
| port = 443 | |
| protocol = "HTTPS" | |
| ssl_policy = "ELBSecurityPolicy-2016-08" | |
| certificate_arn = var.main.acm_certificate_arn | |
| default_action { | |
| type = "forward" | |
| target_group_arn = aws_lb_target_group.app.arn | |
| } | |
| } | |
| # Listener: HTTPをHTTPSにリダイレクトするためのリスナー | |
| resource "aws_lb_listener" "http_redirect_to_https" { | |
| load_balancer_arn = aws_lb.app.arn | |
| port = 80 | |
| protocol = "HTTP" | |
| default_action { | |
| type = "redirect" | |
| redirect { | |
| port = 443 | |
| protocol = "HTTPS" | |
| status_code = "HTTP_301" | |
| } | |
| } | |
| } | |
| # ================================================ | |
| # ALB: app | |
| # ================================================ | |
| resource "aws_lb" "app" { | |
| name = "${var.main.app_name}-alb-app" | |
| internal = false # 内部で使用しないため無効。 | |
| load_balancer_type = "application" | |
| security_groups = [ | |
| aws_security_group.app_alb.id | |
| ] | |
| access_logs { | |
| bucket = aws_s3_bucket.logging.bucket | |
| prefix = "elb" | |
| enabled = true | |
| } | |
| subnets = [ | |
| aws_subnet.public_app_alb_1.id, | |
| aws_subnet.public_app_alb_2.id | |
| ] | |
| idle_timeout = 60 # デフォルトの60秒を設定。 | |
| enable_deletion_protection = false # Terraformで削除したいため無効。 | |
| enable_http2 = true | |
| ip_address_type = "ipv4" # ipv6は使用しないためipv4を指定。 | |
| } | |
| # ================================================ | |
| # EC2: management | |
| # ================================================ | |
| data "aws_ami" "management" { | |
| most_recent = true | |
| owners = ["self"] | |
| filter { | |
| name = "name" | |
| values = ["*management*"] | |
| } | |
| } | |
| resource "aws_instance" "management" { | |
| ami = "${data.aws_ami.management.id}" | |
| vpc_security_group_ids = [aws_security_group.management.id] | |
| subnet_id = aws_subnet.public_management_1.id | |
| key_name = aws_key_pair.management.key_name | |
| instance_type = "t3.micro" | |
| associate_public_ip_address = "true" | |
| tags = { | |
| Name = "${var.main.app_name}-management" | |
| } | |
| } | |
| resource "aws_key_pair" "management" { | |
| key_name = "${var.main.app_name}-key-management" | |
| public_key = file(var.main.management_public_key_path) | |
| } | |
| # ================================================ | |
| # EC2: app | |
| # ================================================ | |
| data "aws_ami" "app" { | |
| most_recent = true | |
| owners = ["self"] | |
| filter { | |
| name = "name" | |
| values = ["*docker*"] | |
| } | |
| } | |
| resource "aws_instance" "app" { | |
| ami = "${data.aws_ami.app.id}" | |
| vpc_security_group_ids = [aws_security_group.app.id] | |
| subnet_id = aws_subnet.private_app_1.id | |
| key_name = aws_key_pair.app.key_name | |
| instance_type = "t3.micro" | |
| tags = { | |
| Name = "${var.main.app_name}-app" | |
| } | |
| } | |
| resource "aws_key_pair" "app" { | |
| key_name = "${var.main.app_name}-key-app" | |
| public_key = file(var.main.app_public_key_path) | |
| } | |
| # ================================================ | |
| # RDS: app db | |
| # ================================================ | |
| resource "aws_db_subnet_group" "app" { | |
| name = "${var.main.app_name}-db-sng-app" | |
| subnet_ids = ["${aws_subnet.private_app_db_1.id}", "${aws_subnet.private_app_db_2.id}"] | |
| tags = { | |
| Name = "${var.main.app_name}-db-sng-app" | |
| } | |
| } | |
| resource "aws_db_instance" "db" { | |
| identifier = "${var.main.app_name}-db-app" | |
| allocated_storage = 20 | |
| storage_type = "gp2" | |
| engine = "mysql" | |
| engine_version = "8.0.23" | |
| instance_class = "db.t3.micro" | |
| name = "${var.main.app_name}_app" | |
| username = "root" | |
| password = "rootroot" | |
| skip_final_snapshot = true | |
| vpc_security_group_ids = [aws_security_group.app_db.id] | |
| db_subnet_group_name = aws_db_subnet_group.app.name | |
| } | |
| # ================================================ | |
| # Route53 | |
| # ================================================ | |
| # ================================================ | |
| # ECR | |
| # ================================================ | |
| resource "aws_ecr_repository" "app" { | |
| name = "${var.main.app_name}-ecr-app" | |
| image_tag_mutability = "MUTABLE" | |
| image_scanning_configuration { | |
| scan_on_push = false | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment