Files
kodekloud-engineer/terraform/task-16.md

4.6 KiB

Assignment

When establishing infrastructure on the AWS cloud, Identity and Access Management (IAM) is among the first and most critical services to configure. IAM facilitates the creation and management of user accounts, groups, roles, policies, and other access controls. The Nautilus DevOps team is currently in the process of configuring these resources and has outlined the following requirements.

Create an IAM policy named iampolicy_siva in us-east-1 region using Terraform. It must allow read-only access to the EC2 console, i.e., this policy must allow users to view all instances, AMIs, and snapshots in the Amazon EC2 console.

The Terraform working directory is /home/bob/terraform. Create the main.tf file (do not create a different .tf file) to accomplish this task.

Note: Right-click under the EXPLORER section in VS Code and select Open in Integrated Terminal to launch the terminal.

Solution

IAM Policy — iampolicy_siva (read-only EC2 console)

Terraform solution to create a customer-managed IAM policy that grants read-only access to view instances, AMIs, and snapshots in the EC2 console.

main.tf

terraform {
  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

provider "aws" {
  region = "us-east-1"
}

resource "aws_iam_policy" "siva" {
  name        = "iampolicy_siva"
  description = "Read-only access to view instances, AMIs, and snapshots in the EC2 console"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Sid    = "EC2ReadOnlyConsole"
        Effect = "Allow"
        Action = [
          "ec2:DescribeInstances",
          "ec2:DescribeImages",
          "ec2:DescribeTags",
          "ec2:DescribeSnapshots"
        ]
        Resource = "*"
      }
    ]
  })
}

How to run

cd /home/bob/terraform
terraform init
terraform apply -auto-approve

How it works

aws_iam_policy

This creates a customer-managed policy — a standalone, reusable permission document that can later be attached to users, groups, or roles. The task requires a specific name (iampolicy_siva), so a managed AWS policy like AmazonEC2ReadOnlyAccess can't be substituted; the policy has to be created explicitly with that exact name.

  • name — the policy's identifier, iampolicy_siva, matching the required iampolicy_ naming convention these environments enforce.
  • description — free-text summary; optional but good hygiene.
  • policy — the JSON policy document, built with jsonencode() so it stays readable HCL instead of a raw heredoc string (and Terraform validates the structure at plan time).

The policy document

This is AWS's canonical "read-only access to the EC2 console" statement. Each action is a Describe* call — none of them mutate anything, which is what makes the policy strictly read-only:

Action What it lets the user view
ec2:DescribeInstances All EC2 instances
ec2:DescribeImages All AMIs
ec2:DescribeSnapshots All EBS snapshots
ec2:DescribeTags Tags on those resources (so the console renders names/labels correctly)

DescribeTags is included because the EC2 console leans on tag data to display resource names and metadata — without it the console view is functional but degraded. This four-action set is exactly what the AWS documentation prescribes for this scenario.

  • Effect = "Allow" grants the listed actions.
  • Resource = "*" — EC2 Describe* actions don't support resource-level permissions (they're list/read operations that span the account), so * is the correct and only valid scope here.
  • Version = "2012-10-17" is the current IAM policy language version — always use this literal date, not today's date.

Sandbox / IAM note

Creating a customer-managed policy uses iam:CreatePolicy, which is often restricted in locked-down lab environments. Because this task explicitly requires a named custom policy, the lab provisions the permission for this specific scenario, so the create succeeds. The policy is created but not attached to any principal — the task only asks for the policy to exist. Attachment to a user/group/role is a separate step you'd add when required.

Verify

POLICY_ARN=$(aws iam list-policies --scope Local \
  --query "Policies[?PolicyName=='iampolicy_siva'].Arn | [0]" --output text)

echo "[$POLICY_ARN]"

aws iam get-policy-version \
  --policy-arn "$POLICY_ARN" \
  --version-id v1 \
  --query 'PolicyVersion.Document'

Expected — the policy document echoing the four ec2:Describe* actions with Effect: Allow and Resource: *.