I am having a problem in the following scenario. An AWS SES email address receives an email and triggers a lambda function. The lambda function start, or stops, one instance, uses SQS and SNS as well as Cloudwatch logs. This is most of the code:
# aws_lambda_function.start-stop-one:
resource "aws_lambda_function" "start-stop-one" {
architectures = [
"x86_64",
]
filename = "${path.module}/lambdas/start-instances.zip"
function_name = "start-stop-one"
handler = "lambda_function.lambda_handler"
layers = []
memory_size = 128
package_type = "Zip"
reserved_concurrent_executions = -1
role = aws_iam_role.start-stop-one.arn
runtime = "python3.9"
skip_destroy = false
source_code_hash = data.archive_file.start-stop-one.output_base64sha256
timeout = 180
ephemeral_storage {
size = 512
}
tracing_config {
mode = "PassThrough"
}
}
data "archive_file" "start-stop-one" {
type = "zip"
source_file = "${path.module}/lambdas/start-stop-one.py"
output_path = "${path.module}/lambdas/start-stop-one.zip"
}
# aws_cloudwatch_log_group.start-stop-one:
resource "aws_cloudwatch_log_group" "start-stop-one" {
name = "/aws/lambda/start-stop-one"
retention_in_days = 30
}
# aws_iam_policy.start-stop-one1:
resource "aws_iam_policy" "start-stop-one" {
name = "gwp-lambda-start-stop"
path = "/"
policy = jsonencode(
{
Statement = [
{
Action = [
"ec2:DescribeInstances",
"ec2:DescribeTags",
]
Effect = "Allow"
Resource = "*"
},
{
Effect = "Allow"
Action = [
"ec2:StartInstances",
"ec2:StopInstances",
]
Resource = [
"arn:aws:ec2:*:${data.aws_caller_identity.aws.account_id}:instance/*",
]
},
{
Effect = "Allow"
Action = [
"logs:CreateLogStream",
"logs:PutLogEvents",
]
Resource = "${aws_cloudwatch_log_group.start-stop-one.arn}:*"
},
{
"Effect": "Allow",
"Action": [
"sqs:SendMessage"
],
"Resource": aws_sqs_queue.ingestion.arn
},
{
"Effect": "Allow",
"Action": "lambda:InvokeFunction",
"Resource": aws_lambda_function.start-stop-one.arn,
"Condition": {
"StringEquals": {
"AWS:SourceAccount": data.aws_caller_identity.aws.account_id
},
"ArnLike": {
"AWS:SourceArn": aws_ses_receipt_rule.start-stop-one.arn
}
}
}
]
Version = "2012-10-17"
}
)
}
# aws_iam_role.start-stop-one:
resource "aws_iam_role" "start-stop-one" {
assume_role_policy = data.aws_iam_policy_document.lambda-amazonaws-com.json
force_detach_policies = false
max_session_duration = 3600
name = "start-stop-one"
path = "/"
}
resource "aws_iam_role_policy_attachment" "start-stop-one" {
role = aws_iam_role.start-stop-one.name
policy_arn = aws_iam_policy.start-stop-one.arn
}
# aws_ses_receipt_rule.start-stop-one:
resource "aws_ses_receipt_rule" "start-stop-one" {
enabled = true
name = "start-stop-one"
recipients = [
"startstopone@${var.client_id}.domain.com",
]
rule_set_name = aws_ses_receipt_rule_set.identity_rset.rule_set_name
scan_enabled = true
tls_policy = "Optional"
lambda_action {
function_arn = aws_lambda_function.start-stop-one.arn
invocation_type = "Event"
position = 1
topic_arn = aws_sns_topic.start-stop-instances.arn
}
}
# aws_lambda_permission.start-stop-one:
resource "aws_lambda_permission" "start-stop-one" {
action = "lambda:InvokeFunction"
function_name = aws_lambda_function.start-stop-one.function_name
principal = "ses.amazonaws.com"
source_account = data.aws_caller_identity.aws.account_id
#source_arn = "arn:aws:ses:us-east-1:123456789:receipt-rule-set/start_stop_emr:receipt-rule/start-stop-one"
source_arn = aws_ses_receipt_rule.start-stop-one.arn
}
If I run terraform apply i will get:
│ Error: creating SES Receipt Rule (start-stop-one): InvalidLambdaFunction: Could not invoke Lambda function: arn:aws:lambda:us-east-1:123456789:function:start-stop-one
│ status code: 400, request id: 4b3cad96-7bfa-4b18-8f69-34955d184f24
│
│ with aws_ses_receipt_rule.start-stop-one,
│ on lambda_start-stop-one.tf line 124, in resource "aws_ses_receipt_rule" "start-stop-one":
│ 124: resource "aws_ses_receipt_rule" "start-stop-one" {
│
If I switch the source_arn then it works perfectly. I have tried to use depends_on but to no avail or resulting in cycle. If I omit the source_arn then it works, but that’s not a good idea from a security perspective. Certainly there is a way of not using a fixed source_arn, but I can not find it. Thanks.