I want to create infra and find the minimum permissions required for the user to perform terraform deployment and follow best practices. The issue is with AWS API Gateway, which makes me puzzled about the permissions I need to give users.
The idea is that API Gateway has methods and mapping before pushing it further to SQS.
The snippet of Terraform I am running is below:
resource "aws_iam_role" "apiSQS" {
name = "${var.integration}-${var.stage}-apigateway_sqs"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "apigateway.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
}
resource "aws_api_gateway_rest_api" "integration-api-gateway"{
name = "${var.integration}-${var.stage}-api"
description = "Parse and send messages to SQS"
endpoint_configuration {
types = ["REGIONAL"]
}
}
resource "aws_api_gateway_resource" "booking" {
rest_api_id = aws_api_gateway_rest_api.integration-api-gateway.id
parent_id = aws_api_gateway_rest_api.integration-api-gateway.root_resource_id
path_part = "booking"
}
# booking/create
resource "aws_api_gateway_resource" "create" {
rest_api_id = aws_api_gateway_rest_api.integration-api-gateway.id
parent_id = aws_api_gateway_resource.booking.id
path_part = "create"
}
resource "aws_api_gateway_method" "method_create" {
rest_api_id = aws_api_gateway_rest_api.integration-api-gateway.id
resource_id = aws_api_gateway_resource.create.id
http_method = "POST"
authorization = "NONE"
request_parameters = {
"method.request.path.proxy" = false
}
}
resource "aws_api_gateway_integration" "create_integration" {
rest_api_id = aws_api_gateway_rest_api.integration-api-gateway.id
resource_id = aws_api_gateway_resource.create.id
http_method = aws_api_gateway_method.method_create.http_method
type = "AWS"
integration_http_method = "POST"
credentials = aws_iam_role.apiSQS.arn
uri = "arn:aws:apigateway:${var.region}:sqs:path/${aws_sqs_queue.bookings-sqs.name}"
request_parameters = {
"integration.request.header.Content-Type" = "'application/x-www-form-urlencoded'"
}
# Request Template for passing Method, Body, QueryParameters and PathParams to SQS messages
request_templates = {
"application/json" = <<EOF
Action=SendMessage&MessageBody={
"data": $util.urlEncode($input.body),
"token": "$input.params('token')"
}
EOF
}
depends_on = [
aws_iam_role_policy_attachment.api_exec_role
]
}
# Mapping SQS Response
resource "aws_api_gateway_method_response" "method_create_response_200" {
rest_api_id = aws_api_gateway_rest_api.integration-api-gateway.id
resource_id = aws_api_gateway_resource.create.id
http_method = aws_api_gateway_method.method_create.http_method
status_code = 200
response_models = {
"application/json" = "Empty"
}
}
resource "aws_api_gateway_integration_response" "create_integration_response" {
rest_api_id = aws_api_gateway_rest_api.integration-api-gateway.id
resource_id = aws_api_gateway_resource.create.id
http_method = aws_api_gateway_method.method_create.http_method
status_code = aws_api_gateway_method_response.method_create_response_200.status_code
response_templates = {
"application/json" = "Empty"
}
depends_on = [
aws_api_gateway_integration.create_integration
]
}
Error is:
╷
│ Error: Error creating API Gateway Integration: AccessDeniedException:
│ status code: 403, request id: 4f6a7ab0-3551-4ea0-80a4-4f89edbaad8c
│
│ with aws_api_gateway_integration.create_integration,
│ on main.tf line 212, in resource "aws_api_gateway_integration" "create_integration":
│ 212: resource "aws_api_gateway_integration" "create_integration" {
│
╵
The latest policy I attached to the user is:
{
"Effect": "Allow",
"Action": [
"apigateway:*"
],
"Resource": [
"arn:aws:apigateway:*::/*"
]
}
Am I missing anything here? How can I find missing policies?
I searched StackOverflow, GitHub, and Googled the issue but so far, no luck. I tried to run the same code with Administration rights, and it worked fine. Any idea?
UPDATE 1:
I have tried IAM Access Analyzer, and it didn't help much. It generated some nonsense.
UPDATE 2:
Based on the previous step, I enabled AWS CloudTrail
and found events I need to reproduce:
- GetIntegration
- PutIntegration
- DeleteIntegration
I found a reference doc
Any idea how to progress further?