Skip to content

AWS Account

The aws_account resource provisions sandboxed AWS accounts for lab environments. It creates controlled AWS accounts with user management, service restrictions, and regional limitations suitable for educational and training purposes.

As a lab author, you can use aws_account resources to:

  • AWS Training Labs: Create realistic AWS environments for hands-on cloud training and certification preparation
  • Service-Specific Learning: Restrict access to specific AWS services for focused learning experiences

AWS account resources provide realistic cloud environments while maintaining educational control and cost management.

resource "aws_account" "name" {
regions = ["us-east-1"]
services = ["ec2", "s3"]
user "student" {
managed_policies = [
"arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"
]
}
}
resource "aws_account" "name" {
regions = ["us-east-1", "us-west-2"]
services = ["ec2", "s3", "iam", "cloudformation"]
tags = {
Environment = "Training"
Purpose = "Lab"
Team = "Education"
}
user "admin" {
iam_policy = file("./policies/admin-policy.json")
managed_policies = [
"arn:aws:iam::aws:policy/PowerUserAccess",
"arn:aws:iam::aws:policy/IAMReadOnlyAccess"
]
}
user "developer" {
iam_policy = file("./policies/dev-policy.json")
managed_policies = [
"arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess"
]
}
scp_policy = file("./policies/lab-restrictions.json")
}
FieldRequiredTypeDescription
regionslist(string)AWS regions where resources can be provisioned. Defaults to empty list.
serviceslist(string)AWS services that users can access. Defaults to empty list.
tagsmap(string)Tags to apply to the AWS account. Defaults to empty map.
scp_policystringService Control Policy JSON to apply to the account

aws_account → user

User blocks define IAM users to create within the AWS account:

FieldRequiredTypeDescription
namelabelUsername for the IAM user (specified as block label)
iam_policystringCustom IAM policy JSON for the user
managed_policieslist(string)AWS managed policy ARNs to attach to the user. Defaults to empty list.

These attributes are set by the system after account provisioning:

Field Type Description
account_id string The AWS account ID
account_name string The AWS account name

For each user block, these attributes are computed:

Field Type Description
username string The IAM username
password string Console password for the user
access_key_id string AWS access key ID for programmatic access
secret_access_key string AWS secret access key for programmatic access
  • Region names must be valid AWS regions (e.g., “us-east-1”, “eu-west-1”)
  • Service names must be valid AWS service identifiers (e.g., “ec2”, “s3”, “lambda”)
  • IAM policies must be valid JSON format
  • Managed policy ARNs must be valid AWS managed policy ARNs
  • SCP policies must be valid Service Control Policy JSON format
  • User names must follow AWS IAM username requirements
resource "aws_account" "training" {
regions = ["us-east-1"]
services = ["ec2", "s3", "iam"]
tags = {
Environment = "Training"
Course = "AWS Fundamentals"
}
user "student" {
managed_policies = [
"arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess",
"arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess"
]
}
}
output "student_credentials" {
value = {
username = resource.aws_account.training.user.student.username # e.g., "student"
password = resource.aws_account.training.user.student.password # e.g., "TempPass123!"
access_key = resource.aws_account.training.user.student.access_key_id # e.g., "AKIAIOSFODNN7EXAMPLE"
}
sensitive = true
}
resource "aws_account" "workshop" {
regions = ["us-east-1", "us-west-2"]
services = [
"ec2",
"s3",
"iam",
"cloudformation",
"lambda"
]
tags = {
Environment = "Workshop"
Event = "AWS Solutions Architect Training"
Instructor = "Jane Doe"
}
# Instructor with administrative access
user "instructor" {
iam_policy = file("./policies/instructor-policy.json")
managed_policies = [
"arn:aws:iam::aws:policy/PowerUserAccess",
"arn:aws:iam::aws:policy/IAMFullAccess"
]
}
# Student with controlled permissions
user "student" {
managed_policies = [
"arn:aws:iam::aws:policy/AmazonEC2FullAccess",
"arn:aws:iam::aws:policy/AmazonS3FullAccess"
]
}
# Observer with read-only access
user "observer" {
managed_policies = [
"arn:aws:iam::aws:policy/ReadOnlyAccess"
]
}
scp_policy = file("./policies/workshop-restrictions.json")
}
resource "aws_account" "serverless_lab" {
regions = ["us-east-1"]
services = [
"lambda",
"apigateway",
"dynamodb",
"s3",
"cloudwatch",
"iam"
]
tags = {
Environment = "Serverless-Lab"
Technology = "AWS Lambda"
Level = "Intermediate"
}
user "developer" {
iam_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"lambda:*",
"apigateway:*",
"dynamodb:*",
"s3:*",
"logs:*"
]
Resource = "*"
}
]
})
}
}
resource "container" "aws_cli" {
image {
name = "amazon/aws-cli:latest"
}
environment = {
AWS_ACCESS_KEY_ID = resource.aws_account.serverless_lab.user.developer.access_key_id # e.g., "AKIAIOSFODNN7EXAMPLE"
AWS_SECRET_ACCESS_KEY = resource.aws_account.serverless_lab.user.developer.secret_access_key # e.g., "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
AWS_DEFAULT_REGION = "us-east-1"
}
}
resource "aws_account" "lab" {
regions = ["us-east-1"]
services = ["ec2", "s3"]
user "student" {
managed_policies = [
"arn:aws:iam::aws:policy/AmazonEC2FullAccess"
]
}
}
resource "template" "aws_credentials" {
source = <<-EOF
[default]
aws_access_key_id = ${resource.aws_account.lab.user.student.access_key_id} # e.g., "AKIAIOSFODNN7EXAMPLE"
aws_secret_access_key = ${resource.aws_account.lab.user.student.secret_access_key} # e.g., "wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY"
region = us-east-1
# Account Information
# Account ID: ${resource.aws_account.lab.account_id} # e.g., "123456789012"
# Account Name: ${resource.aws_account.lab.account_name} # e.g., "instruqt-lab-account"
EOF
destination = "./aws-credentials"
}
resource "template" "lab_instructions" {
source = <<-EOF
# AWS Lab Environment
## Account Details
- Account ID: ${resource.aws_account.lab.account_id} # e.g., "123456789012"
- Account Name: ${resource.aws_account.lab.account_name} # e.g., "instruqt-lab-account"
## User Credentials
- Username: ${resource.aws_account.lab.user.student.username} # e.g., "student"
- Password: ${resource.aws_account.lab.user.student.password} # e.g., "TempPass123!"
## Programmatic Access
- Access Key ID: ${resource.aws_account.lab.user.student.access_key_id}
- Secret Access Key: ${resource.aws_account.lab.user.student.secret_access_key}
EOF
destination = "./lab-info.md"
}
resource "aws_account" "global_training" {
regions = [
"us-east-1", # N. Virginia
"us-west-2", # Oregon
"eu-west-1", # Ireland
"ap-southeast-1" # Singapore
]
services = [
"ec2",
"s3",
"cloudfront",
"route53",
"iam"
]
tags = {
Environment = "Multi-Region-Training"
Topic = "Global Infrastructure"
Duration = "4-hours"
}
user "architect" {
iam_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ec2:*",
"s3:*",
"cloudfront:*",
"route53:*"
]
Resource = "*"
Condition = {
StringEquals = {
"aws:RequestedRegion" = [
"us-east-1",
"us-west-2",
"eu-west-1",
"ap-southeast-1"
]
}
}
}
]
})
}
}
resource "aws_account" "security_lab" {
regions = ["us-east-1"]
services = ["ec2", "s3", "iam"]
tags = {
Environment = "Security-Training"
Focus = "IAM-and-Policies"
}
user "security_student" {
iam_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"ec2:DescribeInstances",
"ec2:RunInstances",
"ec2:TerminateInstances"
]
Resource = "*"
Condition = {
StringEquals = {
"ec2:InstanceType" = ["t2.micro", "t3.micro"]
}
}
}
]
})
}
# Restrictive SCP to prevent privilege escalation
scp_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Deny"
Action = [
"iam:CreateRole",
"iam:DeleteRole",
"iam:AttachRolePolicy",
"iam:DetachRolePolicy",
"organizations:*",
"account:*"
]
Resource = "*"
},
{
Effect = "Deny"
Action = "ec2:RunInstances"
Resource = "arn:aws:ec2:*:*:instance/*"
Condition = {
ForAllValues:StringNotEquals = {
"ec2:InstanceType" = [
"t2.micro",
"t2.small",
"t3.micro",
"t3.small"
]
}
}
}
]
})
}
  1. Principle of Least Privilege: Grant only the minimum permissions required for the lab objectives
  2. Service Restrictions: Limit services to those essential for the learning experience
  3. Regional Constraints: Restrict regions to control costs and simplify the environment
  4. Policy Management: Use external JSON files for complex IAM policies and SCPs
  5. User Separation: Create distinct users for different roles (student, instructor, observer)
  6. Cost Controls: Implement SCPs to prevent expensive resource creation
  7. Tagging Strategy: Use consistent tags for cost tracking and resource management
  8. Credential Security: Mark credential outputs as sensitive and manage access carefully