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

4.3 KiB

Assignment

The Nautilus DevOps team is automating IAM policy creation using Terraform to enhance security and access management. As part of this task, they need to create an IAM policy with specific requirements.

For this task, create an AWS IAM policy using Terraform with the following requirements:

The IAM policy name iampolicy_javed should be stored in a variable named KKE_iampolicy. Note:

The configuration values should be stored in a variables.tf file.

The Terraform script should be structured with a main.tf file referencing variables.tf.

The Terraform working directory is /home/bob/terraform.

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

Solution

IAM Policy with Variables — iampolicy_javed (KKE_iampolicy)

Two-file structure: variables.tf holds the config, main.tf references it. The IAM policy name must be stored in a variable named exactly KKE_iampolicy.

variables.tf

variable "KKE_iampolicy" {
  description = "Name of the IAM policy"
  type        = string
  default     = "iampolicy_javed"
}

main.tf

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

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

resource "aws_iam_policy" "javed" {
  name        = var.KKE_iampolicy
  description = "IAM policy managed by Terraform"

  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect   = "Allow"
        Action   = ["ec2:Describe*"]
        Resource = "*"
      }
    ]
  })
}

How to run

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

How it works

Splitting config from logic

Terraform merges every .tf file in the directory into one configuration, so variables.tf and main.tf act as a single unit — no imports. variables.tf declares inputs; main.tf declares resources that consume them via var.<name>.

The variable

  • variable "KKE_iampolicy" — holds the IAM policy name, exactly as required. The default of iampolicy_javed lets terraform apply run without prompting.
  • type = string validates the input type at plan time.

The IAM policy

  • name = var.KKE_iampolicy — resolves to iampolicy_javed via the var. prefix. This creates a customer-managed policy — a standalone, reusable permission document with its own ARN.

  • policy is mandatory. An IAM policy is defined by its JSON document, so the policy argument is required. The task doesn't specify what the policy should grant, so a minimal, safe statement is used: ec2:Describe* (read-only) on all resources. Read-only actions stay within the login user's permission scope, which avoids the anti-privilege-escalation restrictions these sandboxes enforce — granting actions broader than your own would fail with AccessDenied.

  • jsonencode({...}) builds the policy JSON from an HCL object — readable and correctly escaped, and validated by Terraform at plan time.

  • Version = "2012-10-17" is the current IAM policy language version — always this literal date, not today's date.

  • Resource = "*"ec2:Describe* actions are account-wide list/read operations that don't support resource-level scoping, so * is the correct value.

  • Policy created, not attached. The task only asks for the policy to exist, so it isn't attached to any user, group, or role. Attachment is a separate resource (aws_iam_user_policy_attachment etc.) added when needed.

Sandbox note

Creating a customer-managed policy uses iam:CreatePolicy, which is restricted in some lab environments. Because this task explicitly requires a named custom policy, the lab provisions that permission for this scenario, so the create succeeds. Keeping the document read-only further ensures it stays within the allowed scope.

Verify

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

echo "[$POLICY_ARN]"

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

Expected — a local policy ARN for iampolicy_javed, and its document showing the ec2:Describe* allow statement.