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.
serviceslist(string)AWS services that users can access.
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