Skip to main content

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:
PolicyPurpose
AmazonCognitoPowerUserManage Cognito identity pools
AmazonDynamoDBFullAccessRead/write all DynamoDB tables
AmazonEC2ContainerRegistryFullAccessPush Docker images to ECR (for parse_invoice)
AmazonS3FullAccessManage S3 buckets and objects
AmazonSNSFullAccessPublish to SNS topics
AWSLambda_FullAccessDeploy and manage Lambda functions
CloudWatchEventsFullAccessManage EventBridge rules
CloudWatchLogsFullAccessRead and manage CloudWatch log groups
IAMFullAccessManage IAM resources via Terraform
SecretsManagerReadWriteCreate and manage secrets
Two additional inline policies are attached directly to the user (the group already has the maximum of 10 managed policies):
  • TerraformAutoScalingPermissionsapplication-autoscaling:Describe* and ListTagsForResource for managing DynamoDB autoscaling
  • APIGatewayFullAccessPolicyapigateway:* 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 nameFileFunction
Login-Lambda-Roleiam_login_lambda.tflogin_user
Signup-Lambda-Roleiam_signup_lambda.tfsignup_user
delete_user_lambda_roleiam_delete_user_lambda.tfdelete_user
get_rental_invoices_lambda_roleiam_get_rental_invoices_lambda.tfget_rental_invoices
get_rental_invoice_lambda_roleiam_get_rental_invoice_lambda.tfget_rental_invoice
get_user_profile_lambda_roleiam_get_user_profile_lambda.tfget_user_profile
gmail_store_tokens_lambda_roleiam_gmail_store_tokens_lambda.tfgmail_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:
PolicyPermissions
cognito-unauthenticatedcognito-identity:GetCredentialsForIdentity
wallenstam_sns_policysns: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.

Build docs developers (and LLMs) love