はじめに
下記記事のリソース作成をterraformで行ってみました。
SSM Session Managerを使用してPrivate Subnet内のRDSにアクセスする
事前準備
-
RDSの認証情報をyaml形式でSSMパラメータストアに手動保存
test-rdsdb_name: postgres username: postgres password: 適当なパスワード
-
EC2用のキーペアを手動作成
キーペア名:test-keypair
VPC作成
vpc.tf
resource "aws_vpc" "main" {
cidr_block = "10.0.0.0/16"
tags = {
Name = "test-vpc"
}
enable_dns_hostnames = true
enable_dns_support = true
}
resource "aws_subnet" "private1" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.0.0/24"
tags = {
Name = "test-private-subnet1"
}
availability_zone = "ap-northeast-1a"
}
resource "aws_subnet" "private2" {
vpc_id = aws_vpc.main.id
cidr_block = "10.0.1.0/24"
tags = {
Name = "test-private-subnet2"
}
availability_zone = "ap-northeast-1c"
}
VPCエンドポイント作成
vpc_endpoint.tf
resource "aws_security_group" "vpce_sg" {
name = "vpce-sg"
vpc_id = aws_vpc.main.id
description = "Security group for VPC Endpoints"
ingress {
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = [aws_subnet.private1.cidr_block, aws_subnet.private2.cidr_block]
}
}
resource "aws_vpc_endpoint" "ssm" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.ap-northeast-1.ssm"
vpc_endpoint_type = "Interface"
security_group_ids = [aws_security_group.vpce_sg.id]
private_dns_enabled = true
tags = {
"Name" = "test-ssm-vpe"
}
}
resource "aws_vpc_endpoint" "ssmmessages" {
vpc_id = aws_vpc.main.id
service_name = "com.amazonaws.ap-northeast-1.ssmmessages"
vpc_endpoint_type = "Interface"
security_group_ids = [aws_security_group.vpce_sg.id]
private_dns_enabled = true
tags = {
"Name" = "test-ssmmessages-vpe"
}
}
resource "aws_vpc_endpoint_subnet_association" "ssm" {
vpc_endpoint_id = aws_vpc_endpoint.ssm.id
subnet_id = aws_subnet.private1.id
}
resource "aws_vpc_endpoint_subnet_association" "ssmmessages" {
vpc_endpoint_id = aws_vpc_endpoint.ssmmessages.id
subnet_id = aws_subnet.private1.id
}
RDS作成
rds.tf
data "aws_ssm_parameter" "rds_params" {
name = "test-rds"
}
locals {
rds_params = yamldecode(data.aws_ssm_parameter.rds_params.value)
}
resource "aws_db_subnet_group" "main" {
name = "test-subnet-group"
subnet_ids = [aws_subnet.private1.id, aws_subnet.private2.id]
}
resource "aws_security_group" "rds_sg" {
name = "test-rds-sg"
vpc_id = aws_vpc.main.id
ingress {
protocol = "tcp"
from_port = 5432
to_port = 5432
cidr_blocks = ["${aws_instance.main.private_ip}/32"]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_db_instance" "main" {
identifier = "test-rds"
allocated_storage = 20
storage_type = "gp3"
engine = "postgres"
engine_version = "16.3"
instance_class = "db.t4g.micro"
db_subnet_group_name = aws_db_subnet_group.main.name
password = local.rds_params.password
username = local.rds_params.username
backup_retention_period = 7
multi_az = false
skip_final_snapshot = true
vpc_security_group_ids = [aws_security_group.rds_sg.id]
}
踏み台EC2作成
ec2.tf
resource "aws_security_group" "ec2_sg" {
name = "test-ec2-sg"
vpc_id = aws_vpc.main.id
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
Name = "test-ec2-sg"
}
}
resource "aws_iam_role" "ec2_role" {
name = "test-ec2-role"
assume_role_policy = data.aws_iam_policy_document.ec2_assume_role.json
}
data "aws_iam_policy_document" "ec2_assume_role" {
statement {
actions = ["sts:AssumeRole"]
effect = "Allow"
principals {
type = "Service"
identifiers = ["ec2.amazonaws.com"]
}
}
}
resource "aws_iam_role_policy_attachment" "ec2_policy" {
role = aws_iam_role.ec2_role.name
policy_arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore"
}
resource "aws_iam_instance_profile" "main" {
name = "test-ec2-instance-profile"
role = aws_iam_role.ec2_role.name
depends_on = [aws_iam_role_policy_attachment.ec2_policy]
}
resource "aws_instance" "main" {
ami = "ami-0283b1f9e59025981"
instance_type = "t4g.nano"
key_name = "test-keypair"
subnet_id = aws_subnet.private1.id
iam_instance_profile = aws_iam_instance_profile.main.id
vpc_security_group_ids = [aws_security_group.ec2_sg.id]
root_block_device {
volume_size = 8
volume_type = "gp3"
}
tags = {
Name = "test-ec2"
}
}
以上。