AWS IAM Policy Simulator with Terraform: Test Permissions Before Deploying
Use the AWS IAM Policy Simulator to validate Terraform IAM policies before applying. Automate permission testing with Terraform data sources and avoid AccessDenied errors.
DevOps
Provision mobile app backends with Terraform: AWS Amplify, Cognito auth, AppSync GraphQL, S3 user content, and push notifications via SNS.
Mobile apps on iOS and Android live or die by their backend: auth, sync API, file storage, push, and analytics. Terraform doesn't ship apps to the App Store, but it provisions the entire AWS backend that 90% of mobile apps rely on. This guide shows the canonical stack: Cognito + AppSync + DynamoDB + S3 + SNS + Pinpoint.
| Capability | AWS service |
|---|---|
| User auth | Cognito User Pool + Identity Pool |
| Sync API | AppSync (GraphQL) + DynamoDB |
| User content | S3 with presigned URLs |
| Push | SNS Mobile Push (APNs + FCM) |
| Analytics | Pinpoint |
resource "aws_cognito_user_pool" "users" {
name = "app-users"
password_policy {
minimum_length = 12
require_lowercase = true
require_numbers = true
require_symbols = true
require_uppercase = true
}
mfa_configuration = "OPTIONAL"
software_token_mfa_configuration {
enabled = true
}
username_attributes = ["email"]
auto_verified_attributes = ["email"]
}
resource "aws_cognito_user_pool_client" "mobile" {
name = "mobile"
user_pool_id = aws_cognito_user_pool.users.id
generate_secret = false # mobile apps can't keep secrets
refresh_token_validity = 30
access_token_validity = 60
id_token_validity = 60
token_validity_units {
refresh_token = "days"
access_token = "minutes"
id_token = "minutes"
}
explicit_auth_flows = [
"ALLOW_USER_SRP_AUTH",
"ALLOW_REFRESH_TOKEN_AUTH",
]
}resource "aws_appsync_graphql_api" "api" {
name = "app-api"
authentication_type = "AMAZON_COGNITO_USER_POOLS"
user_pool_config {
user_pool_id = aws_cognito_user_pool.users.id
aws_region = var.region
default_action = "ALLOW"
}
schema = file("${path.module}/schema.graphql")
log_config {
cloudwatch_logs_role_arn = aws_iam_role.appsync_logs.arn
field_log_level = "ERROR"
}
}
resource "aws_appsync_datasource" "todos" {
api_id = aws_appsync_graphql_api.api.id
name = "todos"
service_role_arn = aws_iam_role.appsync.arn
type = "AMAZON_DYNAMODB"
dynamodb_config {
table_name = aws_dynamodb_table.todos.name
}
}resource "aws_s3_bucket" "user_content" {
bucket = "app-user-content"
}
resource "aws_s3_bucket_cors_configuration" "user_content" {
bucket = aws_s3_bucket.user_content.id
cors_rule {
allowed_headers = ["*"]
allowed_methods = ["GET", "PUT", "POST", "HEAD"]
allowed_origins = ["*"]
expose_headers = ["ETag"]
max_age_seconds = 3000
}
}The mobile app calls a Lambda that issues short-lived presigned URLs scoped to users/<sub>/... so users only see their own files.
resource "aws_sns_platform_application" "ios" {
name = "ios-app"
platform = "APNS" # APNS_SANDBOX for dev
platform_credential = file(var.apns_p8_path)
platform_principal = var.apns_team_id
}
resource "aws_sns_platform_application" "android" {
name = "android-app"
platform = "GCM"
platform_credential = var.fcm_server_key
}generate_secret = false + SRP is the safe path.arn:aws:s3:::bucket/users/$${cognito-identity.amazonaws.com:sub}/*.Use the AWS IAM Policy Simulator to validate Terraform IAM policies before applying. Automate permission testing with Terraform data sources and avoid AccessDenied errors.
Deploy real infrastructure on AWS Free Tier with Terraform. Includes EC2, S3, RDS, Lambda, and DynamoDB examples — all within free tier limits. No charges if you follow this guide.
Deploy OpenClaw AI on AWS EC2 with Terraform: Ubuntu 24.04, gp3 EBS for persistent agent data, SSH key pair, security group, and user-data bootstrap.
Provision multiplayer game server backends with Terraform: AWS GameLift fleets, FlexMatch matchmaking, queues, and player session APIs.