🌟

AWS学びなおし(+TF)_IAM

2025/02/27に公開

AWS IAM (Identity and Access Management) は、AWSリソースへのアクセスを安全に管理するためのサービスです。簡単に言うと、「誰が」「どのAWSリソースに対して」「何をできるか」 を細かくコントロールするための仕組みです。

IAMの主要な概念

  • IAMユーザー (IAM User): AWSと直接やり取りする個人またはアプリケーションを表します。ユーザーはパスワードやアクセスキーを持ち、認証情報を提示することでAWSにアクセスできます。

  • IAMグループ (IAM Group): IAMユーザーの集合です。グループにポリシーを適用することで、複数ユーザーに対してまとめて権限を付与・管理できます。部署やプロジェクトチームなど、共通の権限を持つユーザーをグループ化すると管理が楽になります。

  • IAMロール (IAM Role): 特定のAWSサービスやエンティティ (EC2インスタンス、Lambda関数など) に一時的な権限を付与するための仕組みです。ロールは特定のユーザーに紐づくのではなく、必要な時に必要な権限を付与する「役割」のようなものです。認証情報をハードコードせずに安全にAWSリソースへアクセスさせたい場合に利用します。

  • IAMポリシー (IAM Policy): AWSリソースへのアクセス権限を定義するドキュメントです。JSON形式で記述され、「許可 (Allow)」または「拒否 (Deny)」するアクション、対象リソース、条件などを指定します。

    • アイデンティティベースポリシー: IAMユーザー、グループ、ロールにアタッチし、それらのエンティティが実行できるアクションを定義します。
    • リソースベースポリシー: S3バケット、SQSキューなどのリソースにアタッチし、どのプリンシパル (ユーザー、ロール、アカウントなど) がそのリソースにアクセスできるかを定義します。
  • プリンシパル (Principal): AWSリソースへのアクセスを要求するエンティティです。IAMユーザー、IAMロール、AWSアカウントなどがプリンシパルになり得ます。ポリシーの中で、どのプリンシパルに権限を与えるかを指定します。

  • アクション (Action): AWSサービスが提供する操作 (例: EC2インスタンスの起動、S3バケットへのオブジェクトの書き込みなど) です。ポリシーの中で、許可または拒否するアクションを指定します。

  • リソース (Resource): 操作の対象となるAWSリソース (例: EC2インスタンス、S3バケット、DynamoDBテーブルなど) です。ポリシーの中で、アクションを許可または拒否する対象リソースを指定します。

  • 条件 (Condition): アクセスを許可または拒否する条件を追加できます。IPアドレス、時間帯、MFA認証の有無など、様々な条件を指定できます。

IAMの基本的な流れ

  1. 認証 (Authentication): プリンシパルが自分の身元を証明します (例: ユーザー名とパスワード、アクセスキーとシークレットアクセスキーの提示)。
  2. 認可 (Authorization): IAMは、プリンシパルが要求したアクションを、指定されたリソースに対して実行する権限があるかどうかをポリシーに基づいて判断します。
  3. アクセス許可 (Access Granted) または アクセス拒否 (Access Denied): 認可の結果に基づき、アクセスが許可または拒否されます。

IAMの重要性

IAMはAWS環境のセキュリティにおける最重要な要素の一つです。IAMの設定を誤ると、意図しないユーザーやサービスがAWSリソースにアクセスできるようになり、情報漏洩やシステム破壊などの重大なセキュリティ事故につながる可能性があります。

IAMを適切に設定することで、最小権限の原則 (必要な権限だけを必要な人に付与する) を実現し、セキュリティリスクを大幅に低減できます。

【実務レベルの内容と重要事項】

実務レベルでIAMを扱う上で重要な事項は多岐に渡りますが、特に以下の点が重要です。

1. 最小権限の原則の徹底:

  • 必要最小限の権限: ユーザー、グループ、ロールには、業務に必要な最小限の権限のみを付与するように徹底します。過剰な権限はセキュリティリスクを高めます。
  • 具体的なリソース指定: ポリシーでリソースを指定する際は、* (ワイルドカード) を安易に使用せず、可能な限り具体的なARN (Amazon Resource Name) を指定します。
  • アクションの絞り込み: 許可するアクションも、必要最小限に絞り込みます。"Action": ["s3:*"] のように全てのアクションを許可するのではなく、 "Action": ["s3:GetObject", "s3:PutObject"] のように必要なアクションのみを許可します。
  • 定期的な権限の見直し: 定期的にIAMの設定を見直し、不要になった権限は削除、または必要に応じて権限を絞り込みます。

2. IAMロールの積極的な活用:

  • EC2インスタンス、Lambda関数などへの権限付与: EC2インスタンスやLambda関数などのAWSサービスから他のAWSリソースにアクセスする場合は、IAMロールを使用するのが必須と言えます。アクセスキーをハードコードするのは絶対に避けるべきです。
  • クロスアカウントアクセス: 異なるAWSアカウント間でリソースを共有する場合も、IAMロールを利用することで安全に委任アクセスを実現できます。

3. IAMポリシーの適切な設計と管理:

  • 管理しやすいポリシー設計: ポリシーは機能や役割ごとに分割し、再利用性を高めるように設計します。
  • ポリシーのバージョン管理: IAMポリシーは変更履歴を管理し、必要に応じてロールバックできるようにします。
  • ポリシーのテスト: IAMポリシーを作成・変更したら、実際に意図した通りに動作するかテストを行います。AWS Policy Simulator などのツールを活用できます。
  • 命名規則: IAMユーザー、グループ、ロール、ポリシーには一貫性のある命名規則を適用し、管理性を向上させます。

4. セキュリティベストプラクティスの適用:

  • 多要素認証 (MFA) の有効化: IAMユーザーにはMFAを必須で有効化します。特に管理者権限を持つユーザーは必ず有効化してください。
  • パスワードポリシーの強化: 強力なパスワードポリシー (複雑さ、有効期限など) を設定し、定期的なパスワード変更を促します。
  • アクセスキーのローテーション: IAMユーザーのアクセスキーは定期的にローテーションし、漏洩時のリスクを低減します。
  • 不要なアクセスキーの削除: 使用していないアクセスキーは削除します。
  • IAM Access Analyzer の活用: IAM Access Analyzer を利用して、意図しない外部からのアクセスを許可しているポリシーを特定し、修正します。
  • CloudTrail による監査ログの記録: CloudTrail を有効化し、IAM関連の操作ログを含む全てのアクションを記録・監視します。

5. グループとロールの使い分け:

  • グループ: 複数ユーザーに共通の権限を付与する場合に利用します。ユーザーの属性 (部署、役職など) に基づいてグループを作成し、ポリシーを適用します。
  • ロール: 特定のAWSサービスやエンティティに一時的な権限を付与する場合、またはクロスアカウントアクセスを実現する場合に利用します。

6. 委任 (Delegation) とクロスアカウントアクセス:

  • 委任: IAMロールを利用して、あるAWSアカウント (信頼されたアカウント) のIAMユーザーやサービスが、別のアカウント (信頼するアカウント) のリソースにアクセスできるようにする仕組みです。
  • クロスアカウントアクセス: 複数のAWSアカウントを運用している場合に、アカウント間で安全にリソースを共有・アクセスするために不可欠な機能です。

7. サービスコントロールポリシー (SCP):

  • AWS Organizations 環境での利用: AWS Organizations を利用している場合、SCP を使用することで、組織全体またはOU (Organizational Unit) レベルでIAMポリシーを適用し、AWSアカウントの利用をガバナンスできます。
  • ガードレールとしての役割: SCP は、アカウント内でIAMユーザーやロールが設定できる権限の上限を制限するガードレールとして機能します。

【実務でどの程度使用されるのか】

IAMは、AWSを利用する上で間違いなく最も頻繁に使用するサービスの一つです。AWS環境の規模や利用方法に関わらず、IAMは必須のサービスであり、利用頻度は非常に高いです。

実務でのIAM利用例:

  • 新規プロジェクト立ち上げ時: プロジェクトに必要なIAMユーザー、グループ、ロール、ポリシーを設計・作成します。
  • アプリケーションデプロイ時: EC2インスタンスやLambda関数にIAMロールをアタッチし、必要なAWSリソースへのアクセス権限を付与します。
  • 権限変更時: ユーザーの役割変更やプロジェクト構成変更に伴い、IAMポリシーを修正したり、IAMグループのメンバーを変更したりします。
  • セキュリティ監査時: IAMの設定状況を定期的に監査し、不要な権限がないか、セキュリティベストプラクティスが適用されているかなどを確認します。
  • トラブルシューティング時: AWSリソースへのアクセスエラーが発生した場合、IAMポリシーの設定に問題がないか確認します。

IAMはDevSecOpsにおける重要な要素:

近年、DevSecOps (Development, Security, and Operations) の考え方が重要視されていますが、IAMはDevSecOpsにおいても中心的な役割を果たします。IaC (Infrastructure as Code) を活用したIAMの自動化、CI/CDパイプラインへのIAMポリシーの組み込み、セキュリティテストの自動化など、開発ライフサイクル全体を通してIAMを意識した運用が求められます。

IAMのスキルは市場価値が高い:

クラウドエンジニア、インフラエンジニア、セキュリティエンジニアなど、AWSに関わる職種においては、IAMの知識・スキルは必須であり、市場価値も非常に高いです。IAMを深く理解し、適切に設計・運用できる人材は、企業にとって非常に貴重な存在です。

【terraformのコードで記述する場合の基本的内容と実務レベルの内容】

Terraformは、IaC (Infrastructure as Code) を実現するためのツールであり、IAMリソースもコードとして定義・管理できます。TerraformでIAMを管理することで、設定のバージョン管理、再現性、自動化などが容易になります。

TerraformでのIAM記述の基本:

TerraformでIAMリソースを記述する場合、主に以下のリソースタイプを使用します。

  • aws_iam_user: IAMユーザーを作成します。
resource "aws_iam_user" "example" {
  name = "example-user"
}
  • aws_iam_group: IAMグループを作成します。
resource "aws_iam_group" "example" {
  name = "example-group"
}
  • aws_iam_role: IAMロールを作成します。
resource "aws_iam_role" "example" {
  name = "example-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "ec2.amazonaws.com"
        }
      },
    ]
  })
}
  • aws_iam_policy: IAMポリシーを作成します。ポリシーの内容はJSON形式で記述します。
resource "aws_iam_policy" "example" {
  name        = "example-policy"
  description = "Example policy"
  policy      = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action   = [ "s3:GetObject", "s3:PutObject" ]
        Effect   = "Allow"
        Resource = [ "arn:aws:s3:::example-bucket/*" ]
      },
    ]
  })
}
  • aws_iam_policy_attachment: IAMポリシーをユーザー、グループ、ロールにアタッチします。
resource "aws_iam_policy_attachment" "user_policy_attachment" {
  name       = "user-policy-attachment"
  users      = [aws_iam_user.example.name]
  policy_arn = aws_iam_policy.example.arn
}

resource "aws_iam_policy_attachment" "group_policy_attachment" {
  name       = "group-policy-attachment"
  groups     = [aws_iam_group.example.name]
  policy_arn = aws_iam_policy.example.arn
}

resource "aws_iam_policy_attachment" "role_policy_attachment" {
  name       = "role-policy-attachment"
  roles      = [aws_iam_role.example.name]
  policy_arn = aws_iam_policy.example.arn
}

TerraformでのIAM記述の実務レベルの内容:

実務レベルでTerraformを用いてIAMを管理する場合、以下の点を考慮する必要があります。

  1. 変数 (Variables) の活用:
  • 環境 (開発環境、本番環境など) やプロジェクトによって異なる値を変数として定義し、コードの再利用性を高めます。
  • IAMユーザー名、グループ名、ロール名、ポリシー名、ARNなどを変数化します。
variable "environment" {
  type    = string
  default = "dev"
}

resource "aws_iam_user" "example" {
  name = "example-user-${var.environment}"
}
  1. モジュール (Modules) の活用:
  • IAMユーザー、グループ、ロール、ポリシーなどを機能や役割ごとにモジュール化し、コードの構造化と再利用性を高めます。
  • 例えば、S3アクセス用のIAMモジュール、EC2アクセス用のIAMモジュールなどを作成します。
module "s3_access_iam" {
  source = "./modules/iam/s3_access"
  bucket_name = "example-bucket"
}
  1. データソース (Data Sources) の活用:
  • 既存のAWSリソースの情報 (例: AWSアカウントID、VPC ID、サブネットIDなど) をデータソースから取得し、コード内で動的に利用します。
  • IAMポリシーの中で、アカウントIDやリージョンなどを参照する場合に便利です。
data "aws_caller_identity" "current" {}

resource "aws_iam_policy" "example" {
  name        = "example-policy"
  description = "Example policy"
  policy      = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action   = [ "s3:GetObject", "s3:PutObject" ]
        Effect   = "Allow"
        Resource = [ "arn:aws:s3:::example-bucket/*" ]
        Condition = {
          StringEquals = {
            "aws:PrincipalAccount" = data.aws_caller_identity.current.account_id
          }
        }
      },
    ]
  })
}
  1. ループ処理 (for_each, count) の活用:
  • 複数のIAMユーザー、グループ、ロールなどをまとめて作成する場合に、ループ処理を利用することでコード量を削減できます。
locals {
  users = ["user1", "user2", "user3"]
}

resource "aws_iam_user" "example" {
  for_each = toset(local.users)
  name     = each.value
}
  1. IAMポリシーの外部ファイル化:
  • 複雑なIAMポリシーは、Terraformコード内に直接記述するのではなく、JSONファイルとして外部ファイル化し、file() 関数で読み込むことで、コードの見通しを良くすることができます。
resource "aws_iam_policy" "example" {
  name        = "example-policy"
  description = "Example policy"
  policy      = file("policies/example-policy.json")
}
  1. IAMポリシーのJSON記述の工夫:
  • jsonencode() 関数を活用して、Terraformの変数やデータソースをJSONポリシー内で展開します。
  • 条件 (Condition) ブロックを効果的に活用し、よりセキュアなIAMポリシーを記述します。
  • IAM Policy Simulator などのツールでポリシーを検証してからTerraformコードに反映します。
  1. 冪等性 (Idempotency) の考慮:
  • Terraformは冪等性を持つツールですが、IAMリソースの作成・変更処理も冪等性を意識して記述します。
  • 同じTerraformコードを複数回実行しても、意図しない変更が発生しないように注意します。
  1. ドリフト (Drift) 検知と対応:
  • Terraformの状態管理 (State Management) を適切に行い、実際のAWS環境とTerraformの状態定義との差異 (ドリフト) を検知し、必要に応じて修正します。
  • terraform plan コマンドでドリフトを確認し、 terraform apply コマンドで修正します。
  1. Terraform Cloud/Enterprise の活用:
  • チームでのTerraform運用を行う場合、Terraform Cloud や Terraform Enterprise を活用することで、状態管理、コラボレーション、ガバナンスなどを強化できます。
  • 特に大規模なAWS環境をTerraformで管理する場合は、Terraform Cloud/Enterprise の導入を検討すべきです。

TerraformでIAMを管理することで、AWS環境全体のセキュリティと運用効率を大きく向上させることができます。上記の基本と実務レベルの内容を理解し、Terraformを効果的に活用してください。

Discussion