🔐

EC2にS3操作権限を持つIAMロールを割り当てる。それ、terraformでやる

に公開

背景

EC2インスタンスから他のAWSサービス(S3など)にアクセスする必要がある場合、認証方法として以下の2つの選択肢があります。

アクセスキー方式(非推奨)

私はEC2にロールを割り当てることができるというのを知らずに、この方法を採用していました。。。今思うと、よくこんな面倒なことをやっていたなと思います。

  • アクセスキーとシークレットアクセスキーをEC2に設定
  • デメリット:
    • キーがEC2上のファイルに保存されるためセキュリティリスクが高い
    • キーのローテーション管理が必要
    • キーが流出すると不正アクセスのリスクがある

IAMロール方式(推奨)

  • EC2インスタンスにIAMロールを割り当て
  • メリット:
    • 一時的な認証情報が自動的に発行・更新される
    • アクセスキーをEC2上に保存する必要がない
    • 権限管理がシンプルで安全

本記事では、IAMロール方式でEC2にS3操作権限を付与する方法をTerraformで実装します。

IAMロールとインスタンスプロファイルの関係

EC2にIAMロールを割り当てるには、以下の3つのリソースが必要です:

リソース 役割
IAMロール 権限の定義と信頼ポリシーを持つエンティティ
IAMポリシー 具体的な操作権限(S3への読み書きなど)を定義
インスタンスプロファイル EC2インスタンスとIAMロールを紐付けるコンテナ

Terraformでの実装

ステップ1: IAMロールの作成

まず、EC2インスタンスが引き受ける(AssumeRole)ことができるIAMロールを作成します。

resource "aws_iam_role" "ec2_s3_role" {
  name = "ec2-s3-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"
        }
        Action    = "sts:AssumeRole"
      }
    ]
  })
}
  • assume_role_policy: このロールを誰が引き受けられるかを定義(信頼ポリシー)
  • Principal.Service = "ec2.amazonaws.com": EC2サービスがこのロールを使用できることを許可
  • Action = "sts:AssumeRole": ロールの引き受けを許可

ステップ2: S3操作ポリシーの定義

S3に対する操作権限を定義したIAMポリシーを作成します。

resource "aws_iam_policy" "s3_policy" {
  name        = "EC2S3Policy"
  description = "Policy for EC2 instance to operate only on S3"
  policy = jsonencode({
    Version = "2012-10-17",
    Statement = [
      {
        Effect   = "Allow",
        Action   = [
          "s3:*"
        ],
        Resource = "*"
      }
    ]
  })
}
  • Action = "s3:*": S3に対するすべての操作を許可
  • Resource = "*": すべてのS3バケットに対して許可

ステップ3: ロールにポリシーをアタッチ

作成したIAMポリシーをIAMロールに関連付けます。

resource "aws_iam_role_policy_attachment" "attach_s3_policy" {
  role       = aws_iam_role.ec2_s3_role.name
  policy_arn = aws_iam_policy.s3_policy.arn
}

ポイント:

  • role: アタッチ先のロール名
  • policy_arn: アタッチするポリシーのARN

ステップ4: インスタンスプロファイルの作成

EC2インスタンスとIAMロールを紐付けるインスタンスプロファイルを作成します。

resource "aws_iam_instance_profile" "ec2_s3_instance_profile" {
  name = "ec2-s3-instance-profile"
  role = aws_iam_role.ec2_s3_role.name
}

ステップ5: EC2インスタンスにプロファイルを割り当て

EC2インスタンスのリソース定義で、インスタンスプロファイルを指定します。

resource "aws_instance" "this" {
  ami                     = "ami-0a6fd4c92fc6ed7d5"
  instance_type           = "t3.nano"
  disable_api_termination = false
  monitoring              = true

  # ... 省略 ...

  iam_instance_profile = aws_iam_instance_profile.ec2_s3_instance_profile.name
}

ポイント:

  • iam_instance_profile: 作成したインスタンスプロファイルの名前を指定

EC2インスタンスでの確認

確認方法

EC2インスタンスにSSHログインし、以下のコマンドで認証情報の取得元を確認します:

aws configure list

ロール割り当て前の状態

IAMロールを割り当てる前は、access_keysecret_key<not set>になっています。

aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key                <not set>             None    None
secret_key                <not set>             None    None
    region           ap-northeast-1             imds

ロール割り当て後の状態

IAMロールを割り当てると、Typeiam-roleになり、一時的な認証情報が自動的に設定されます。

aws configure list
      Name                    Value             Type    Location
      ----                    -----             ----    --------
   profile                <not set>             None    None
access_key     CN5X         iam-role
secret_key     KCNh         iam-role
    region           ap-northeast-1             imds
  • Type列がiam-roleになっている → IAMロールから認証情報を取得していることを示す
  • access_keysecret_keyが表示されている → 一時的な認証情報が自動発行されている
  • これらの認証情報は定期的に自動更新される

動作確認

S3へのアクセスが可能か確認します:

# S3バケット一覧の取得
aws s3 ls

# 特定バケットへのファイルコピー
aws s3 cp test.txt s3://my-bucket/

まとめ

項目 内容
目的 EC2インスタンスにS3操作権限を安全に付与
推奨方法 IAMロール方式(アクセスキー方式は非推奨)
必要なリソース IAMロール + IAMポリシー + インスタンスプロファイル
セキュリティ 一時認証情報の自動更新、キー流出リスクなし

実装のポイント

  1. IAMロール: EC2サービスが引き受け可能なロールを作成
  2. IAMポリシー: S3操作権限を定義(本番環境では特定バケットに制限推奨)
  3. ポリシーアタッチ: ロールとポリシーを関連付け
  4. インスタンスプロファイル: EC2とIAMロールを紐付ける中間リソース
  5. EC2に割り当て: iam_instance_profileパラメータで指定

IAMロールを使用することで、アクセスキーを管理する手間がなくなり、セキュアなAWS環境を構築できます。

GitHubで編集を提案

Discussion