Skip to main content

IAM Admin User Setup Guide

Complete guide for setting up an admin IAM user with appropriate permissions for managing the FishingLog AWS infrastructure.

📋 Overview

This guide covers IAM policies for an admin user who needs to manage:

  • Cognito (user management)
  • ECS (container deployment)
  • ECR (Docker images)
  • RDS (PostgreSQL database)
  • ElastiCache/Valkey (caching)
  • S3 (images/media storage)
  • CloudWatch (logs & monitoring)
  • Load Balancer (traffic distribution)
  • Certificate Manager (SSL certificates)
  • IAM (role management)

🔐 Step 1: Create Admin User

  1. AWS ConsoleIAMUsersCreate user

  2. User name: fishinglog-admin (or your preferred name)

  3. Access type:

    • Provide user access to the AWS Management Console - Checked (for console access)
    • Access key - Programmatic access - Checked (for CLI/API access)
  4. Set permissions → Choose one of the options below


🎯 Option 1: AWS Managed Policies (Quick Setup)

Pros: Easy to set up, AWS-maintained
Cons: May include more permissions than needed

  1. PowerUserAccess (Recommended for Admin)

    • Full access except IAM user/role management
    • Good balance of power and security
    • Can manage all services but can't create/delete IAM users/roles
  2. Or combine these specific policies:

    • AmazonEC2FullAccess (for Load Balancer, Security Groups)
    • AmazonECS_FullAccess (for ECS management)
    • AmazonEC2ContainerRegistryFullAccess (for ECR)
    • AmazonRDSFullAccess (for database management)
    • AmazonElastiCacheFullAccess (for Valkey cache)
    • AmazonS3FullAccess (for S3 buckets)
    • AmazonCognitoPowerUser (for Cognito user management)
    • CloudWatchFullAccess (for logs & metrics)
    • AWSCertificateManagerFullAccess (for SSL certificates)

Note: These are broad policies. For better security, use Option 2 (Custom Policy).


Pros: Least privilege, only what you need
Cons: Requires more setup, needs updates as services grow

Create Custom Admin Policy

  1. IAM ConsolePoliciesCreate policyJSON

  2. Policy name: FishingLogAdminPolicy

  3. Description: Full admin access to FishingLog AWS resources (staging + production)

  4. Policy JSON:

{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "CognitoUserManagement",
"Effect": "Allow",
"Action": [
"cognito-idp:AdminCreateUser",
"cognito-idp:AdminDeleteUser",
"cognito-idp:AdminGetUser",
"cognito-idp:AdminSetUserPassword",
"cognito-idp:AdminConfirmSignUp",
"cognito-idp:AdminEnableUser",
"cognito-idp:AdminDisableUser",
"cognito-idp:AdminResetUserPassword",
"cognito-idp:ListUsers",
"cognito-idp:DescribeUserPool",
"cognito-idp:DescribeUserPoolClient"
],
"Resource": [
"arn:aws:cognito-idp:us-east-2:606532921651:userpool/us-east-2_TZtGx1T3X"
]
},
{
"Sid": "ECRManagement",
"Effect": "Allow",
"Action": [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"ecr:PutImage",
"ecr:InitiateLayerUpload",
"ecr:UploadLayerPart",
"ecr:CompleteLayerUpload",
"ecr:DescribeRepositories",
"ecr:ListImages",
"ecr:CreateRepository",
"ecr:DeleteRepository",
"ecr:TagResource",
"ecr:UntagResource"
],
"Resource": [
"arn:aws:ecr:us-east-2:606532921651:repository/reelog-api-staging",
"arn:aws:ecr:us-east-2:606532921651:repository/reelog-api-prod"
]
},
{
"Sid": "ECSManagement",
"Effect": "Allow",
"Action": [
"ecs:CreateCluster",
"ecs:DeleteCluster",
"ecs:DescribeClusters",
"ecs:ListClusters",
"ecs:CreateService",
"ecs:UpdateService",
"ecs:DeleteService",
"ecs:DescribeServices",
"ecs:ListServices",
"ecs:RegisterTaskDefinition",
"ecs:DeregisterTaskDefinition",
"ecs:DescribeTaskDefinition",
"ecs:ListTaskDefinitions",
"ecs:RunTask",
"ecs:StopTask",
"ecs:DescribeTasks",
"ecs:ListTasks",
"ecs:TagResource",
"ecs:UntagResource"
],
"Resource": "*"
},
{
"Sid": "RDSManagement",
"Effect": "Allow",
"Action": [
"rds:DescribeDBInstances",
"rds:DescribeDBClusters",
"rds:CreateDBInstance",
"rds:ModifyDBInstance",
"rds:DeleteDBInstance",
"rds:RebootDBInstance",
"rds:CreateDBSnapshot",
"rds:DescribeDBSnapshots",
"rds:RestoreDBInstanceFromDBSnapshot",
"rds:StartDBInstance",
"rds:StopDBInstance",
"rds:AddTagsToResource",
"rds:RemoveTagsFromResource",
"rds:ListTagsForResource"
],
"Resource": [
"arn:aws:rds:us-east-2:606532921651:db:reelog-db-staging",
"arn:aws:rds:us-east-2:606532921651:db:reelog-db-prod"
]
},
{
"Sid": "ElastiCacheManagement",
"Effect": "Allow",
"Action": [
"elasticache:DescribeCacheClusters",
"elasticache:DescribeReplicationGroups",
"elasticache:CreateCacheCluster",
"elasticache:ModifyCacheCluster",
"elasticache:DeleteCacheCluster",
"elasticache:RebootCacheCluster",
"elasticache:CreateSnapshot",
"elasticache:DescribeSnapshots",
"elasticache:AddTagsToResource",
"elasticache:RemoveTagsFromResource",
"elasticache:ListTagsForResource"
],
"Resource": "*"
},
{
"Sid": "S3Management",
"Effect": "Allow",
"Action": [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject",
"s3:ListBucket",
"s3:GetBucketLocation",
"s3:GetBucketAcl",
"s3:PutBucketAcl",
"s3:GetBucketPolicy",
"s3:PutBucketPolicy",
"s3:DeleteBucketPolicy",
"s3:GetBucketTagging",
"s3:PutBucketTagging"
],
"Resource": [
"arn:aws:s3:::reelog-media-staging",
"arn:aws:s3:::reelog-media-staging/*",
"arn:aws:s3:::reelog-media-prod",
"arn:aws:s3:::reelog-media-prod/*"
]
},
{
"Sid": "LoadBalancerManagement",
"Effect": "Allow",
"Action": [
"elasticloadbalancing:CreateLoadBalancer",
"elasticloadbalancing:DeleteLoadBalancer",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:ModifyLoadBalancerAttributes",
"elasticloadbalancing:CreateTargetGroup",
"elasticloadbalancing:DeleteTargetGroup",
"elasticloadbalancing:DescribeTargetGroups",
"elasticloadbalancing:ModifyTargetGroup",
"elasticloadbalancing:RegisterTargets",
"elasticloadbalancing:DeregisterTargets",
"elasticloadbalancing:DescribeTargetHealth",
"elasticloadbalancing:CreateListener",
"elasticloadbalancing:DeleteListener",
"elasticloadbalancing:DescribeListeners",
"elasticloadbalancing:ModifyListener",
"elasticloadbalancing:AddTags",
"elasticloadbalancing:RemoveTags"
],
"Resource": "*"
},
{
"Sid": "CloudWatchManagement",
"Effect": "Allow",
"Action": [
"logs:CreateLogGroup",
"logs:DeleteLogGroup",
"logs:DescribeLogGroups",
"logs:CreateLogStream",
"logs:DeleteLogStream",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
"logs:GetLogEvents",
"logs:FilterLogEvents",
"logs:TagLogGroup",
"cloudwatch:GetMetricStatistics",
"cloudwatch:ListMetrics",
"cloudwatch:PutMetricAlarm",
"cloudwatch:DeleteAlarms",
"cloudwatch:DescribeAlarms"
],
"Resource": "*"
},
{
"Sid": "CertificateManager",
"Effect": "Allow",
"Action": [
"acm:RequestCertificate",
"acm:DescribeCertificate",
"acm:ListCertificates",
"acm:DeleteCertificate",
"acm:AddTagsToCertificate",
"acm:RemoveTagsFromCertificate"
],
"Resource": "*"
},
{
"Sid": "IAMRolePassThrough",
"Effect": "Allow",
"Action": [
"iam:PassRole"
],
"Resource": [
"arn:aws:iam::606532921651:role/reelog-ecs-task-execution-role",
"arn:aws:iam::606532921651:role/reelog-ecs-task-role"
]
},
{
"Sid": "IAMReadOnly",
"Effect": "Allow",
"Action": [
"iam:GetRole",
"iam:GetRolePolicy",
"iam:ListRolePolicies",
"iam:ListAttachedRolePolicies",
"iam:ListRoles",
"iam:GetPolicy",
"iam:ListPolicies",
"iam:GetUser",
"iam:ListUsers"
],
"Resource": "*"
},
{
"Sid": "EC2SecurityGroups",
"Effect": "Allow",
"Action": [
"ec2:DescribeSecurityGroups",
"ec2:CreateSecurityGroup",
"ec2:DeleteSecurityGroup",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:RevokeSecurityGroupEgress",
"ec2:DescribeVpcs",
"ec2:DescribeSubnets",
"ec2:DescribeNetworkInterfaces"
],
"Resource": "*"
},
{
"Sid": "TagManagement",
"Effect": "Allow",
"Action": [
"tag:GetResources",
"tag:TagResources",
"tag:UntagResources"
],
"Resource": "*"
}
]
}
  1. Tags (optional):

    • Environment = All
    • Project = Reelog
    • Purpose = AdminPolicy
  2. Create policy

  3. Attach to user:

    • Go to your user → PermissionsAdd permissionsAttach policies directly
    • Select FishingLogAdminPolicy
    • NextAdd permissions

🎯 Option 3: Hybrid Approach (Balanced)

Use AWS managed policies for broad access, plus custom policy for specific restrictions:

  1. Attach managed policies:

    • PowerUserAccess (or ReadOnlyAccess + specific service policies)
  2. Add custom policy for:

    • Cognito user management (if not covered)
    • IAM PassRole (for ECS task roles)
    • Resource-specific restrictions (S3 buckets, RDS instances)

✅ Step 2: Configure AWS CLI

After creating the user and attaching policies:

  1. Create access key:

    • IAM → Users → fishinglog-adminSecurity credentials
    • Access keysCreate access key
    • Choose Command Line Interface (CLI)
    • Copy Access key ID and Secret access key
  2. Configure AWS CLI:

    aws configure

    Enter:

    • AWS Access Key ID: Your access key
    • AWS Secret Access Key: Your secret key
    • Default region: us-east-2
    • Default output format: json
  3. Test configuration:

    aws sts get-caller-identity

    Should return your account ID and user ARN.


🔒 Security Best Practices

1. Enable MFA (Multi-Factor Authentication)

Highly Recommended:

  1. IAM ConsoleUsersfishinglog-admin
  2. Security credentials tab
  3. Assigned MFA deviceAssign MFA device
  4. Choose Virtual MFA device (use authenticator app)
  5. Scan QR code and enter two consecutive codes

Note: Console access will require MFA. CLI access can use session tokens.

2. Use IAM Roles Instead of Users (For Applications)

  • For GitHub Actions: Use IAM user (as configured)
  • For ECS tasks: Use IAM roles (already configured)
  • For admin console access: IAM user with MFA

3. Rotate Access Keys Regularly

  • Rotate access keys every 90 days
  • IAM → Users → Security credentials → Rotate access keys

4. Use Least Privilege

  • Start with minimal permissions
  • Add permissions as needed
  • Review and remove unused permissions quarterly

5. Enable CloudTrail

  • Track all API calls made by admin user
  • AWS Console → CloudTrail → Create trail
  • Monitor for suspicious activity

📝 Quick Reference: What Each Service Needs

ServiceAdmin NeedsPolicy Section
CognitoCreate/delete users, set passwordsCognitoUserManagement
ECSDeploy services, update tasksECSManagement
ECRPush/pull Docker imagesECRManagement
RDSManage database instancesRDSManagement
ElastiCacheManage cache clustersElastiCacheManagement
S3Upload/download files, manage bucketsS3Management
Load BalancerCreate/update load balancersLoadBalancerManagement
CloudWatchView logs, create alarmsCloudWatchManagement
ACMManage SSL certificatesCertificateManager
IAMPass roles to ECS tasksIAMRolePassThrough

🚨 Common Issues

Issue: "Access Denied" when running AWS CLI commands

Solution:

  • Check IAM user has correct policies attached
  • Verify access keys are correct: aws configure list
  • Test with: aws sts get-caller-identity

Issue: "Cannot assume role" for ECS tasks

Solution:

  • Ensure iam:PassRole permission is granted
  • Verify role ARNs in policy match your actual roles

Issue: "Cannot access S3 bucket"

Solution:

  • Check S3 bucket ARNs in policy match your buckets
  • Verify bucket names: reelog-media-staging, reelog-media-prod

📚 Next Steps

  1. ✅ Create admin user with policies
  2. ✅ Configure AWS CLI
  3. ✅ Enable MFA
  4. ✅ Test Cognito user creation: aws cognito-idp admin-create-user ...
  5. ✅ Test ECS deployment
  6. ✅ Review CloudTrail logs

Account ID: 606532921651
Region: us-east-2
Last Updated: December 10, 2025