🥅
Terraform × VPCで仮想ネットワークを構築した
目的
- せっかくなのでクラウドインフラへの知見を深めたい。
- AWS Cognitoを活用しているので、インフラ構成はAWSを用いる。
- Terraformでの管理を前提とする。
目指すもの
- 個人で開発した「認証機能しかないアプリ」を本番環境で運用したい。
- まずはECRに登録したコンテナイメージをECS上にデプロイするところまでを目標とする。
設計図
- 留意点:ユーザー認証周りはALBとCognitoで連携できるが、今回はなぜかアプリ側で認証機能を書いているので、微妙な構成になっている。
VPC
- リソースの配置、接続性、セキュリティなどを制御可能な仮想ネットワーク
- 仮想ネットワーク内のインスタンスのアクセス制限
- 独自の IP アドレス範囲の選択
- サブネットの作成
- ルートテーブルの設定
- ゲートウェイ・エンドポイントの設定
VPC Network
- 大枠のネットワーク
aws_vpc
を定義する。-
enable_dns_support
:DNS 解決をサポートするかどうか -
cidr_block
:- 将来的なサービスの拡張性よりIPを枯渇させない、サブネットとIPの計算が楽になるという理由で /16 を選択した。
-
resource "aws_vpc" "vpc_network" {
cidr_block = var.vpc_network # "192.168.0.0/16"
enable_dns_support = true
enable_dns_hostnames = true
}
Public Subnet
- インターネット経由でアクセスできるサブネット。
-
map_public_ip_on_launch
:パブリックIPは「必要」
-
resource "aws_subnet" "public_subnet" {
vpc_id = aws_vpc.vpc_network.id
availability_zone = var.region # "ap-northeast-1a"
cidr_block = var.public_subnet # "192.168.1.0/24"
map_public_ip_on_launch = true
}
Private Subnet
- インターネット経由でアクセスできないサブネット。
-
map_public_ip_on_launch
:パブリックIPは「不要」
-
resource "aws_subnet" "private_subnet" {
vpc_id = aws_vpc.vpc_network.id
availability_zone = var.region # "ap-northeast-1a"
cidr_block = var.private_subnet # "192.168.2.0/24"
map_public_ip_on_launch = false
}
ここまでの構成図
Internet Gateway
- 外部インターネットとVPC間を双方向に接続する時の窓口となるゲートウェイ。
resource "aws_internet_gateway" "internet_gateway" {
vpc_id = aws_vpc.vpc_network.id
}
- ルーティングテーブルを作成する。
- ルーター内で経路情報を指し示す経路表を示す。
resource "aws_route_table" "public_routes" {
vpc_id = aws_vpc.vpc_network.id
}
resource "aws_route" "public_igw_route" {
route_table_id = aws_route_table.public_routes.id
gateway_id = aws_internet_gateway.internet_gateway.id
}
VPC EndPoint
VPCエンドポイントとは...?
- VPCと他のサービス(ECR)間の通信を可能にするVPCコンポーネント
- 接続が発生するたびにコストがかかるNATゲートウェイを使用するより、コスト的に◎
- コンテナー内のログをCloudWatchに送信する。 →
logs
- AWS Systems Manager パラメータストア経由で環境変数を使用する。 →
ssm
Interface型
-
vpc_endpoint_type
:ECRに対応しているInterface型
を採用する。 -
security_group_ids
:次章でセキュリティグループに関する設定を説明する。
VPCエンドポイントとAWSサービスとの通信は、Amazonのネットワーク内で完結している。
このネットワークをPrivateLink
と呼ぶが、PrivateLink
接続できるものはInterface型
を用いる。
resource "aws_vpc_endpoint" "interface_endpoint" {
vpc_id = aws_vpc.vpc_network.id
for_each = toset(var.vpc_endpoints_interface)
# ["ecr.dkr", "ecr.api", "logs", "ssm"]
service_name = "com.amazonaws.ap-northeast-1.${each.value}"
vpc_endpoint_type = "Interface"
subnet_ids = [aws_subnet.private_subnet.id]
security_group_ids = [var.vpc_endpoints_security_groups]
depends_on = [
aws_vpc.vpc_network, aws_subnet.private_subnet
]
private_dns_enabled = true
}
Gateway型
-
vpc_endpoint_type
:設置時間に応じて費用が発生しないGateway型を採用する。
resource "aws_vpc_endpoint" "gateway_endpoint" {
vpc_id = aws_vpc.vpc_network.id
for_each = toset(var.vpc_endpoints_gateway) # ["s3"]
service_name = "com.amazonaws.ap-northeast-1.${each.value}"
vpc_endpoint_type = "Gateway"
}
Discussion