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. Thedefaultofiampolicy_javedletsterraform applyrun without prompting.type = stringvalidates the input type at plan time.
The IAM policy
-
name = var.KKE_iampolicy— resolves toiampolicy_javedvia thevar.prefix. This creates a customer-managed policy — a standalone, reusable permission document with its own ARN. -
policyis mandatory. An IAM policy is defined by its JSON document, so thepolicyargument 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 withAccessDenied. -
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_attachmentetc.) 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.