こんにちは、やまぐちです。
CloudFormation で EC2 を構築しようとして、ステータスを確認するも「CREATE_IN_PROGRESS」から全然進まない!
といったご経験はございませんでしょうか。
エラーなら早く「CREATE_FAILED」を出して…!とエラー結果を早く欲しがってしまいます。
実はしばらく待ったらエラーがでます。
今回は以下のエラーが出た時の対処方法を考えたいと思います。
Value (ec2-test-role) for parameter iamInstanceProfile.name is invalid. Invalid IAM Instance Profile name (Service: AmazonEC2; Status Code: 400; Error Code: InvalidParameterValue; Request ID: リクエストID ; Proxy: null)
やってみる
パターン 1
まず以下のテンプレートから EC2 を構築します。
AWSTemplateFormatVersion: "2010-09-09" Parameters: ImageId: Type: AWS::EC2::Image::Id Description: AMI to use for the EC2 instance Subnet: Type: AWS::EC2::Subnet::Id Description: Subnet to deploy the EC2 instance in SecurityGroup: Type: AWS::EC2::SecurityGroup::Id Description: Security group to assign to the EC2 instance Resources: EC2Instance: Type: AWS::EC2::Instance Properties: BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: true VolumeSize: 8 VolumeType: gp3 IamInstanceProfile: !Ref IamRole ImageId: !Ref ImageId InstanceType: t3.micro Monitoring: false NetworkInterfaces: - AssociatePublicIpAddress: false DeleteOnTermination: true DeviceIndex: 0 GroupSet: - !Ref SecurityGroup SubnetId: !Ref Subnet IamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / RoleName: ec2-test-role
IAMロールは作成されますが、EC2 が「CREATE_IN_PROGRESS」から進みません!
挙句の果てにタイムアウトされてしまいました。
エラー内容は以下です
Value (ec2-test-role) for parameter iamInstanceProfile.name is invalid. Invalid IAM Instance Profile name (Service: AmazonEC2; Status Code: 400; Error Code: InvalidParameterValue; Request ID: リクエストID ; Proxy: null)
原因
エラーの内容からインスタンスプロファイルが怪しいなとわかります。
テンプレートの中では、IAMロールの作成をし、その IAMロールを EC2 へアタッチするような流れとなっています。
以下のようにEC2Instance
内のIamInstanceProfile
で IAM Role を参照しています。
IamInstanceProfile: !Ref IamRole
しかし、これだと EC2 に IAM ロールがアタッチされません。
EC2 の場合、インスタンスプロファイルを使用して IAM ロールを EC2 インスタンスに渡します。
なので、インスタンスプロファイルではなく IAM ロールを直接指定していたため EC2 が作成ができなかったという感じです。
以下、ドキュメントの引用です。
Amazon EC2 は、IAM ロールのコンテナとしてインスタンスプロファイルを使用します。IAM コンソールを使用して IAM ロールを作成すると、コンソールによりインスタンスプロファイルが自動的に作成され、対応するロールと同じ名前が付けられます。Amazon EC2 コンソールを使用して IAM ロールを持つインスタンスを起動する場合、またはインスタンスに IAM ロールをアタッチする場合は、インスタンスプロファイル名のリストに基づいてロールを選択します。
AWS CLI、API、または AWS SDK を使用してロールを作成する場合、ロールとインスタンスプロファイルを別個のアクションとして作成します。名前は異なる可能性があります。次に AWS CLI、API、または AWS SDK を使用して IAM ロールを持つインスタンスを起動する場合、またはインスタンスに IAM ロールをアタッチする場合は、インスタンスプロファイル名を指定します。
インスタンスプロファイルに含めることができる IAM ロールの数は 1 つのみです。この制限を増やすことはできません。
解決法
テンプレートを以下のようにします
AWSTemplateFormatVersion: "2010-09-09" Parameters: ImageId: Type: AWS::EC2::Image::Id Description: AMI to use for the EC2 instance Subnet: Type: AWS::EC2::Subnet::Id Description: Subnet to deploy the EC2 instance in SecurityGroup: Type: AWS::EC2::SecurityGroup::Id Description: Security group to assign to the EC2 instance Resources: EC2Instance: Type: AWS::EC2::Instance Properties: BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: true VolumeSize: 8 VolumeType: gp3 IamInstanceProfile: !Ref IamInstanceProfile ImageId: !Ref ImageId InstanceType: t3.micro Monitoring: false NetworkInterfaces: - AssociatePublicIpAddress: false DeleteOnTermination: true DeviceIndex: 0 GroupSet: - !Ref SecurityGroup SubnetId: !Ref Subnet IamInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref IamRole IamRole: Type: AWS::IAM::Role Properties: AssumeRolePolicyDocument: Version: "2012-10-17" Statement: - Effect: Allow Principal: Service: - ec2.amazonaws.com Action: - sts:AssumeRole Path: / RoleName: ec2-test-role
修正点 1
以下を追記し、インスタンスプロファイルを作成するようにしました。
IamInstanceProfile: Type: AWS::IAM::InstanceProfile Properties: Path: / Roles: - !Ref IamRole
修正点 2
EC2Instance
内のIamInstanceProfile
で作成したインスタンスプロファイルを参照するようにしました。
IamInstanceProfile: !Ref IamInstanceProfile
結果
ということで見事「CREATE_COMPLETE」で EC2 インスタンスが作成完了しました!
パターン 2
次のパターンとして、すでに作成済みの IAM ロールを指定して EC2 を作成してみましょう!
テンプレートを以下です。
AWSTemplateFormatVersion: "2010-09-09" Parameters: ImageId: Type: AWS::EC2::Image::Id Description: AMI to use for the EC2 instance Subnet: Type: AWS::EC2::Subnet::Id Description: Subnet to deploy the EC2 instance in SecurityGroup: Type: AWS::EC2::SecurityGroup::Id Description: Security group to assign to the EC2 instance Resources: EC2Instance: Type: AWS::EC2::Instance Properties: BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: true VolumeSize: 8 VolumeType: gp3 IamInstanceProfile: ec2-test-role ImageId: !Ref ImageId InstanceType: t3.micro Monitoring: false NetworkInterfaces: - AssociatePublicIpAddress: false DeleteOnTermination: true DeviceIndex: 0 GroupSet: - !Ref SecurityGroup SubnetId: !Ref Subnet
先ほどのテンプレートと違う点は、IAM ロール「ec2-test-role」はパターン1ですでに作成済みのためそのまま直接指定しています。
IAMロールはすでに作成済みのため、当然 IAMロールやインスタンスプロファイルの作成は行っていません。
IamInstanceProfile: ec2-test-role
このテンプレートをアップロードして作成を試みるも
「CREATE_IN_PROGRESS」から進まない…!
しばらくすると、パターン1と同じエラーが出ました。
原因
原因はパターン1と同じです。インスタンスプロファイルです。
「でも、今回は既に IAMロールがあるわけだし…」
だから、IAMロールではなくインスタンスプロファイルなんです。
パターン1で作成した IAM ロール「ec2-test-role」をマネコンから確認します。
あれ、ARN と インスタンスプロファイルの ARN !?
パターン1で引用したドキュメントの内容をもう一度出します。
AWS CLI、API、または AWS SDK を使用してロールを作成する場合、ロールとインスタンスプロファイルを別個のアクションとして作成します。名前は異なる可能性があります。次に AWS CLI、API、または AWS SDK を使用して IAM ロールを持つインスタンスを起動する場合、またはインスタンスに IAM ロールをアタッチする場合は、インスタンスプロファイル名を指定します。
AWS CLI、API、または AWS SDK で IAMロールを使用する場合は、IAMロール名とインスタンスプロファイル名が異なるものになると記載されています。
ということで、インスタンスプロファイル名が必ずしもIAMロール名と同じになっているとは限らないのです。
今回の場合は以下のように IAMロール名とインスタンスプロファイル名が異なります。
IAMロール名:ec2-test-role
インスタンスプロファイル名:ec2-test2-IamInstanceProfile-IUGySFIUWGfq
解決法
ということで、IamInstanceProfile:
にインスタンスプロファイル名を指定します。
AWSTemplateFormatVersion: "2010-09-09" Parameters: ImageId: Type: AWS::EC2::Image::Id Description: AMI to use for the EC2 instance Subnet: Type: AWS::EC2::Subnet::Id Description: Subnet to deploy the EC2 instance in SecurityGroup: Type: AWS::EC2::SecurityGroup::Id Description: Security group to assign to the EC2 instance Resources: EC2Instance: Type: AWS::EC2::Instance Properties: BlockDeviceMappings: - DeviceName: /dev/xvda Ebs: DeleteOnTermination: true VolumeSize: 8 VolumeType: gp3 IamInstanceProfile: ec2-test2-IamInstanceProfile-IUGySFIUWGfq ImageId: !Ref ImageId InstanceType: t3.micro Monitoring: false NetworkInterfaces: - AssociatePublicIpAddress: false DeleteOnTermination: true DeviceIndex: 0 GroupSet: - !Ref SecurityGroup SubnetId: !Ref Subnet
変更点
インスタンスプロファイルを IAMロール名からインスタンスプロファイル名に変更しました。
IamInstanceProfile: ec2-test2-IamInstanceProfile-IUGySFIUWGfq
結果
EC2 が作成されました。
余談
AWS CLI、API、または AWS SDK を使用してロールを作成する場合とことなのでマネコンから作成した場合はどうなるのでしょうか?
マネコンから IAMロールを作成した結果、IAMロール名とインスタンスプロファイル名は同じになりました。
まとめ
- CloudFormation で IAMロールと EC2 を作成する時は、インスタンスプロファイルも作成し、参照させること
- 既存の IAMロールを指定して EC2 を構築する時はインスタンスプロファイル名が IAMロール名と一致しているかを確認すること