Documentation Index
Fetch the complete documentation index at: https://mintlify.com/azfar-imtiaz/PayPulse-Cloud/llms.txt
Use this file to discover all available pages before exploring further.
All IAM resources are managed in the iam child module at aws-infra-terraform/iam/. The module is invoked from the root main.tf and receives table ARNs, secret ARNs, and configuration variables as inputs.
Module structure
aws-infra-terraform/iam/
├── main.tf # Provider config
├── variables.tf # Module input variables
├── outputs.tf # Role ARN outputs consumed by root module
├── iam.tf # User, group, shared roles, and policies
├── iam_signup_lambda.tf
├── iam_login_lambda.tf
├── iam_delete_user_lambda.tf
├── iam_get_rental_invoice_lambda.tf
├── iam_get_rental_invoices_lambda.tf
├── iam_get_user_profile_lambda.tf
└── iam_gmail_store_tokens_lambda.tf
Each Lambda function that requires a custom IAM role has its own file in this directory. This keeps per-function permissions isolated and easy to audit.
IAM user and group
User: WallenstamTenant
resource "aws_iam_user" "wallenstam_user" {
name = "WallenstamTenant"
}
This is the IAM user used for programmatic access to AWS resources from local development and Terraform.
Group: Wallenstam
resource "aws_iam_group" "wallenstam_group" {
name = "Wallenstam"
}
WallenstamTenant is a member of the Wallenstam group, which has the following AWS-managed policies attached:
| Policy | Purpose |
|---|
AmazonCognitoPowerUser | Manage Cognito identity pools |
AmazonDynamoDBFullAccess | Read/write all DynamoDB tables |
AmazonEC2ContainerRegistryFullAccess | Push Docker images to ECR (for parse_invoice) |
AmazonS3FullAccess | Manage S3 buckets and objects |
AmazonSNSFullAccess | Publish to SNS topics |
AWSLambda_FullAccess | Deploy and manage Lambda functions |
CloudWatchEventsFullAccess | Manage EventBridge rules |
CloudWatchLogsFullAccess | Read and manage CloudWatch log groups |
IAMFullAccess | Manage IAM resources via Terraform |
SecretsManagerReadWrite | Create and manage secrets |
Two additional inline policies are attached directly to the user (the group already has the maximum of 10 managed policies):
- TerraformAutoScalingPermissions —
application-autoscaling:Describe* and ListTagsForResource for managing DynamoDB autoscaling
- APIGatewayFullAccessPolicy —
apigateway:* for managing API Gateway resources
Lambda execution roles
Wallenstam-Lambda-Role
The primary shared execution role used by most Lambda functions. Attached managed policies:
AmazonDynamoDBFullAccess
AmazonS3FullAccess
AmazonSNSFullAccess
CloudWatchLogsFullAccess
SecretsManagerReadWrite
Per-function roles
Several Lambda functions have dedicated execution roles with narrowly scoped inline policies. These are defined in the per-function IAM files:
| Role name | File | Function |
|---|
Login-Lambda-Role | iam_login_lambda.tf | login_user |
Signup-Lambda-Role | iam_signup_lambda.tf | signup_user |
delete_user_lambda_role | iam_delete_user_lambda.tf | delete_user |
get_rental_invoices_lambda_role | iam_get_rental_invoices_lambda.tf | get_rental_invoices |
get_rental_invoice_lambda_role | iam_get_rental_invoice_lambda.tf | get_rental_invoice |
get_user_profile_lambda_role | iam_get_user_profile_lambda.tf | get_user_profile |
gmail_store_tokens_lambda_role | iam_gmail_store_tokens_lambda.tf | gmail_store_tokens |
Each file follows the same pattern: an aws_iam_role with a Lambda trust policy, an aws_iam_policy with the minimum required permissions (typically DynamoDB table access and Secrets Manager read), and an aws_iam_role_policy_attachment binding the two.
Role ARNs are exported via outputs.tf and passed into the lambdas module by the root main.tf:
# In root main.tf
module "lambdas" {
...
wallenstam_lambda_role_arn = module.iam.wallenstam_lambda_role_arn
signup_lambda_role_arn = module.iam.signup_lambda_role_arn
delete_user_lambda_role_arn = module.iam.delete_user_lambda_role_arn
get_invoices_lambda_role_arn = module.iam.get_invoices_lambda_role_arn
get_rental_invoice_lambda_role_arn = module.iam.get_rental_invoice_lambda_role_arn
get_user_profile_lambda_role_arn = module.iam.get_user_profile_lambda_role_arn
gmail_store_tokens_lambda_role_arn = module.iam.gmail_store_tokens_lambda_role_arn
}
App identity role
WallenstamAppIdentityRole
This role is assumed by unauthenticated identities via the Cognito identity pool (WallenstamAppIdentityPool). It is used by the iOS app to register its APNs device token with SNS for push notifications.
resource "aws_iam_role" "wallenstam_app_identity_role" {
name = "WallenstamAppIdentityRole"
assume_role_policy = jsonencode({
Statement = [{
Effect = "Allow",
Principal = { Federated = "cognito-identity.amazonaws.com" },
Action = "sts:AssumeRoleWithWebIdentity",
Condition = {
"StringEquals" = {
"cognito-identity.amazonaws.com:aud" = "eu-west-1:81322675-4a0a-4b9b-a406-0058e1e2d9f4"
},
"ForAnyValue:StringLike" = {
"cognito-identity.amazonaws.com:amr" = "unauthenticated"
}
}
}]
})
}
Inline policies attached to this role:
| Policy | Permissions |
|---|
cognito-unauthenticated | cognito-identity:GetCredentialsForIdentity |
wallenstam_sns_policy | sns:CreatePlatformEndpoint |
The AmazonDynamoDBReadOnlyAccess managed policy is also attached to allow the iOS app to read invoice data directly from DynamoDB if needed.
Cognito identity pool
The WallenstamAppIdentityPool Cognito identity pool is defined in cognito.tf. It provides unauthenticated guest access for the iOS app, enabling it to call sns:CreatePlatformEndpoint to register for push notifications without requiring a full Cognito user pool login.
The identity pool is linked to WallenstamAppIdentityRole as its unauthenticated role.