Search code examples
amazon-web-servicesaws-lambdaterraformaws-clilocalstack

Error with creating IAM role when terraform applying a lambda function to localstack?


I have the following directory hierarchy:

Lambda
│
├── adduserpost
│   ├── venv
│   ├── .terraform
│   ├── .terraform.lock.hcl
│   ├── lambda_function_add_user_post.zip
│   ├── lambda-addUserPost.tf
│   ├── lambdafunctions.py
│   ├── terraform.tfstate
│   └── terraform.tfstate.backup
└── ...

lambda-addUserPost.tf has this content:

 provider "aws" {
      region                  = "us-east-1"  # Change to your desired region
      access_key              = "test"       # Access key for LocalStack
      secret_key              = "test"       # Secret key for LocalStack
      skip_credentials_validation = true
      skip_requesting_account_id = true
    
    
      endpoints {
        dynamodb    = "http://localhost:4566"  # LocalStack DynamoDB endpoint
        lambda      = "http://localhost:4566"
      }
    }
    
    resource "aws_lambda_function" "add_user_post" {
      function_name = "AddUserPost"
      handler       = "addUserPost.lambda_handler"
      runtime       = "python3.8"
      filename      = data.archive_file.lambda_function_add_user_post.output_path  # ZIP file containing your Python code
      role          = aws_iam_role.lambda_execution_role.arn
      source_code_hash = filebase64sha256(data.archive_file.lambda_function_add_user_post.output_path)
    
      environment {
        variables = {
          TABLE_NAME = "UserProfileTable"  # Update with your DynamoDB table name
        }
      }
    }
    
    resource "aws_iam_role" "lambda_execution_role" {
      name = "lambda_execution_role"
    
      assume_role_policy = jsonencode({
        Version = "2012-10-17",
        Statement = [
          {
            Action = "sts:AssumeRole",
            Effect = "Allow",
            Principal = {
              Service = "lambda.amazonaws.com"
            }
          }
        ]
      })
    }
    
    
    resource "aws_iam_role_policy_attachment" "lambda_dynamodb_access" {
      policy_arn = "arn:aws:iam::aws:policy/AmazonDynamoDBFullAccess"
      role       = aws_iam_role.lambda_execution_role.name
    }
    
    
    
    data "archive_file" "lambda_function_add_user_post" {
      type          = "zip"
      source_dir    = "${path.module}"
      output_path   = "${path.module}/lambda_function_add_user_post.zip"
    }

As far as I can tell, this is configured properly. However, running terraform apply gives me an error:

│ Error: creating IAM Role (lambda_execution_role): InvalidClientTokenId: The security token included in the request is invalid.
│       status code: 403, request id: e47ff97c-1fd3-46e7-b379-3b27d2cbb40f
│ 
│   with aws_iam_role.lambda_execution_role,
│   on lambda-addUserPost.tf line 30, in resource "aws_iam_role" "lambda_execution_role":

I don't understand why I am receiving this error. What security token? I have access_key and secret_key with placeholder values, but its localstack. Why do I need a valid security token? If needed, why is mine not properly set up? How can I fix this? I am able to terraform apply a dynamoDB table with no issues.


Solution

  • First step is to make sure your localstack, terraform and aws provider versions are up to date.

    Next, I suspect the issue is that the IAM endpoint is not configured, so when terraform tries to create the IAM resources you have, it tried to connect to AWS.

    endpoints {
            dynamodb    = "http://localhost:4566"
            lambda      = "http://localhost:4566"
            iam         = "http://localhost:4566"
     }