この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
踏み台サーバーとは
踏み台サーバーはプライベートなサーバーにアクセスするために経由されるサーバーのことです。 今回はRedshiftクラスターはインターネットに接続していないため、EC2インスタンスを踏み台としてアクセスします。 こうすることで通信先を限定することができ、アクセスの管理がしやすくなります。 以下は今回の構成図です。
Redshiftクラスターにアクセスする場合は、EC2インスタンスを経由しなければアクセスできないようになっています。
Terraformでデプロイする
ネットワーク
network.tf
resource "aws_vpc" "example" {
cidr_block = "10.1.0.0/16"
enable_dns_hostnames = true
}
resource "aws_internet_gateway" "example" {
vpc_id = aws_vpc.example.id
}
resource "aws_subnet" "redshift_1a" {
cidr_block = "10.1.1.0/24"
availability_zone = "ap-northeast-1a"
vpc_id = aws_vpc.example.id
}
resource "aws_subnet" "bastion" {
cidr_block = "10.1.10.0/24"
availability_zone = "ap-northeast-1a"
vpc_id = aws_vpc.example.id
}
resource "aws_route_table" "main" {
vpc_id = aws_vpc.example.id
route {
cidr_block = "0.0.0.0/0"
gateway_id = aws_internet_gateway.example.id
}
}
resource "aws_route_table_association" "bastion_main" {
subnet_id = aws_subnet.bastion.id
route_table_id = aws_route_table.main.id
}
今回はサブネットを2つ作り、1つはRedshift用、1つを踏み台サーバー用(bastion)にしています。
インターネットゲートウェイを設置していますが踏み台サーバーのあるサブネットからしかアクセスできません。
ポイントとしてはVPCの設定でenable_dns_hostnames
をtrue
にしておくことです。
こうすることでVPC内からでもエンドポイントのドメイン名を解決できます。
Redshift
redshift.tf
resource "aws_security_group" "redshift" {
name = "redshift"
vpc_id = aws_vpc.example.id
description = "redshift cluster"
ingress {
from_port = 5439
to_port = 5439
protocol = "tcp"
security_groups = [aws_security_group.bastion.id]
}
}
resource "aws_redshift_cluster" "example" {
cluster_identifier = "example-cluster"
database_name = "example"
master_username = "exampleuser"
master_password = "SuperSecr3t"
node_type = "dc2.large"
cluster_type = "multi-node"
number_of_nodes = 2
publicly_accessible = false
cluster_subnet_group_name = aws_redshift_subnet_group.example.id
vpc_security_group_ids = [aws_security_group.redshift.id]
skip_final_snapshot = true
}
resource "aws_redshift_subnet_group" "example" {
name = "example"
subnet_ids = [aws_subnet.redshift_1a.id]
}
Redshiftクラスターとそれ用のセキュリティグループの設定をしています。 ポイントとしては以下の通りです。
- セキュリティグループを設定しアクセス制御
- 踏み台サーバー用のセキュリティグループからのアクセスのみを許可
- マルチノード構成のためノード数を2以上に
publicly_accessible
で外部との通信を二重で拒否
注意点
- ポート番号は何も指定しないと
5439
になります。 - 検証用なので
skip_final_snapshot
はtrue
にしていますが、本番で使う場合は適宜設定してください。 - 簡略化のためにユーザー名とパスワードをコードに埋め込んでいますが、これは危険です。
- AWS Secrets Mangerなどを利用して安全に保管しましょう
EC2
ec2.tf
resource "aws_security_group" "bastion" {
name = "bastion"
vpc_id = aws_vpc.example.id
description = "bastion server"
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
resource "aws_instance" "bastion" {
ami = "ami-0ca38c7440de1749a" # Amazon Linux 2 64_x86
instance_type = "t2.micro"
subnet_id = aws_subnet.bastion.id
iam_instance_profile = aws_iam_instance_profile.systems_manager.name
associate_public_ip_address = true
vpc_security_group_ids = [
aws_security_group.bastion.id
]
}
今回は割愛しますが、EC2インスタンスへはSessionManager経由で接続します。 そのためのIAMロールは適宜設定してください。 ポイントとしては以下の通りです。
- 踏み台サーバー用のセキュリティグループを設定
- 今回はSessionManager経由なのでアウトバウンドの設定のみで十分
- 外部とのアクセス用にパブリックIPを割り当てる。
接続してみる
エンドポイントはマネージドコンソールかTerraformから確認することができます。 今回はTerraformから確認します。
Redshiftクラスターのエンドポイントを確認する
$ terraform state show 'aws_redshift_cluster.example' | grep endpoint
endpoint = "example-cluster.XXXXXX.ap-northeast-1.redshift.amazonaws.com:5439"
はじめにドメイン名が解決されているか確認してみます。
以下ではSession Managerで接続したEC2インスタンス内で作業を行なっていきます。
プライベートアドレスで解決されているか確認
$ nslookup example-cluster.XXXXXX.ap-northeast-1.redshift.amazonaws.com
Server: 10.1.0.2
Address: 10.1.0.2#53
Non-authoritative answer:
Name: example-cluster.XXXXXX.ap-northeast-1.redshift.amazonaws.com
Address: 10.1.1.214
IPアドレスの範囲的にクラスターはap-northeast-1a
にプロビジョニングされたようです。
マネージドコンソールから確認するとリーダーノード1つとコンピュートノード2つが作成されています。
リーダーノードのIPアドレスが返されています。
ここでパブリックIPが設定されいますが、これは外部からアクセス可能であるかにかかわらず表示されるものです。
パブリックおよびプライベートクラスターノードの IP アドレスは、クラスターがパブリックにアクセス可能であるかどうかに関係なく表示されます。
psqlでRedshiftクラスターに接続
sh-4.2$ sudo yum install postgresql
sh-4.2$ psql -h example-cluster.XXXXXX.ap-northeast-1.redshift.amazonaws.com -p 5439 -U exampleuser -d example
Password for user exampleuser:
psql (9.2.24, server 8.0.2)
WARNING: psql version 9.2, server version 8.0.
Some psql features might not work.
SSL connection (cipher: ECDHE-RSA-AES256-GCM-SHA384, bits: 256)
Type "help" for help.
example=# \l
List of databases
name | owner | encoding | access privileges
--------------+-------------+----------+-------------------
dev | rdsdb | UNICODE |
example | exampleuser | UNICODE |
padb_harvest | rdsdb | UNICODE |
template0 | rdsdb | UNICODE | rdsdb=CT/rdsdb
template1 | rdsdb | UNICODE | rdsdb=CT/rdsdb
(5 rows)
無事に接続できました。 データベースも作成されています。
感想
Terraformを使用してプライベートなRedshiftクラスターを構築することができました。 VPCの設定も同時にできるので便利だと思います。 AdminerなどのWeb上で動くSQLクライアントを踏み台サーバーに設置すればHTTP経由でもアクセスできるので便利かもしれません。