IAP TCP転送をローカルプロトコルに割り当てて、ローカルマシンから直接PrivateなCloudSQLにアクセスする方法を書いていきます。
タイトルのアクセス方法を見つけるまでは、VMにSSH接続してからCloudSQLにアクセスしていました。
VMには外部IPアドレスを持たせていないのでIdentity Aware Proxy(以降IAP)経由でVMにアクセスしています。
この方法だとSHELLでしか操作ができないので、DBクライアントツール大好きマンな私はとても辛い日々を過ごしておりました。
そんな日々を過ごす中で、ふと思いつきました。
『IAP経由でVMにアクセスしてMySQLにアクセスできるのなら、IAPをポートフォワーディングするなりなんなりできればローカルマシンからもMySQLにアクセスできるのではないか』 と。
そしてIAPのドキュメントから見つけ出したのが 『IAP TCP 転送』 です。
https://cloud.google.com/iap/docs/using-tcp-forwarding?hl=ja
IAP TCP 転送では、SSH、RDP、その他のトラフィックを VM インスタンスに転送できる暗号化トンネルを確立できます。IAP TCP 転送では、トンネルの確立を許可するユーザーと、ユーザーの接続を許可する VM インスタンスをきめ細かく制御することもできます
まさに私が求めていたもの!!!
早速試します。
1. VPC作成
IP範囲35.235.240.0/20
はIAP が TCP 転送に使用するすべての IP アドレスが含まれてます。
このIP範囲を許可するFWルールがないとIAP経由でのSSHができないので、必須ルールになります。
module "vpc_iap_tcp" {
source = "terraform-google-modules/network/google"
version = "~> 6.0"
project_id = var.project_id
network_name = "vpc-iap-tcp"
routing_mode = "GLOBAL"
subnets = [
{
subnet_name = "vpc-iap-tcp-sub"
subnet_ip = "10.10.10.0/24"
subnet_region = "asia-northeast1"
}
]
firewall_rules = [
# IAP TCP 転送に使用するすべてのIPアドレスからの上り(内向き)トラフィックを許可
{
name = "fw-allow-ssh-ingress-from-ssh"
direction = "INGRESS"
allow = [{
protocol = "tcp"
ports = ["22"]
}]
ranges = [
"35.235.240.0/20"
]
},
]
}
2. 外部IPアドレスを持たないVM(Compute Engine)を作成
resource "google_compute_instance" "gce_vpn_test" {
name = "gce-iap-tcp"
machine_type = "e2-standard-2"
zone = "asia-northeast1-a"
boot_disk {
initialize_params {
image = "ubuntu-os-cloud/ubuntu-2204-lts"
}
}
network_interface {
subnetwork = module.vpc_iap_tcp.subnets["asia-northeast1/vpc-iap-tcp-sub"].self_link
}
}
3. 外部IPアドレスを持たないCloudSQLインスタンスを作成
module "private_service_access" {
source = "GoogleCloudPlatform/sql-db/google//modules/private_service_access"
version = "14.0.0"
project_id = var.project_id
vpc_network = module.vpc_iap_tcp.network_name
}
module "sql_iap_tcp" {
source = "GoogleCloudPlatform/sql-db/google//modules/mysql"
version = "14.0.0"
project_id = var.project_id
name = "sql-iap-tcp"
random_instance_name = true
database_version = "MYSQL_8_0"
region = var.region
zone = var.zone
tier = "db-f1-micro" # 検証用なので低スペックなマシンタイプを使用
deletion_protection = false # 検証用なので削除保護は無効
ip_configuration = {
ipv4_enabled = false # 外部IPアドレスは無効
private_network = module.vpc_iap_tcp.network_id
require_ssl = false
allocated_ip_range = module.private_service_access.google_compute_global_address_name
authorized_networks = []
}
additional_databases = [
{
name = "iap-tcp",
charset = "utf8mb4"
collation = "utf8mb4_bin"
}
]
depends_on = [module.private_service_access.peering_completed]
}
4. VMにSSH接続する
SSH接続が成功すると~/.ssh
ディレクトリにSSH認証鍵関連ファイルが生成されます。
gcloud compute ssh IAMユーザ名@GCEインスタンス名
# `gcloud compute ssh GCEインスタンス名`でもSSH接続できますが、DBクライアントツールからCloudSQLにアクセスする時にエラーになります
.ssh
├── google_compute_engine
├── google_compute_engine.pub
├── google_compute_known_hosts
├── ...
├── ..
├── .
VMのSSH接続解除
exit
5. ローカルマシンとVMの間にIAPトンネルを作成する(IAP TCP 転送)
gcloud compute start-iap-tunnel gce-iap-tcp 22 \
--local-host-port=localhost:2022 \
--zone=asia-northeast1-a
上記コマンドを実行するとローカルマシンはHTTPSでIAPにアクセスしVMとのトンネルを作成します。
トンネルが存在している間、ローカルポート(Port:22)に送信されるすべてのトラフィックはVMに転送されるようになります。
Listening on port [ローカルポート]
と表示されれば成功です。
...
Testing if tunnel connection works.
Listening on port [2022].
DBクライアントツールでPrivateなCloudSQLにアクセスしてみる
今回はMySQLWorkbenchを使用します。
項目 | 値 |
---|---|
SSH Hostname | localhost:ローカルポート |
SSH Username | 自身のIAMユーザ名 |
SSH Password | 未設定 |
SSH Key File |
gcloud compute ssh で生成したSSH認証鍵 |
MySQL Hostname | CloudSQLにプライベートIP |
MySQL Server Port | MySQLのポート |
Username | MySQLユーザ名 |
Password | MySQLユーザパスワード |
「Test Connection」ボタンをクリックしてSuccessfully
と表示されたら成功です。
クライアントツールから実際に接続して、データベースも確認できました。
これで、PrivateなCloudSQLもDBクライアントツールで快適に操作できるようになりました。
VPN不要なのに手軽 かつ セキュアにCloudSQLに接続できるCloud IAP最高。