Let me provide a comprehensive solution addressing all three focus areas:
1. IAM Policy Resource ARNs:
Your resource ARN wildcard is incorrect. API Gateway execute-api requires specific stage and path specifications:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": [
"arn:aws:execute-api:us-east-1:123456789012:abc123def/prod/GET/hr/*",
"arn:aws:execute-api:us-east-1:123456789012:abc123def/prod/POST/hr/*",
"arn:aws:execute-api:us-east-1:123456789012:abc123def/prod/*/hr/employees"
]
}
]
}
Resource ARN format breakdown:
abc123def = API Gateway ID
prod = Stage name
GET/POST/* = HTTP method
/hr/* = Resource path
For broader access across all methods and paths in a stage:
"Resource": "arn:aws:execute-api:us-east-1:123456789012:abc123def/prod/*/*"
2. API Gateway Resource Policies:
Your resource policy’s VPC condition is blocking IAM role access. Here’s the corrected policy:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:123456789012:abc123def/*",
"Condition": {
"StringEquals": {
"aws:PrincipalArn": [
"arn:aws:iam::123456789012:role/AutomationServiceRole"
]
}
}
},
{
"Effect": "Allow",
"Principal": "*",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:123456789012:abc123def/*",
"Condition": {
"StringEquals": {
"aws:SourceVpce": "vpce-abc123" // Use VPC Endpoint ID, not VPC ID
}
}
}
]
}
Key differences:
- Changed
aws:SourceVpc to aws:SourceVpce (VPC Endpoint ID)
- Added explicit principal ARN condition for IAM role access
- Separated concerns: one statement for IAM roles, one for VPC endpoint access
3. Service Control Policy Overrides:
Check for SCPs that might deny API Gateway access:
# List all SCPs attached to your account
aws organizations list-policies-for-target \
--target-id 123456789012 \
--filter SERVICE_CONTROL_POLICY
# Get SCP content
aws organizations describe-policy \
--policy-id p-abc123
Common SCP that blocks API Gateway:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Deny",
"Action": "execute-api:Invoke",
"Resource": "*",
"Condition": {
"StringNotEquals": {
"aws:RequestedRegion": ["us-east-1", "us-west-2"]
}
}
}
]
}
If you find a blocking SCP, work with your organization admin to add an exception for your automation role.
Complete Diagnostic Process:
Pseudocode for troubleshooting IAM denials:
// Pseudocode - IAM access denial diagnosis:
1. Check CloudTrail for denied API call with full context
2. Verify IAM role trust policy allows EC2 service principal
3. Test IAM policy simulator: aws iam simulate-principal-policy
4. Review API Gateway resource policy for conflicting conditions
5. Check for SCPs: aws organizations list-policies-for-target
6. Verify resource ARN format includes stage and method
7. Test with aws apigateway test-invoke-method for direct validation
8. Check for session policies if using AssumeRole
// See AWS IAM Policy Evaluation Logic documentation
Verification Steps:
- Test IAM policy with simulator:
aws iam simulate-principal-policy \
--policy-source-arn arn:aws:iam::123456789012:role/AutomationServiceRole \
--action-names execute-api:Invoke \
--resource-arns arn:aws:execute-api:us-east-1:123456789012:abc123def/prod/GET/hr/employees
- Verify EC2 instance profile:
# From EC2 instance
curl http://169.254.169.254/latest/meta-data/iam/security-credentials/
- Test API Gateway access with assumed role credentials:
aws sts get-caller-identity # Verify you're using correct role
aws apigateway test-invoke-method \
--rest-api-id abc123def \
--resource-id xyz789 \
--http-method GET \
--path-with-query-string "/hr/employees"
Additional Considerations:
• Permission Boundaries: Check if the role has a permissions boundary that restricts execute-api:
aws iam get-role --role-name AutomationServiceRole \
--query 'Role.PermissionsBoundary'
• Session Tags: If using session tags with AssumeRole, ensure they don’t conflict with resource policy conditions
• VPC Endpoint Setup (if needed):
aws ec2 create-vpc-endpoint \
--vpc-id vpc-abc123 \
--service-name com.amazonaws.us-east-1.execute-api \
--route-table-ids rtb-abc123
Final Working Configuration:
IAM Role Policy (attached to AutomationServiceRole):
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:123456789012:abc123def/prod/*/*"
}]
}
API Gateway Resource Policy:
{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {"AWS": "arn:aws:iam::123456789012:role/AutomationServiceRole"},
"Action": "execute-api:Invoke",
"Resource": "arn:aws:execute-api:us-east-1:123456789012:abc123def/*"
}]
}
The key issues in your configuration were:
- Resource ARN missing stage and method specification
- Resource policy using
aws:SourceVpc condition which doesn’t apply to IAM role-based calls
- Potential SCP overrides not checked
With these corrections, your automation service should successfully invoke the HR APIs through API Gateway using the custom IAM role.