前にRDS(MySQL)をやったのでAuroraもやってみた。
違いはDBのClusterがあるかないかでそれによりRDSProxyの設定項目が少し変わる程度。
amegaeru.hatenablog.jp
構成
実践!
1.環境構築
1-1.terraformコードを作成
# vi main.tf
provider "aws" { region = "ap-northeast-1" } variable "env" { default = { env_name = "test" vpc_cidr = "10.0.0.0/16" sb_az1a = "ap-northeast-1a" sb_az1a_cidr = "10.0.1.0/24" sb_az1c = "ap-northeast-1c" sb_az1c_cidr = "10.0.2.0/24" sb_az1a_p = "ap-northeast-1a" sb_az1a_cidr_p = "10.0.3.0/24" sb_az1c_p = "ap-northeast-1c" sb_az1c_cidr_p = "10.0.4.0/24" } } ### VPC resource "aws_vpc" "vpc" { cidr_block = "${var.env.vpc_cidr}" enable_dns_support = true enable_dns_hostnames = true tags = { Name = "${var.env.env_name}_vpc" } } ### Subnet resource "aws_subnet" "public_1a" { vpc_id = "${aws_vpc.vpc.id}" availability_zone = "${var.env.sb_az1a}" cidr_block = "${var.env.sb_az1a_cidr}" tags = { Name = "${var.env.env_name}_public_1a" } } resource "aws_subnet" "public_1c" { vpc_id = "${aws_vpc.vpc.id}" availability_zone = "${var.env.sb_az1c}" cidr_block = "${var.env.sb_az1c_cidr}" tags = { Name = "${var.env.env_name}_public_1c" } } resource "aws_subnet" "private_1a" { vpc_id = "${aws_vpc.vpc.id}" availability_zone = "${var.env.sb_az1a_p}" cidr_block = "${var.env.sb_az1a_cidr_p}" tags = { Name = "${var.env.env_name}_private_1a" } } resource "aws_subnet" "private_1c" { vpc_id = "${aws_vpc.vpc.id}" availability_zone = "${var.env.sb_az1c_p}" cidr_block = "${var.env.sb_az1c_cidr_p}" tags = { Name = "${var.env.env_name}_private_1c" } } ### InternetGateway resource "aws_internet_gateway" "igw" { vpc_id = aws_vpc.vpc.id tags = { Name = "${var.env.env_name}_igw" } } ### RouteTable_public resource "aws_route_table" "public" { vpc_id = aws_vpc.vpc.id route { cidr_block = "0.0.0.0/0" gateway_id = aws_internet_gateway.igw.id } tags = { Name = "${var.env.env_name}_public_route_table" } } resource "aws_route_table_association" "public_1a" { subnet_id = aws_subnet.public_1a.id route_table_id = aws_route_table.public.id } resource "aws_route_table_association" "public_1c" { subnet_id = aws_subnet.public_1c.id route_table_id = aws_route_table.public.id } ### RouteTable_private resource "aws_route_table" "private" { vpc_id = aws_vpc.vpc.id tags = { Name = "${var.env.env_name}_private_route_table" } } resource "aws_route_table_association" "private_1a" { subnet_id = aws_subnet.private_1a.id route_table_id = aws_route_table.private.id } resource "aws_route_table_association" "private_1c" { subnet_id = aws_subnet.private_1c.id route_table_id = aws_route_table.private.id } ### VPCEndpoint SecretManager resource "aws_vpc_endpoint" "secretsmanager" { vpc_id = aws_vpc.vpc.id service_name = "com.amazonaws.ap-northeast-1.secretsmanager" vpc_endpoint_type = "Interface" subnet_ids = [aws_subnet.private_1a.id, aws_subnet.private_1c.id] security_group_ids = [aws_security_group.example_vpce_sg.id] } ### SecurityGroup(VPCEndpoint) resource "aws_security_group" "example_vpce_sg" { name = "example_vpce_sg" description = "Allow RDS" vpc_id = aws_vpc.vpc.id ingress { from_port = 0 to_port = 0 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_security_group_rule" "egress_vpce_all" { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.example_vpce_sg.id } ### SecurityGroup(RDS Proxy) resource "aws_security_group" "example_rdsp_sg" { name = "example_rdsp_sg" description = "RDS Proxy" vpc_id = aws_vpc.vpc.id ingress { from_port = 3306 to_port = 3306 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } resource "aws_security_group_rule" "egress_rdsp_all" { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.example_rdsp_sg.id } ### SecurityGroup(RDS) resource "aws_security_group" "example_rds_sg" { name = "example_rds_sg" description = "RDS" vpc_id = aws_vpc.vpc.id ingress { from_port = 3306 to_port = 3306 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] } } ### SecurityGroup(EC2) resource "aws_security_group" "example_ec2_sg" { name = "example_ec2_sg" vpc_id = aws_vpc.vpc.id } resource "aws_security_group_rule" "ingress_ec2_http" { type = "ingress" from_port = 80 to_port = 80 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.example_ec2_sg.id } resource "aws_security_group_rule" "ingress_ec2_ssh" { type = "ingress" from_port = 22 to_port = 22 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.example_ec2_sg.id } resource "aws_security_group_rule" "egress_ec2_all" { type = "egress" from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] security_group_id = aws_security_group.example_ec2_sg.id } ### IAM Role(RDS) resource "aws_iam_role" "example_rds_iam_role" { name = "example-rds-iam-role" assume_role_policy = jsonencode({ Version = "2012-10-17", Statement = [ { Action = "sts:AssumeRole", Effect = "Allow", Principal = { Service = "rds.amazonaws.com" }, }, ], }) } # Secrets Managerへのアクセスを許可するIAMポリシー resource "aws_iam_policy" "secretsmanager_access" { name = "secretsmanager_access_policy" description = "Policy to allow RDS Proxy to access Secrets Manager" policy = jsonencode({ Version = "2012-10-17", Statement = [ { Action = [ "secretsmanager:GetSecretValue", "secretsmanager:DescribeSecret" ], Effect = "Allow", Resource = "*" } ] }) } # IAMポリシーをRDS ProxyのIAMロールにアタッチ resource "aws_iam_role_policy_attachment" "secretsmanager_access_attachment" { role = aws_iam_role.example_rds_iam_role.name policy_arn = aws_iam_policy.secretsmanager_access.arn } ### IAM Role(EC2) resource "aws_iam_role" "example-ec2-ssm-role" { name = "example-ec2-ssm-role" assume_role_policy = data.aws_iam_policy_document.example-ec2-assume-role.json } data "aws_iam_policy_document" "example-ec2-assume-role" { statement { actions = ["sts:AssumeRole"] principals { type = "Service" identifiers = ["ec2.amazonaws.com"] } } } data "aws_iam_policy" "example-ec2-policy_ssm_managed_instance_core" { arn = "arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore" } resource "aws_iam_role_policy_attachment" "example-ec2-ssm_managed_instance_core" { role = aws_iam_role.example-ec2-ssm-role.name policy_arn = data.aws_iam_policy.example-ec2-policy_ssm_managed_instance_core.arn } resource "aws_iam_instance_profile" "example-ec2-profile" { name = "example-ec2-profile" role = aws_iam_role.example-ec2-ssm-role.name } ### EC2 resource "aws_instance" "example" { ami = "ami-06180cd4edb6844d2" instance_type = "t2.micro" subnet_id = aws_subnet.public_1a.id security_groups = [aws_security_group.example_ec2_sg.id] associate_public_ip_address = true iam_instance_profile = aws_iam_instance_profile.example-ec2-profile.name user_data = <<-EOF #!/bin/bash sudo yum update -y sudo amazon-linux-extras install epel -y sudo yum install nginx -y sudo systemctl start nginx sudo systemctl enable nginx sudo yum install mysql -y EOF tags = { Name = "example-instance" } } ### SecretManager resource "aws_secretsmanager_secret" "example" { name = "mysecret" } resource "aws_secretsmanager_secret_version" "example" { secret_id = aws_secretsmanager_secret.example.id secret_string = "{\"username\":\"user\",\"password\":\"mypassword\"}" } ### RDS Proxy resource "aws_db_proxy" "example" { name = "example" debug_logging = false engine_family = "MYSQL" idle_client_timeout = 1800 require_tls = false role_arn = aws_iam_role.example_rds_iam_role.arn vpc_security_group_ids = [aws_security_group.example_rdsp_sg.id] vpc_subnet_ids = [aws_subnet.private_1a.id, aws_subnet.private_1c.id] auth { auth_scheme = "SECRETS" description = "example" iam_auth = "DISABLED" secret_arn = aws_secretsmanager_secret.example.arn } } # RDS Proxyターゲットグループ resource "aws_db_proxy_default_target_group" "default" { db_proxy_name = aws_db_proxy.example.name } resource "aws_db_proxy_target" "example" { db_proxy_name = aws_db_proxy.example.name target_group_name = "default" db_cluster_identifier = aws_rds_cluster.aurora_cluster.id ## ここがdb_cluster_identifierに代わって値はAuroraのものに変更 } ### RDS ## ここがClusterの設定に変更 resource "aws_rds_cluster" "aurora_cluster" { cluster_identifier = "aurora-cluster-demo" engine = "aurora-mysql" engine_version = "5.7.mysql_aurora.2.07.10" database_name = "mydb" master_username = "user" master_password = "mypassword" db_subnet_group_name = aws_db_subnet_group.example.name vpc_security_group_ids = [aws_security_group.example_rds_sg.id] skip_final_snapshot = true } ## ここがClusterの設定に変更 resource "aws_rds_cluster_instance" "aurora_instances" { count = 2 identifier = "aurora-instance-${count.index}" cluster_identifier = aws_rds_cluster.aurora_cluster.id instance_class = "db.r4.large" engine = "aurora-mysql" engine_version = "5.7.mysql_aurora.2.07.10" } resource "aws_db_subnet_group" "example" { name = "my-db-subnet-group" subnet_ids = [aws_subnet.private_1a.id, aws_subnet.private_1c.id] tags = { Name = "My DB Subnet Group" } }
1-2.terraform実行
# terraform plan # terraform apply
2.MySQL接続確認
2-1.[EC2] - 作成されたEC2インスタンスを選択 - [接続]
2-2.[接続]
2-3.接続できることを確認
2-4.RDS Proxyのエンドポイントへmysqlコマンドで接続し、接続できることを確認
sh-4.2$ mysql -h example.proxy-ckmgc9vjvwrf.ap-northeast-1.rds.amazonaws.com -u user -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 1617414075 Server version: 5.7.12 MySQL Community Server (GPL) Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> exit Bye
terraformで何度か作り直しをする場合、下記コマンドをCloudShellから実行しSecretManagerのシークレットを削除すること。
※terraformで削除しても7日間は使えない状態で残っていて、再作成した際にはすでにあるというエラーになるのでCLIでバッサリ削除する。
$ aws secretsmanager delete-secret --secret-id mysecret --force-delete-without-recovery { "ARN": "arn:aws:secretsmanager:ap-northeast-1:xxxxxxxxxxxx:secret:mysecret-3Q9YYz", "Name": "mysecret", "DeletionDate": "2023-11-23T16:12:26.020000+00:00" }
感想
半日かかった。。。