Packer が好きで使ってます。 AWSのAMIをビルドするために使ってるんですが、そこであった話。
構成
デプロイ用のインスタンスから packer build
してAMIを作る。
- PackerBuilderには既存のSecurityGroup(セキュリティグループ)を指定する
- PackerBuilderはPublicAccessを受け付ける
- ParkerBuilderには既存のSSHキーペアを指定する
この既存のSecurityGroupは「デフォルト」のSecurityGroupで、このSecurityGroup自身からのアクセスを受け付けるようにしています。 デプロイ用のインスタンスも、PackerBuilderも同じSecurityGroupに所属させることでアクセスを許可しようという狙いです。
起こったこと
packer build
中にSSH接続できない
原因と理由
PackerはデフォルトでパブリックIPを使って接続しようとしていたのが原因(PackerBuilderでPublicAccessを受け付けるようにしていたからかな)。 SecurityGroupは パブリックIPを通して接続すると、「特定のSecurityGroupからのアクセス」と特定できなくなってしまう ので、単なる外部アクセスと判断されてSSHが拒否されていた。
ローカルIPを直接使うか、パブリックDNS(Public DNS)を使えば、EC2インスタンス上からIPを引けばローカルIPが取得できるのでアクセスできる (正しく特定のSecurityGroupからアクセスがあったと判断してもらえる)。
解決方法
packer.json
に "ssh_interface": "public_dns"
を指定して、パブリックDNSを使ってSSH接続するようにした。
"builders": [ { "type": "amazon-ebs", ... "associate_public_ip_address": true, "security_group_ids": ["<デフォルトSecurityGroup>"], "ssh_keypair_name": "...", "ssh_private_key_file": "...", "ssh_interface": "public_dns" }, ]
Amazon EBS - Builders - Packer by HashiCorp
デプロイサーバー上でパブリックDNSを引けばローカルIPが引けるので問題なし。
まぁ、 "local_ip"
を指定してもいいんだけど。
Packerのデバッグ方法
Packerのログを見るときはPACKER_LOG=1 をつけて実行すると良い。 実行している内容とかが標準出力ででる。
$ PACKER_LOG=1 packer build ...
あと packer build -debug ... とオプションを付ければステップ実行できる。 便利よ。
$ PACKER_LOG=1 packer build -debug ...
動かないときは色々試す前に原因見つけような! ログがしょっぱいツールとかシステムのときは仕方ないけどね。
結構ハマったって話
デプロイサーバー上からもローカルからもPackerBuilderにSSHできるので原因が分からなかった。 デバッグ出力するとどうやらパブリックIPでつないでいるようだったので、これが原因だとわかった。
SecurityGroupはローカルIPで繋がないと、「SecurityGroupからアクセスがあった」と特定できないっていうのは気をつけないとね。