はじめに
こんにちは!nayaaaaです。
最近Kubernetesの学習をしていたのですが、そろそろAWSのハンズオンもやっておきたいなぁというところで、Terraformを使ってEC2の立ち上げの設定を行いました。
こちらの記事は、その際の振り返りとなります。
Terraformとは
Iac(infrastructure as code)ツールの一つでプラットフォームを提供することができます。
Ansible と比較されることが多いですが、Ansible
はミドルウェアやアプリケーションのデプロイを主な役割とし、Terraform
はネットワークやストレージ、仮想マシンなどのプラットフォームの構築を担う、という違いがあります。
また、.tf ファイルで設定を定義できることや実行環境が異なるといった違いもあります。
.tfファイル
EC2の立ち上げのみを行うため、以下の通りに設定しました。
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
provider "aws" {
region = "ap-northeast-1"
}
resource "aws_instance" "TechBull-server" {
ami = "ami-0a6fd4c92fc6ed7d5"
instance_type = "t2.micro"
tags = {
Name = "TechBull-server-Instance"
}
}
aws
AWS のプロバイダーを使用することを指定
source
Terraform が使用する AWS プロバイダーのソース
region
リソースを作成する AWS のリージョン (東京を使用しています。)
ami
使用する Amazon マシンイメージ(AMI)
instance_type
作成する EC2 インスタンスの種類
tags
インスタンスに付与するタグ (インスタンスの管理に使用する。)
Name
EC2インスタンスの名前
IAMポリシーの設定とTerraform実行
まず、EC2インスタンスにアタッチするIAMポリシーとして以下のように設定しました。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:RunInstances",
"ec2:CreateTags",
"ec2:DescribeInstances",
"ec2:DescribeInstanceTypes",
"ec2:DescribeTags",
"ec2:TerminateInstances"
],
"Resource": "*"
}
]
実際にTerraformを実行
- 初回実行
# terraform plan
# terraform apply
すると、以下のエラーが発生しました。
Error: reading EC2 Instance (i-0c0d633d0d34e41ac): getting attribute (instanceInitiatedShutdownBehavior): operation error EC2: DescribeInstanceAttribute, https response error StatusCode: 403, RequestID: ddd0459e-da69-41a7-81f8-305e7d13830c, api error UnauthorizedOperation: You are not authorized to perform this operation. User: arn:aws:iam::864899840494:user/naya is not authorized to perform: ec2:DescribeInstanceAttribute on resource: arn:aws:ec2:ap-northeast-1:864899840494:instance/i-0c0d633d0d34e41ac because no identity-based policy allows the ec2:DescribeInstanceAttribute action. Encoded authorization failure message: orBDnWQ2odGNJpRx1EMuS1DJlqUPrnCQLLIFohlJYTkAukYpoxRPyOIhtIeRYrpOor9zn0WDNi1N3qmIfio-1pHkZ_HmSGTTqZQdTdBQOZkHZbdTS8WBODRtFw3HGqRRdKd5SLMstBIlOKd-sRDhItp2LkjtvsPZ7Smk0JZwWBVhAMBJxjIRPsMJAjXBHE6g6oP3MXkR8qePH7_Ns-Umd0tCDv1pCb8VmOMLteWqGs2jyk27exFMP1l3TuoTNp6rarJk4dLghXpe8CttydFV7RBiB97Z32XpCkG2kjLfIBkXM1TosENX-6BxFPB1z7D509yVd97pD_8dD4nDfotf2Vsp_XiJN839wmq71s5xsrySu_6lTXw2TjTNgu3SYZzohfpt-U7m_2V_ufFSjsohQOFbaQtVN4JWKZLxJpRo78A6l7Uj-1ThG8NgiSDIYZlltLko2aMtbECu_keWnqsdurswAm3czvTt9ppNwPiJA_VZIaHUiKRHwKTi-zxyL_LI4zjYk_vPODhZOMHDrxyTRuSk2wyQdFooNa4H-5UmJg5v-f2Yd04llV4Dc0cVFS-n9T-c9kr3XUZFGAYbeDX7mr6LBxCLfXbxIEyqWZ5vSgekuWxa9ax4BSUQNZlJdmInIQnSMwpKG854nmEb7g_47Q2Jmaycmpfi0EZx-GcsKh7QYBCotUgFFNeFV7XlufmHylWXyh6bGRviC7mfZCUddBhTPhNae5OTcxUPzdLLU5903tQdVTJA4kEPU8p1tBHJB7uf6uY5FN75Ful6QknVldTmG9Us6bkAto9snMCpR0sC6IxsVEo9AZPEeNm1VsDnflOznVuJO6s2OlawtqXZanU4uMOhlAr1y1EAEIGm9Q
アクセス権限が足りなかったようなので、権限を追加してapply
- 2回目の実行
Error: reading EC2 Instance (i-0c0d633d0d34e41ac): reading block devices: operation error EC2: DescribeVolumes, https response error StatusCode: 403, RequestID: fd64cc6b-eb8b-4f67-87f1-543f4df21db0, api error UnauthorizedOperation: You are not authorized to perform this operation. User: arn:aws:iam::864899840494:user/naya is not authorized to perform: ec2:DescribeVolumes because no identity-based policy allows the ec2:DescribeVolumes action
別の権限エラーが出たので追加してapply
- 3回目の実行
Error: reading EC2 Instance (i-0c0d633d0d34e41ac) credit specification: operation error EC2: DescribeInstanceCreditSpecifications, https response error StatusCode: 403, RequestID: 5e40637d-1fda-4f73-acd8-468d2ca68984, api error UnauthorizedOperation: You are not authorized to perform this operation. User: arn:aws:iam::864899840494:user/naya is not authorized to perform: ec2:DescribeInstanceCreditSpecifications because no identity-based policy allows the ec2:DescribeInstanceCreditSpecifications action
また出ました。もう一度追加してapply
- 4回目の実行
Plan: 1 to add, 0 to change, 1 to destroy.
Do you want to perform these actions?
Terraform will perform the actions described above.
Only 'yes' will be accepted to approve.
Enter a value: yes
aws_instance.TechBull-server: Destroying... [id=i-0c0d633d0d34e41ac]
aws_instance.TechBull-server: Still destroying... [id=i-0c0d633d0d34e41ac, 10s elapsed]
aws_instance.TechBull-server: Still destroying... [id=i-0c0d633d0d34e41ac, 20s elapsed]
aws_instance.TechBull-server: Still destroying... [id=i-0c0d633d0d34e41ac, 30s elapsed]
aws_instance.TechBull-server: Destruction complete after 30s
aws_instance.TechBull-server: Creating...
aws_instance.TechBull-server: Still creating... [10s elapsed]
aws_instance.TechBull-server: Creation complete after 13s [id=i-02d841658cbacee8b]
Apply complete! Resources: 1 added, 0 changed, 1 destroyed.
するとようやっと完了しました。
- 修正後の最終的なIAMポリシーの設定
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:RunInstances",
"ec2:CreateTags",
"ec2:DescribeInstances",
"ec2:DescribeInstanceTypes",
"ec2:DescribeTags",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeVolumes",
"ec2:DescribeInstanceCreditSpecifications",
"ec2:TerminateInstances"
],
"Resource": "*"
}
]
}
- コンソール画面
ec2:DescribeInstanceAttribute
、ec2:DescribeInstanceCreditSpecifications
、ec2:DescribeVolumes
の 3 つの権限について調査したのですが、明確に「必須である理由」を特定するのが難しかったため、
ChatGPT様
に確認したところ、以下の理由で Terraform による EC2 インスタンスの作成時に必要になる可能性があることが分かりました。
以下、コピペ
権限が必要になる理由
ec2:DescribeInstanceAttribute
Terraform は EC2 インスタンスの 詳細属性(例: disable_api_termination) を確認するために DescribeInstanceAttribute を実行します。
たとえ disable_api_termination を .tf ファイルで明示的に設定していなくても、Terraform は デフォルト値を AWS に問い合わせる ため、この権限が必要になる場合があります。
ec2:DescribeInstanceCreditSpecifications
T2/T3 インスタンス (t2.micro など) は CPU クレジットの仕様 (standard / unlimited) を持っており、Terraform はその設定を確認するために DescribeInstanceCreditSpecifications を実行します。
したがって、T2/T3 系のインスタンスを使用する場合は必須ですが、それ以外のインスタンス(例: m5.large)を使用する場合は不要 です。
ec2:DescribeVolumes
Terraform は EC2 インスタンスにアタッチされた EBS ボリュームの情報(サイズ、タイプなど)を AWS から取得 しようとするため DescribeVolumes を実行します。
.tf ファイルで root_block_device を 明示的に指定していなくても、AMI に紐づいたデフォルトの EBS ボリュームの情報を取得するために、この権限が必要になることがあります。
ここら辺の権限についてご存じの方がいれば教えていただけるとありがたいです。
まとめ
Terraform は非常に便利なツールですね。CloudFormation とは異なり、AWS 以外のクラウドプロバイダーにも対応しているため、マルチクラウド環境でも利用できる、というのは利点なのかなと思います。
また、IaC(Infrastructure as Code)の記述方法やディレクトリ構成のベストプラクティスを学ぶことができるため、AWS入門者が最初に学ぶツールとしても適していると感じました。