Skip to content

You are viewing documentation for Instruqt 2.0 Labs. For Tracks documentation, please visit docs.instruqt.com.

AWS Account


Defined insandbox.hcl

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")
}

Fields

FieldTypeRequiredDescription
serviceslist(string)✓AWS services users can access, as AWS service namespaces - the prefix used in IAM policy actions (e.g. ec2, s3, lambda). At least one service is required.
Constraintsat least one service must be specified
regionslist(string)✓AWS regions where resources can be provisioned, as standard AWS region codes (e.g. us-east-1, eu-west-1). At least one region is required.
Constraintsat least one region must be specified
tagsmap(string)—Add metadata tags to organize and track AWS resources (e.g., 'Environment: Production')
scp_policystring—Define organization-wide restrictions using AWS SCP JSON syntax. Leave empty for no restrictions.
userblock—Define IAM users with specific permissions for lab participantsrepeatable
Constraintsat least one user must be specified

IAM User

aws_account→IAM User

IAM users to create in the AWS account

FieldTypeRequiredDescription
sluglabel—Unique identifier for the IAM user (e.g., 'alice', 'admin')
iam_policystring—Define custom permissions using AWS IAM policy JSON syntax. Overrides managed policies if specified.
managed_policieslist(string)—Attach AWS-managed policies by ARN (e.g., 'arn:aws:iam::aws:policy/ReadOnlyAccess')

Computed Attributes

These attributes are set by the system and are read-only.

AttributeTypeDescription
account_idstringThe AWS account ID assigned to this sandbox account
account_namestringThe AWS account name assigned to this sandbox account
user[].usernamestringThe IAM username assigned to this user
user[].passwordstringThe console password for this IAM user
user[].access_key_idstringThe AWS access key ID for programmatic access
user[].secret_access_keystringThe AWS secret access key for programmatic access

aws_account → user

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

FieldRequiredTypeDescription
slug✓labelUsername for the IAM user, written as the block label: user “alice” { … }
iam_policystringCustom IAM policy JSON for the user
managed_policieslist(string)AWS managed policy ARNs to attach to the user. Defaults to empty list.

The block label is a short name you choose, such as alice, student, or admin. It doesn’t have to match anything outside the lab. Pick a name that describes the user’s role in the scenario.

In the UI, the label is the Username field of the IAM User section. The Name (internal) field at the top of the form is the name of the aws_account resource itself, not of an IAM user.

Instruqt creates an IAM user from the label and generates its sign-in credentials. The learner signs in with the computed attributes below (username, password, access_key_id, secret_access_key). You usually show them in a cloud credentials tab or with instruction variables.

For each user block, these attributes are computed:

FieldTypeDescription
usernamestringThe IAM username
passwordstringConsole password for the user
access_key_idstringAWS access key ID for programmatic access
secret_access_keystringAWS secret access key for programmatic access
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.0.username # e.g., "student"
password = resource.aws_account.training.user.0.password # e.g., "TempPass123!"
access_key = resource.aws_account.training.user.0.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.0.access_key_id # e.g., "AKIAIOSFODNN7EXAMPLE"
AWS_SECRET_ACCESS_KEY = resource.aws_account.serverless_lab.user.0.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.0.access_key_id} # e.g., "AKIAIOSFODNN7EXAMPLE"
aws_secret_access_key = ${resource.aws_account.lab.user.0.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.0.username} # e.g., "student"
- Password: ${resource.aws_account.lab.user.0.password} # e.g., "TempPass123!"
## Programmatic Access
- Access Key ID: ${resource.aws_account.lab.user.0.access_key_id}
- Secret Access Key: ${resource.aws_account.lab.user.0.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