Search code examples
amazon-s3terraformaws-cliterraform-provider-aws

Getting errors when executing terraform script


I have below terraform script that throws errors like IAM role can not be found and S3 bucket not found. I am writing this script for first time. I know i am doing something silly. I checked and compared this script in google. But i couldnt figure out what is wrong with this. Any insights?

provider "aws" {
  region = "us-east-1"
}

resource "aws_s3_bucket" "my_bucket" {
  bucket = "exe-use1-s3-splt-loa-fix-test"
}

# Upload jar file to S3
resource "aws_s3_object" "my_jar_file" {
  bucket = aws_s3_bucket.my_bucket.id
  key    = "ADMoveTerminatedAccount-0.0.1-SNAPSHOT.jar"
  #Actual path has been changed to the below
  source = "/path/to/jar/ADMoveTerminatedAccount-0.0.1-SNAPSHOT.jar"
}

# Create an IAM role for the Lambda function
resource "aws_iam_role" "lambda_role" {
  name = "EXE-USE1-IAMROLE-SPLT-LOA-TEST"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Action = "sts:AssumeRole"
        Effect = "Allow"
        Principal = {
          Service = "lambda.amazonaws.com"
        }
      }
    ]
  })
}

# Lambda policy
resource "aws_iam_policy" "lambda_policy" {
  name        = "EXE-USE1-IAMLAMBDAPOLICY-SPLT-LOA-TEST"
  policy      = jsonencode({
    Version = "2012-10-17"
    Statement = [
      {
        Effect    = "Allow"
        Action    = [
          "logs:CreateLogGroup",
          "logs:CreateLogStream",
          "logs:PutLogEvents"
        ]
        Resource  = "*"
      }
    ]
  })
}

# Attach a basic execution policy to the IAM role
resource "aws_iam_role_policy_attachment" "lambda_policy_attachment" {
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
  role = aws_iam_role.lambda_role.name
}

data "aws_iam_role" "lambda_role" {
  name = "EXE-USE1-IAMROLE-SPLT-LOA-TEST"
}

# Define the Lambda function code
data "aws_s3_object" "splt_loa_lambda_jar" {
  bucket = "exe-use1-s3-splt-loa-fix-test"
  key = "ADMoveTerminatedAccount-0.0.1-SNAPSHOT.jar"
}

# Create the Lambda function
resource "aws_lambda_function" "lambda_function" {
  function_name    = "EXE-USE1-LAMBDA-SPLT-LOA-FIX-TEST"
  role             = "${data.aws_iam_role.lambda_role.arn}"
  handler          = "com.wynd.inow.ADMoveTerminatedUser.StreamLambdaHandler::SpringBootLambdaContainerHandler"
  runtime          = "java8"
  s3_bucket = "data.aws_s3_object.splt_loa_lambda_jar.bucket"
  s3_key = data.aws_s3_object.splt_loa_lambda_jar.key
}

# Create the API Gateway Rest API
resource "aws_api_gateway_rest_api" "splt-loa-api" {
  name = "EXE-USE1-APIGW-SPLT-LOA-FIX-TEST"
  description = "API Gateway for Sailpoint LOA issue"
}

# Create a resource moveaccount
resource "aws_api_gateway_resource" "splt-loa-api-resource" {
  rest_api_id = aws_api_gateway_rest_api.splt-loa-api.id
  parent_id   = aws_api_gateway_rest_api.splt-loa-api.root_resource_id
  path_part   = "moveaccount"
}

# Create a method
resource "aws_api_gateway_method" "splt_load_api_method" {
  rest_api_id   = aws_api_gateway_rest_api.splt-loa-api.id
  resource_id   = aws_api_gateway_resource.splt-loa-api-resource.id
  http_method   = "POST"
  authorization = "NONE"
}

# Create an integration between the API Gateway and the Lambda function
resource "aws_api_gateway_integration" "my_api_integration" {
  rest_api_id             = aws_api_gateway_rest_api.splt-loa-api.id
  resource_id             = aws_api_gateway_resource.splt-loa-api-resource.id
  http_method             = aws_api_gateway_method.splt_load_api_method.http_method
  integration_http_method = "POST"
  type                    = "AWS_PROXY"
  uri                     = aws_lambda_function.lambda_function.invoke_arn
}

# Create a deployment for the API Gateway
resource "aws_api_gateway_deployment" "splt_loa_api_deployment" {
  rest_api_id = aws_api_gateway_rest_api.splt-loa-api.id
  stage_name  = "test"
}

resource "aws_lambda_permission" "apigw" {
   statement_id  = "AllowExecutionFromAPIGateway"
   action        = "lambda:InvokeFunction"
   function_name = aws_lambda_function.lambda_function.function_name
   principal     = "apigateway.amazonaws.com"

   source_arn = "${aws_api_gateway_rest_api.splt-loa-api.execution_arn}/*/*"
}

# Output the API Gateway endpoint URL
output "api_gateway_url" {
  value = "${aws_api_gateway_deployment.splt_loa_api_deployment.invoke_url}"
}

Errors reported by terraform

    terraform plan       
data.aws_iam_role.lambda_role: Reading...
data.aws_s3_object.splt_loa_lambda_jar: Reading...
aws_api_gateway_rest_api.splt-loa-api: Refreshing state... [id=y4949w6uoe]
╷
│ Error: reading IAM Role (EXE-USE1-IAMROLE-SPLT-LOA-TEST): **NoSuchEntity: The role with name EXE-USE1-IAMROLE-SPLT-LOA-TEST cannot be found.**
│   status code: 404, request id: 26d7dfd5-f8e1-4254-a5b7-6ee16c17da22
│ 
│   with data.aws_iam_role.lambda_role,
│   on Sailpoint_AWS_Resources_deployment.tf line 59, in data "aws_iam_role" "lambda_role":
│   59: data "aws_iam_role" "lambda_role" {
│ 
╵


╷
│ Error: **getting S3 Bucket (exe-use1-s3-splt-loa-fix-test) Object (ADMoveTerminatedAccount-0.0.1-SNAPSHOT.jar): NotFound: Not Found**
│   status code: 404, request id: 4Q7JGD3YS8BSJD76, host id: Vqqgivqu+KJ6F5WEPHyVAWi7w/q1YMhdmgkByUfs8Q0rV0zBXvH2AnPLx80vRM3JmeEXJs+6pVo=
│ 
│   with data.aws_s3_object.splt_loa_lambda_jar,
│   on Sailpoint_AWS_Resources_deployment.tf line 64, in data "aws_s3_object" "splt_loa_lambda_jar":
│   64: data "aws_s3_object" "splt_loa_lambda_jar" {

    

 

Solution

  • You have a resource that will create an aws_iam_role:

    # Create an IAM role for the Lambda function
    resource "aws_iam_role" "lambda_role" {
      name = "EXE-USE1-IAMROLE-SPLT-LOA-TEST"
      assume_role_policy = jsonencode({
        Version = "2012-10-17"
        Statement = [
          {
            Action = "sts:AssumeRole"
            Effect = "Allow"
            Principal = {
              Service = "lambda.amazonaws.com"
            }
          }
        ]
      })
    }
    

    Then you define a data in what appears to be an attempt to capture an existing resource, in this case iam_role:

    data "aws_iam_role" "lambda_role" {
      name = "EXE-USE1-IAMROLE-SPLT-LOA-TEST"
    }
    

    I think you can simply delete the data aws_iam_role. It appears to serve no purpose because you can just reference the resource "lambda_role".

    Perhaps terraform checks that an aws_iam_role with a name of "EXE-USE1-IAMROLE-SPLT-LOA-TEST" exists due to the data element you have defined in there.