Make組ブログ

Python、Webアプリや製品・サービス開発についてhirokikyが書きます。

AWS上のデプロイ用インスタンスからPackerでAMIビルドしたらPackerBuilderにSSHできない問題を解決した話

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 ...

www.packer.io

動かないときは色々試す前に原因見つけような! ログがしょっぱいツールとかシステムのときは仕方ないけどね。

結構ハマったって話

デプロイサーバー上からもローカルからもPackerBuilderにSSHできるので原因が分からなかった。 デバッグ出力するとどうやらパブリックIPでつないでいるようだったので、これが原因だとわかった。

SecurityGroupはローカルIPで繋がないと、「SecurityGroupからアクセスがあった」と特定できないっていうのは気をつけないとね。