├── ap-northeast-1 ├── variables.tf ├── simple │ ├── variables.tf │ ├── terraform.tf │ ├── remote_state.tf │ ├── vpc_sg.tf │ └── ec2.tf ├── terraform.tf ├── vpc_sg.tf ├── output.tf ├── vpc_route.tf └── vpc.tf ├── .envrc ├── .gitignore ├── terraform.tf ├── remote_state.tf ├── variables.tf ├── README.md └── iam_role.tf /ap-northeast-1/variables.tf: -------------------------------------------------------------------------------- 1 | ../variables.tf -------------------------------------------------------------------------------- /ap-northeast-1/simple/variables.tf: -------------------------------------------------------------------------------- 1 | ../../variables.tf -------------------------------------------------------------------------------- /.envrc: -------------------------------------------------------------------------------- 1 | export AWS_PROFILE=default 2 | export AWS_REGION=ap-northeast-1 3 | export AWS_DEFAULT_REGION=${AWS_REGION} 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | trash 2 | terraform.tfvers 3 | .terraform.d 4 | crash.log 5 | .terraform 6 | *.tf_ 7 | *.tfstate 8 | *.tfstate.backup 9 | -------------------------------------------------------------------------------- /terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "> 0.10.0" 3 | backend "s3" { 4 | bucket = "my-terraform-state" 5 | key = "global.terraform.tfstate" 6 | region = "ap-northeast-1" 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ap-northeast-1/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "> 0.10.0" 3 | 4 | backend "s3" { 5 | bucket = "my-terraform-state" 6 | key = "ap-northeast-1/terraform.tfstate" 7 | region = "ap-northeast-1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ap-northeast-1/simple/terraform.tf: -------------------------------------------------------------------------------- 1 | terraform { 2 | required_version = "> 0.10.0" 3 | 4 | backend "s3" { 5 | bucket = "my-terraform-state" 6 | key = "ap-northeast-1/simple/terraform.tfstate" 7 | region = "ap-northeast-1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /ap-northeast-1/simple/remote_state.tf: -------------------------------------------------------------------------------- 1 | data "terraform_remote_state" "ap-northeast-1" { 2 | backend = "s3" 3 | 4 | config { 5 | bucket = "my-terraform-state" 6 | key = "ap-northeast-1/terraform.tfstate" 7 | region = "ap-northeast-1" 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /remote_state.tf: -------------------------------------------------------------------------------- 1 | data "terraform_remote_state" "ap-northeast-1" { 2 | backend = "s3" 3 | config { 4 | bucket = "my-terraform-state" 5 | key = "ap-northeast-1/terraform.tfstate" 6 | region = "ap-northeast-1" 7 | } 8 | } 9 | 10 | #data "terraform_remote_state" "us-east-2" { 11 | # backend = "s3" 12 | # config { 13 | # bucket = "my-terraform-state" 14 | # key = "us-east-2/terraform.tfstate" 15 | # region = "ap-northeast-1" 16 | # } 17 | #} 18 | -------------------------------------------------------------------------------- /variables.tf: -------------------------------------------------------------------------------- 1 | variable "cidr" { 2 | type = "map" 3 | 4 | default = { 5 | ap-northeast-1 = "10.0.0.0/16" 6 | us-west-2 = "10.1.0.0/16" 7 | us-east-2 = "10.2.0.0/16" 8 | } 9 | } 10 | 11 | variable "project_code" { 12 | type = "string" 13 | default = "mypj" 14 | } 15 | 16 | variable "my_ip_addresses" { 17 | type = "list" 18 | 19 | default = [ 20 | "xxx.xxx.xxx.xxx/32", 21 | ] 22 | } 23 | 24 | variable "key_pair" { 25 | type = "map" 26 | 27 | default = { 28 | ap-northeast-1 = "my-key-ap-northeast-1" 29 | #us-east-2 = "my-key-us-east-2" 30 | } 31 | } 32 | 33 | variable "ami_id" { 34 | type = "map" 35 | 36 | default = { 37 | ap-northeast-1 = "" # Base AMI build by Packer 38 | #us-east-2 = "" # Base AMI build by Packer 39 | } 40 | } 41 | 42 | variable "log_bucket" { 43 | type = "string" 44 | default = "my-aws-logs" 45 | } 46 | -------------------------------------------------------------------------------- /ap-northeast-1/simple/vpc_sg.tf: -------------------------------------------------------------------------------- 1 | ################################ 2 | # simple 3 | ################################ 4 | resource "aws_security_group" "simple-common" { 5 | name = "simple-common" 6 | description = "simple-common" 7 | vpc_id = "${data.terraform_remote_state.ap-northeast-1.vpc_id}" 8 | 9 | tags { 10 | Name = "simple-common" 11 | } 12 | } 13 | 14 | resource "aws_security_group_rule" "simple-common_egress_all" { 15 | security_group_id = "${aws_security_group.simple-common.id}" 16 | type = "egress" 17 | protocol = "-1" 18 | from_port = 0 19 | to_port = 0 20 | cidr_blocks = ["0.0.0.0/0"] 21 | } 22 | 23 | resource "aws_security_group_rule" "simple-common_ingress_self" { 24 | security_group_id = "${aws_security_group.simple-common.id}" 25 | type = "ingress" 26 | protocol = "-1" 27 | from_port = 0 28 | to_port = 0 29 | self = true 30 | } 31 | -------------------------------------------------------------------------------- /ap-northeast-1/vpc_sg.tf: -------------------------------------------------------------------------------- 1 | ################################ 2 | # SSH 3 | ################################ 4 | # ec2-bastion 5 | resource "aws_security_group" "ec2-bastion" { 6 | name = "ec2-bastion" 7 | description = "ec2-bastion" 8 | vpc_id = "${aws_vpc.main.id}" 9 | 10 | tags { 11 | Name = "ec2-bastion" 12 | } 13 | } 14 | 15 | resource "aws_security_group_rule" "ec2-bastion_egress_all" { 16 | security_group_id = "${aws_security_group.ec2-bastion.id}" 17 | type = "egress" 18 | protocol = "-1" 19 | from_port = 0 20 | to_port = 0 21 | cidr_blocks = ["0.0.0.0/0"] 22 | } 23 | 24 | resource "aws_security_group_rule" "ec2-bastion_ingress_22" { 25 | security_group_id = "${aws_security_group.ec2-bastion.id}" 26 | type = "ingress" 27 | protocol = "tcp" 28 | from_port = 22 29 | to_port = 22 30 | 31 | cidr_blocks = [ 32 | "${var.my_ip_addresses}", 33 | ] 34 | } 35 | -------------------------------------------------------------------------------- /ap-northeast-1/output.tf: -------------------------------------------------------------------------------- 1 | # vpc id 2 | output "vpc_id" { 3 | value = "${aws_vpc.main.id}" 4 | } 5 | 6 | # subnet id 7 | output "vpc_subnet" { 8 | value = "${ 9 | map( 10 | "public-a", element(aws_subnet.public.*.id, index(var.zones, "ap-northeast-1a")), 11 | "public-c", element(aws_subnet.public.*.id, index(var.zones, "ap-northeast-1c")), 12 | 13 | "private-a", element(aws_subnet.private.*.id, index(var.zones, "ap-northeast-1a")), 14 | "private-c", element(aws_subnet.private.*.id, index(var.zones, "ap-northeast-1c")), 15 | 16 | "protected-a", element(aws_subnet.protected.*.id, index(var.zones, "ap-northeast-1a")), 17 | "protected-c", element(aws_subnet.protected.*.id, index(var.zones, "ap-northeast-1c")), 18 | 19 | "lb-a", element(aws_subnet.lb.*.id, index(var.zones, "ap-northeast-1a")), 20 | "lb-c", element(aws_subnet.lb.*.id, index(var.zones, "ap-northeast-1c")), 21 | 22 | "nat-a", element(aws_subnet.nat.*.id, index(var.zones, "ap-northeast-1a")), 23 | "nat-c", element(aws_subnet.nat.*.id, index(var.zones, "ap-northeast-1c")), 24 | )}" 25 | } 26 | 27 | # security group 28 | output "vpc_sg" { 29 | value = "${ 30 | map( 31 | "ec2-bastion", aws_security_group.ec2-bastion.id, 32 | )}" 33 | } 34 | -------------------------------------------------------------------------------- /ap-northeast-1/vpc_route.tf: -------------------------------------------------------------------------------- 1 | ################################ 2 | # Gateway 3 | ################################ 4 | resource "aws_internet_gateway" "main" { 5 | vpc_id = "${aws_vpc.main.id}" 6 | 7 | tags { 8 | Name = "${var.project_code}-main" 9 | } 10 | } 11 | 12 | ################################ 13 | # Main RouteTable 14 | ################################ 15 | resource "aws_route_table" "main" { 16 | vpc_id = "${aws_vpc.main.id}" 17 | 18 | route { 19 | cidr_block = "0.0.0.0/0" 20 | gateway_id = "${aws_internet_gateway.main.id}" 21 | } 22 | 23 | tags { 24 | Name = "${var.project_code}-main" 25 | } 26 | } 27 | 28 | resource "aws_main_route_table_association" "main" { 29 | vpc_id = "${aws_vpc.main.id}" 30 | route_table_id = "${aws_route_table.main.id}" 31 | } 32 | 33 | ################################ 34 | # PrivateTable 35 | ################################ 36 | resource "aws_route_table" "private" { 37 | vpc_id = "${aws_vpc.main.id}" 38 | 39 | tags { 40 | Name = "${var.project_code}-private" 41 | } 42 | } 43 | 44 | resource "aws_route_table_association" "private" { 45 | count = "${length(var.zones)}" 46 | route_table_id = "${aws_route_table.private.id}" 47 | subnet_id = "${element(aws_subnet.private.*.id, count.index)}" 48 | } 49 | 50 | ################################ 51 | # ProtectedTable 52 | ################################ 53 | resource "aws_route_table" "protected" { 54 | vpc_id = "${aws_vpc.main.id}" 55 | 56 | tags { 57 | Name = "${var.project_code}-protected" 58 | } 59 | } 60 | 61 | resource "aws_route_table_association" "protected" { 62 | count = "${length(var.zones)}" 63 | route_table_id = "${aws_route_table.protected.id}" 64 | subnet_id = "${element(aws_subnet.protected.*.id, count.index)}" 65 | } 66 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # aws-terraform-template 2 | 3 | ## 設計方針 4 | - ディレクトリ階層毎にtfstateを分離 5 | - グローバル/リージョン/環境 で3階層 6 | - IPアドレスなどの全階層共通変数はvariables.tfに記載, symlinkで階層間を共有 7 | - AWSのARNやIDなどのAWSリソース情報はoutput, terraform_remote_stateを利用して階層間で共有 8 | - tfstateはs3管理, Backend S3を用いて同アカウントのs3にtfstateを保存 9 | 10 | ## ディレクトリ構成 11 | 12 | 階層 13 | ``` 14 | . 15 | |-- 16 | | |-- 17 | | | |-- .tf ... 環境毎のリソースを定義する (S3/CloudFront/EC2/S3/ElastiCache/RDS) 18 | | | |-- remote_state.tf 19 | | | |-- output.tf 20 | | | |-- terraform.tf 21 | | | `-- variables.tf -> ../../variables.tf 22 | | | 23 | | |-- .tf ... 全環境共通リソースを定義する(vpc, sg) 24 | | |-- remote_state.tf 25 | | |-- output.tf 26 | | |-- terraform.tf 27 | | `-- variables.tf -> ../variables.tf 28 | | 29 | |-- .tf ... iam等 全リージョン、全環境共通リソースを定義する 30 | |-- output.tf 31 | |-- remote_state.tf 32 | |-- terraform.tf 33 | `-- variables.tf 34 | ``` 35 | 36 | 各ディレクトリに配置するファイルについて 37 | ``` 38 | ./ 39 | |-- .tf ... 同階層に記載するAWSリソースを定義する,名前は任意 40 | |-- output.tf ... 別階層から参照する情報をouputに記載, 別階層のremote_state.tfから読み取る 41 | |-- remote_state.tf ... 別階層のtfstateに記載されている情報を参照 42 | |-- terraform.tf ... 同ディレクトリのterraform設定を記載(backend s3) 43 | `-- variables.tf ... 全環境共通の変数 44 | ``` 45 | 46 | 47 | ## VPC Subnet設計 48 | ### Region 49 | リージョン間VPNを貼る可能性を踏まえ、CIDRが被らないよう設計する 50 | 51 | | region | IPv4 CIDR | 52 | | :--- | :---- | 53 | | ap-northeast-1 | 10.0.0.0/16 | 54 | | other | 10.xx.0.0/16 | 55 | 56 | ### 広域サブネット 57 | /23割り * AZ (1AZ 507台) 58 | 1AZに500台以上作成する可能性がある場合、maskを広げて設計する。 59 | 60 | | name | masks | use | 61 | | :--- | :---- | :------------------------------------------------------ | 62 | | public-* | /23 | PublicIPを付与するEC2用 | 63 | | protected-* | /23 | 主に直接通信不要のEC2に利用 NAT-Gatwayを経由してOutBound通信可 | 64 | | private-* | /23 | 外部通信不要なEC2, RDS, ElastiCache等に利用 | 65 | 66 | ### 特殊サブネット 67 | /25割り * AZ (1AZ 123台まで) 68 | 69 | | name | masks | use | 70 | | :--- | :---- | :------------- | 71 | | lb-* | /25 | ELB, ALBに利用 | 72 | | nat-* | /25 | NAT-Gateway専用 | 73 | 74 | -------------------------------------------------------------------------------- /ap-northeast-1/simple/ec2.tf: -------------------------------------------------------------------------------- 1 | ################################ 2 | # Launch instance 3 | ################################ 4 | 5 | resource "aws_eip" "simple-web-1" { 6 | vpc = true 7 | } 8 | 9 | 10 | data "aws_ami" "amzn-ami-hvm" { 11 | most_recent = true 12 | filter { 13 | name = "name" 14 | values = ["amzn-ami-hvm-*"] 15 | } 16 | filter { 17 | name = "virtualization-type" 18 | values = ["hvm"] 19 | } 20 | filter { 21 | name = "architecture" 22 | values = ["x86_64"] 23 | } 24 | filter { 25 | name = "owner-alias" 26 | values = ["amazon"] 27 | } 28 | filter { 29 | name = "root-device-type" 30 | values = ["ebs"] 31 | } 32 | filter { 33 | name = "block-device-mapping.volume-type" 34 | values = ["gp2"] 35 | } 36 | #name_regex = "^(?!.*(.rc-)).+$" 37 | } 38 | 39 | resource "aws_eip_association" "eip_assoc" { 40 | instance_id = "${aws_instance.simple-web.0.id}" 41 | allocation_id = "${aws_eip.simple-web-1.id}" 42 | } 43 | 44 | resource "aws_instance" "simple-web" { 45 | ## hvm 46 | instance_type = "t2.micro" 47 | ami = "${data.aws_ami.amzn-ami-hvm.id}" 48 | 49 | subnet_id = "${data.terraform_remote_state.ap-northeast-1.vpc_subnet["public-a"]}" 50 | vpc_security_group_ids = [ 51 | "${aws_security_group.simple-common.id}", 52 | "${data.terraform_remote_state.ap-northeast-1.vpc_sg["ec2-bastion"]}", 53 | ] 54 | key_name = "${var.key_pair["ap-northeast-1"]}" 55 | iam_instance_profile = "${aws_iam_instance_profile.ec2-simple.name}" 56 | tags = { 57 | Name = "${var.project_code}-${format("simple-web-%02d", count.index)}" 58 | Roles = "web" 59 | Environment = "simple" 60 | auto_stop = "enable" 61 | amirotate = "{\"no_reboot\":true,\"retention_period\":170000}" 62 | } 63 | count = 1 64 | } 65 | 66 | resource "aws_iam_role" "ec2-simple" { 67 | name = "${var.project_code}-ec2-simple" 68 | path = "/" 69 | 70 | assume_role_policy = <