[小ネタ]AWS CloudFormationのスタック作成時、ネットワークインターフェースでの指定のやり方でつまづいた話

EC2インスタンスに自動でIPアドレスを割り当てようとした時に引っかかったエラーです。
2020.07.06

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

みなさんどうも、たいがーです。

先日、AWS CloudFormationのテンプレートを分解したブログを書きました。

分解することにより、テンプレートの書き方がわかってきたので、自分でテンプレートを作成しようとしていました。

今回の構成は非常にシンプルです。 VPCを作成し、その中にパブリックサブネットを作成します。その中にEC2インスタンスを起動し、セキュリティグループで22番、80番ポートのインバウンド通信を許可し、アウトバウンド通信は全て許可するように設定します。

また、インスタンスにはパブリックIPが自動で割り当てられるように設定していました。

Network interfaces and an instance-level 〇〇 may not be specified on the same request

AWS CloudFormationでスタックを作成している時、VPCやサブネット、セキュリティグループはうまく作成できました。

しかし、何度もインスタンスを作成する場面でこのようなエラーメッセージが発生し、ROLL_BACKを繰り返します。

Network interfaces and an instance-level 〇〇 may not be specified on the same request

ちなみに〇〇には、subnet ID、セキュリティグループが入っていました。

上記のエラーが出ていた時に私が作成していたテンプレートは、こちらです。(エラーの要因と考えられる部分だけ抜き出しています。)

"WebServerInstance" : {
        "Type" : "AWS::EC2::Instance",
        "DependsOn" : "AttachGateway",
        "Properties" : {
          "ImageId": "ami-00a5245b4816c38e6", 
          "InstanceType" : "t2.nano",
          "KeyName": {"Ref" : "KeyName"},
          "NetworkInterfaces": [ {
            "AssociatePublicIpAddress": "true",
            "DeviceIndex": "0",
            "GroupSet" : [{ "Ref" : "InstanceSecurityGroup"}],
            "SubnetId": { "Ref" : "Subnet" }
          } ],
          "SecurityGroupIds" : [{"Ref": "InstanceSecurityGroup"}],
          "SubnetId" : [{"Ref": "Subnet"}]
        }

エラーでは、"ネットワークインターフェースとインスタンスレベルのセキュリティグループを同じリクエストで指定することはできません。"と言われています。AWS CloudFormationでは、インスタンスにはセキュリティグループがアタッチできないのでしょうか?

もちろん、そんなことはありません。

無事、インスタンスにセキュリティグループをアタッチし、エラーの原因も判明しました。

インスタンスのSubnetやSecurityGroupを指定する場所に気をつけましょう

解決方法は至ってシンプルです。このように直します。

"WebServerInstance" : {
        "Type" : "AWS::EC2::Instance",
        "DependsOn" : "AttachGateway",
        "Properties" : {
          "ImageId": "ami-00a5245b4816c38e6", 
          "InstanceType" : "t2.nano",
          "KeyName": {"Ref" : "KeyName"},
          "NetworkInterfaces": [ {
            "AssociatePublicIpAddress": "true",
            "DeviceIndex": "0",
            "GroupSet" : [{ "Ref" : "InstanceSecurityGroup"}],
            "SubnetId": { "Ref" : "Subnet" }
          } ]
}

インスタンスのプロパティ内ではなく、"ネットワークインタフェースのプロパティ内"でのみ指定するように変更しました。

今回のエラーの原因としては、ネットワークインターフェイスを指定する場合、"ネットワークインターフェイスの一部としてサブネットやセキュリティグループを指定"する必要があるからでした。

ちなみにVPCの各インスタンスには、プライマリネットワークインターフェイスと呼ばれるデフォルトのネットワークインターフェイスがあり、今回はそちらの設定を変更するので"DeviceIndex"は"0"を指定しています。パブリック IP アドレスをネットワークインターフェイスと関連付けることができるのは、プライマリインターフェースのみだからです。

ネットワークインターフェイスを指定し、サブネットやセキュリティグループを指定する場合は、このように宣言しましょう!みなさんの参考になれば嬉しいです。

以上、たいがーでした?

参考資料