Skip to content

AWS Lambda Churn Prediction

Install packages

!uv pip install -q \
    diagrams==0.25.1

Import packages

1
2
3
4
5
from diagrams import Cluster, Diagram
from diagrams.aws.compute import EC2ContainerRegistry as ECR
from diagrams.aws.compute import Lambda
from diagrams.aws.general import User
from diagrams.aws.security import IAM

Architecture diagram

with Diagram(
    show=False,
    direction="TB",
    outformat="png",
    graph_attr={
        "size": "6",  # inches
        "margin": "0.1",
    },
) as diag:

    user = User("Client / Invoker")

    with Cluster(
        "AWS Account",
        graph_attr={
            "margin": "20",
        },
    ):
        iam = IAM("Execution Role")

        with Cluster("Amazon ECR"):
            ecr = ECR("Image")

        with Cluster("AWS Lambda"):
            lambda_fn = Lambda("Prediction")

        ecr >> lambda_fn
        iam >> lambda_fn

    user >> lambda_fn

diag
<diagrams.Diagram at 0x7fc20147c5d0>

Directory Structure

!tree -L 3
.

├── app

│   ├── Dockerfile

│   ├── event.json

│   ├── lambda_function.py

│   ├── model_C=10.bin

│   ├── pyproject.toml

│   ├── README.md

│   └── uv.lock

├── aws-lambda-churn-prediction.ipynb

├── diagrams_image.png

└── infra

    ├── main.tf

    ├── terraform.tfstate

    └── terraform.tfstate.backup



3 directories, 12 files

Application code

app/lambda_function.py
import pickle
from typing import Any, Dict

with open("model_C=10.bin", "rb") as f_in:
    loaded_dict_vectorizer, loaded_model = pickle.load(f_in)


def predict_single(customer: Any) -> Any:
    X = loaded_dict_vectorizer.transform([customer])
    result = loaded_model.predict_proba(X)[0, 1]
    return float(result)


def lambda_handler(event: Any, context: Any) -> Dict[str, Any]:
    print("Parameters: ", event)
    customer = event["customer"]
    churn_probability = predict_single(customer)

    return {
        "churn_probability": churn_probability,
        "churn": bool(churn_probability >= 0.5),
    }

Dockerfile

app/Dockerfile
FROM public.ecr.aws/lambda/python:3.13

COPY --from=ghcr.io/astral-sh/uv:latest /uv /bin
COPY pyproject.toml uv.lock ./

RUN uv pip install --system -r <(uv export --format requirements-txt)

COPY model_C=10.bin .
COPY lambda_function.py .

CMD ["lambda_function.lambda_handler"]

Terraform

infra/main.tf
terraform {
  required_version = ">= 1.5.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 5.0"
    }
    docker = {
      source  = "kreuzwerker/docker"
      version = "~> 3.0"
    }
  }
}

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

data "aws_caller_identity" "current" {}
data "aws_region" "current" {}

resource "aws_ecr_repository" "lambda_repo" {
  name                 = "churn-prediction-lambda"
  image_tag_mutability = "MUTABLE"
  force_delete         = true

  image_scanning_configuration {
    scan_on_push = true
  }
}

data "aws_ecr_authorization_token" "ecr" {}

locals {
  app_dir = "${path.module}/../app"

  docker_context_hash = sha256(join("", [
    for f in fileset(local.app_dir, "**") :
    filesha256("${local.app_dir}/${f}")
  ]))
}

provider "docker" {
  registry_auth {
    address  = "${data.aws_caller_identity.current.account_id}.dkr.ecr.${data.aws_region.current.name}.amazonaws.com"
    username = data.aws_ecr_authorization_token.ecr.user_name
    password = data.aws_ecr_authorization_token.ecr.password
  }
}

resource "docker_image" "lambda_image" {
  name = "${aws_ecr_repository.lambda_repo.repository_url}:${local.docker_context_hash}"

  build {
    context    = local.app_dir
    dockerfile = "Dockerfile"
    platform   = "linux/amd64"
  }
}

resource "docker_registry_image" "lambda_image" {
  name          = docker_image.lambda_image.name
  keep_remotely = true

  depends_on = [
    docker_image.lambda_image
  ]
}

resource "aws_ecr_lifecycle_policy" "cleanup" {
  repository = aws_ecr_repository.lambda_repo.name

  policy = jsonencode({
    rules = [{
      rulePriority = 1
      description  = "Keep last 2 images"
      selection = {
        tagStatus   = "any"
        countType   = "imageCountMoreThan"
        countNumber = 2
      }
      action = {
        type = "expire"
      }
    }]
  })
}

resource "aws_iam_role" "lambda_role" {
  name = "churn-prediction-lambda-role"

  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect = "Allow"
      Principal = {
        Service = "lambda.amazonaws.com"
      }
      Action = "sts:AssumeRole"
    }]
  })
}

resource "aws_iam_role_policy_attachment" "basic_logs" {
  role       = aws_iam_role.lambda_role.name
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
}


resource "aws_lambda_function" "churn_lambda" {
  function_name = "churn-prediction"
  role          = aws_iam_role.lambda_role.arn

  package_type = "Image"
  image_uri    = docker_registry_image.lambda_image.name

  memory_size = 1024
  timeout     = 30

  depends_on = [
    docker_registry_image.lambda_image
  ]
}

output "lambda_name" {
  value = aws_lambda_function.churn_lambda.function_name
}

output "ecr_repository_url" {
  value = aws_ecr_repository.lambda_repo.repository_url
}

Copy model artifact into app directory

!cp ../../machine-learning/artifacts/predicting-customer-churn/model_C=10.bin ./app

Terraform initialization

!cd infra && \
    terraform init
Initializing the backend...

Initializing provider plugins...

- Reusing previous version of kreuzwerker/docker from the dependency lock file

- Reusing previous version of hashicorp/aws from the dependency lock file

- Using previously-installed kreuzwerker/docker v3.6.2

- Using previously-installed hashicorp/aws v5.100.0



Terraform has been successfully initialized!



You may now begin working with Terraform. Try running "terraform plan" to see

any changes that are required for your infrastructure. All Terraform commands

should now work.



If you ever set or change modules or backend configuration for Terraform,

rerun this command to reinitialize your working directory. If you forget, other

commands will detect it and remind you to do so if necessary.

Terraform validation

!cd infra && \
    terraform validate
Success! The configuration is valid.

Terraform plan

!cd infra && \
    terraform plan
data.aws_region.current: Reading...

data.aws_ecr_authorization_token.ecr: Reading...

data.aws_caller_identity.current: Reading...

data.aws_region.current: Read complete after 0s [id=us-east-1]

data.aws_caller_identity.current: Read complete after 0s [id=544244312696]

data.aws_ecr_authorization_token.ecr: Read complete after 1s [id=us-east-1]



Terraform used the selected providers to generate the following execution plan.

Resource actions are indicated with the following symbols:

  + create



Terraform will perform the following actions:



  # aws_ecr_lifecycle_policy.cleanup will be created

  + resource "aws_ecr_lifecycle_policy" "cleanup" {

      + id          = (known after apply)

      + policy      = jsonencode(

            {

              + rules = [

                  + {

                      + action       = {

                          + type = "expire"

                        }

                      + description  = "Keep last 2 images"

                      + rulePriority = 1

                      + selection    = {

                          + countNumber = 2

                          + countType   = "imageCountMoreThan"

                          + tagStatus   = "any"

                        }

                    },

                ]

            }

        )

      + registry_id = (known after apply)

      + repository  = "churn-prediction-lambda"

    }



  # aws_ecr_repository.lambda_repo will be created

  + resource "aws_ecr_repository" "lambda_repo" {

      + arn                  = (known after apply)

      + force_delete         = true

      + id                   = (known after apply)

      + image_tag_mutability = "MUTABLE"

      + name                 = "churn-prediction-lambda"

      + registry_id          = (known after apply)

      + repository_url       = (known after apply)

      + tags_all             = (known after apply)



      + image_scanning_configuration {

          + scan_on_push = true

        }

    }



  # aws_iam_role.lambda_role will be created

  + resource "aws_iam_role" "lambda_role" {

      + arn                   = (known after apply)

      + assume_role_policy    = jsonencode(

            {

              + Statement = [

                  + {

                      + Action    = "sts:AssumeRole"

                      + Effect    = "Allow"

                      + Principal = {

                          + Service = "lambda.amazonaws.com"

                        }

                    },

                ]

              + Version   = "2012-10-17"

            }

        )

      + create_date           = (known after apply)

      + force_detach_policies = false

      + id                    = (known after apply)

      + managed_policy_arns   = (known after apply)

      + max_session_duration  = 3600

      + name                  = "churn-prediction-lambda-role"

      + name_prefix           = (known after apply)

      + path                  = "/"

      + tags_all              = (known after apply)

      + unique_id             = (known after apply)



      + inline_policy (known after apply)

    }



  # aws_iam_role_policy_attachment.basic_logs will be created

  + resource "aws_iam_role_policy_attachment" "basic_logs" {

      + id         = (known after apply)

      + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"

      + role       = "churn-prediction-lambda-role"

    }



  # aws_lambda_function.churn_lambda will be created

  + resource "aws_lambda_function" "churn_lambda" {

      + architectures                  = (known after apply)

      + arn                            = (known after apply)

      + code_sha256                    = (known after apply)

      + function_name                  = "churn-prediction"

      + id                             = (known after apply)

      + image_uri                      = (known after apply)

      + invoke_arn                     = (known after apply)

      + last_modified                  = (known after apply)

      + memory_size                    = 1024

      + package_type                   = "Image"

      + publish                        = false

      + qualified_arn                  = (known after apply)

      + qualified_invoke_arn           = (known after apply)

      + reserved_concurrent_executions = -1

      + role                           = (known after apply)

      + signing_job_arn                = (known after apply)

      + signing_profile_version_arn    = (known after apply)

      + skip_destroy                   = false

      + source_code_hash               = (known after apply)

      + source_code_size               = (known after apply)

      + tags_all                       = (known after apply)

      + timeout                        = 30

      + version                        = (known after apply)



      + ephemeral_storage (known after apply)



      + logging_config (known after apply)



      + tracing_config (known after apply)

    }



  # docker_image.lambda_image will be created

  + resource "docker_image" "lambda_image" {

      + id          = (known after apply)

      + image_id    = (known after apply)

      + name        = (known after apply)

      + repo_digest = (known after apply)



      + build {

          + cache_from     = []

          + context        = "./../app"

          + dockerfile     = "Dockerfile"

          + extra_hosts    = []

          + platform       = "linux/amd64"

          + remove         = true

          + security_opt   = []

          + tag            = []

            # (12 unchanged attributes hidden)

        }

    }



  # docker_registry_image.lambda_image will be created

  + resource "docker_registry_image" "lambda_image" {

      + id                   = (known after apply)

      + insecure_skip_verify = false

      + keep_remotely        = true

      + name                 = (known after apply)

      + sha256_digest        = (known after apply)

    }



Plan: 7 to add, 0 to change, 0 to destroy.



Changes to Outputs:

  + ecr_repository_url = (known after apply)

  + lambda_name        = "churn-prediction"



───────────────────────────────────────────────────────────────────────────────



Note: You didn't use the -out option to save this plan, so Terraform can't

guarantee to take exactly these actions if you run "terraform apply" now.

Terraform apply

!cd infra && \
    terraform apply --auto-approve
data.aws_region.current: Reading...

data.aws_ecr_authorization_token.ecr: Reading...

data.aws_caller_identity.current: Reading...

data.aws_region.current: Read complete after 0s [id=us-east-1]

data.aws_caller_identity.current: Read complete after 0s [id=544244312696]

data.aws_ecr_authorization_token.ecr: Read complete after 0s [id=us-east-1]



Terraform used the selected providers to generate the following execution plan.

Resource actions are indicated with the following symbols:

  + create



Terraform will perform the following actions:



  # aws_ecr_lifecycle_policy.cleanup will be created

  + resource "aws_ecr_lifecycle_policy" "cleanup" {

      + id          = (known after apply)

      + policy      = jsonencode(

            {

              + rules = [

                  + {

                      + action       = {

                          + type = "expire"

                        }

                      + description  = "Keep last 2 images"

                      + rulePriority = 1

                      + selection    = {

                          + countNumber = 2

                          + countType   = "imageCountMoreThan"

                          + tagStatus   = "any"

                        }

                    },

                ]

            }

        )

      + registry_id = (known after apply)

      + repository  = "churn-prediction-lambda"

    }



  # aws_ecr_repository.lambda_repo will be created

  + resource "aws_ecr_repository" "lambda_repo" {

      + arn                  = (known after apply)

      + force_delete         = true

      + id                   = (known after apply)

      + image_tag_mutability = "MUTABLE"

      + name                 = "churn-prediction-lambda"

      + registry_id          = (known after apply)

      + repository_url       = (known after apply)

      + tags_all             = (known after apply)



      + image_scanning_configuration {

          + scan_on_push = true

        }

    }



  # aws_iam_role.lambda_role will be created

  + resource "aws_iam_role" "lambda_role" {

      + arn                   = (known after apply)

      + assume_role_policy    = jsonencode(

            {

              + Statement = [

                  + {

                      + Action    = "sts:AssumeRole"

                      + Effect    = "Allow"

                      + Principal = {

                          + Service = "lambda.amazonaws.com"

                        }

                    },

                ]

              + Version   = "2012-10-17"

            }

        )

      + create_date           = (known after apply)

      + force_detach_policies = false

      + id                    = (known after apply)

      + managed_policy_arns   = (known after apply)

      + max_session_duration  = 3600

      + name                  = "churn-prediction-lambda-role"

      + name_prefix           = (known after apply)

      + path                  = "/"

      + tags_all              = (known after apply)

      + unique_id             = (known after apply)



      + inline_policy (known after apply)

    }



  # aws_iam_role_policy_attachment.basic_logs will be created

  + resource "aws_iam_role_policy_attachment" "basic_logs" {

      + id         = (known after apply)

      + policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"

      + role       = "churn-prediction-lambda-role"

    }



  # aws_lambda_function.churn_lambda will be created

  + resource "aws_lambda_function" "churn_lambda" {

      + architectures                  = (known after apply)

      + arn                            = (known after apply)

      + code_sha256                    = (known after apply)

      + function_name                  = "churn-prediction"

      + id                             = (known after apply)

      + image_uri                      = (known after apply)

      + invoke_arn                     = (known after apply)

      + last_modified                  = (known after apply)

      + memory_size                    = 1024

      + package_type                   = "Image"

      + publish                        = false

      + qualified_arn                  = (known after apply)

      + qualified_invoke_arn           = (known after apply)

      + reserved_concurrent_executions = -1

      + role                           = (known after apply)

      + signing_job_arn                = (known after apply)

      + signing_profile_version_arn    = (known after apply)

      + skip_destroy                   = false

      + source_code_hash               = (known after apply)

      + source_code_size               = (known after apply)

      + tags_all                       = (known after apply)

      + timeout                        = 30

      + version                        = (known after apply)



      + ephemeral_storage (known after apply)



      + logging_config (known after apply)



      + tracing_config (known after apply)

    }



  # docker_image.lambda_image will be created

  + resource "docker_image" "lambda_image" {

      + id          = (known after apply)

      + image_id    = (known after apply)

      + name        = (known after apply)

      + repo_digest = (known after apply)



      + build {

          + cache_from     = []

          + context        = "./../app"

          + dockerfile     = "Dockerfile"

          + extra_hosts    = []

          + platform       = "linux/amd64"

          + remove         = true

          + security_opt   = []

          + tag            = []

            # (12 unchanged attributes hidden)

        }

    }



  # docker_registry_image.lambda_image will be created

  + resource "docker_registry_image" "lambda_image" {

      + id                   = (known after apply)

      + insecure_skip_verify = false

      + keep_remotely        = true

      + name                 = (known after apply)

      + sha256_digest        = (known after apply)

    }



Plan: 7 to add, 0 to change, 0 to destroy.



Changes to Outputs:

  + ecr_repository_url = (known after apply)

  + lambda_name        = "churn-prediction"

aws_ecr_repository.lambda_repo: Creating...

aws_iam_role.lambda_role: Creating...

aws_ecr_repository.lambda_repo: Creation complete after 1s [id=churn-prediction-lambda]

aws_ecr_lifecycle_policy.cleanup: Creating...

docker_image.lambda_image: Creating...

aws_iam_role.lambda_role: Creation complete after 1s [id=churn-prediction-lambda-role]

aws_iam_role_policy_attachment.basic_logs: Creating...

aws_ecr_lifecycle_policy.cleanup: Creation complete after 1s [id=churn-prediction-lambda]

aws_iam_role_policy_attachment.basic_logs: Creation complete after 1s [id=churn-prediction-lambda-role-20260104184406582500000001]

docker_image.lambda_image: Still creating... [00m10s elapsed]

docker_image.lambda_image: Still creating... [00m20s elapsed]

docker_image.lambda_image: Still creating... [00m30s elapsed]

docker_image.lambda_image: Creation complete after 32s [id=sha256:c8c0790d688fa293b6d2806471ff3da2603e76b7f8f30eb1f7d69f27b4bf969c544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda:0f2bacac0942f7715c68395bc5249170ba3dd9ca68e4a85a148977ad654d069f]

docker_registry_image.lambda_image: Creating...

docker_registry_image.lambda_image: Still creating... [00m10s elapsed]

docker_registry_image.lambda_image: Still creating... [00m20s elapsed]

docker_registry_image.lambda_image: Still creating... [00m30s elapsed]

docker_registry_image.lambda_image: Still creating... [00m40s elapsed]

docker_registry_image.lambda_image: Still creating... [00m50s elapsed]

docker_registry_image.lambda_image: Still creating... [01m00s elapsed]

docker_registry_image.lambda_image: Still creating... [01m10s elapsed]

docker_registry_image.lambda_image: Creation complete after 1m17s [id=sha256:9bce8fc227d08878d336be1c28d18a40a472d1b8c9dceb024ffa55a2b2202d9b]

aws_lambda_function.churn_lambda: Creating...

aws_lambda_function.churn_lambda: Still creating... [00m10s elapsed]

aws_lambda_function.churn_lambda: Still creating... [00m20s elapsed]

aws_lambda_function.churn_lambda: Creation complete after 22s [id=churn-prediction]



Apply complete! Resources: 7 added, 0 changed, 0 destroyed.



Outputs:



ecr_repository_url = "544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda"

lambda_name = "churn-prediction"

Terraform destroy

!cd infra && \
    terraform destroy --auto-approve
data.aws_region.current: Reading...

data.aws_caller_identity.current: Reading...

data.aws_ecr_authorization_token.ecr: Reading...

aws_ecr_repository.lambda_repo: Refreshing state... [id=churn-prediction-lambda]

aws_iam_role.lambda_role: Refreshing state... [id=churn-prediction-lambda-role]

data.aws_region.current: Read complete after 0s [id=us-east-1]

data.aws_caller_identity.current: Read complete after 0s [id=544244312696]

data.aws_ecr_authorization_token.ecr: Read complete after 1s [id=us-east-1]

aws_ecr_lifecycle_policy.cleanup: Refreshing state... [id=churn-prediction-lambda]

aws_iam_role_policy_attachment.basic_logs: Refreshing state... [id=churn-prediction-lambda-role-20260104184406582500000001]

docker_image.lambda_image: Refreshing state... [id=sha256:c8c0790d688fa293b6d2806471ff3da2603e76b7f8f30eb1f7d69f27b4bf969c544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda:0f2bacac0942f7715c68395bc5249170ba3dd9ca68e4a85a148977ad654d069f]

docker_registry_image.lambda_image: Refreshing state... [id=sha256:9bce8fc227d08878d336be1c28d18a40a472d1b8c9dceb024ffa55a2b2202d9b]

aws_lambda_function.churn_lambda: Refreshing state... [id=churn-prediction]



Terraform used the selected providers to generate the following execution plan.

Resource actions are indicated with the following symbols:

  - destroy



Terraform will perform the following actions:



  # aws_ecr_lifecycle_policy.cleanup will be destroyed

  - resource "aws_ecr_lifecycle_policy" "cleanup" {

      - id          = "churn-prediction-lambda" -> null

      - policy      = jsonencode(

            {

              - rules = [

                  - {

                      - action       = {

                          - type = "expire"

                        }

                      - description  = "Keep last 2 images"

                      - rulePriority = 1

                      - selection    = {

                          - countNumber = 2

                          - countType   = "imageCountMoreThan"

                          - tagStatus   = "any"

                        }

                    },

                ]

            }

        ) -> null

      - registry_id = "544244312696" -> null

      - repository  = "churn-prediction-lambda" -> null

    }



  # aws_ecr_repository.lambda_repo will be destroyed

  - resource "aws_ecr_repository" "lambda_repo" {

      - arn                  = "arn:aws:ecr:us-east-1:544244312696:repository/churn-prediction-lambda" -> null

      - force_delete         = true -> null

      - id                   = "churn-prediction-lambda" -> null

      - image_tag_mutability = "MUTABLE" -> null

      - name                 = "churn-prediction-lambda" -> null

      - registry_id          = "544244312696" -> null

      - repository_url       = "544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda" -> null

      - tags                 = {} -> null

      - tags_all             = {} -> null



      - encryption_configuration {

          - encryption_type = "AES256" -> null

            # (1 unchanged attribute hidden)

        }



      - image_scanning_configuration {

          - scan_on_push = true -> null

        }

    }



  # aws_iam_role.lambda_role will be destroyed

  - resource "aws_iam_role" "lambda_role" {

      - arn                   = "arn:aws:iam::544244312696:role/churn-prediction-lambda-role" -> null

      - assume_role_policy    = jsonencode(

            {

              - Statement = [

                  - {

                      - Action    = "sts:AssumeRole"

                      - Effect    = "Allow"

                      - Principal = {

                          - Service = "lambda.amazonaws.com"

                        }

                    },

                ]

              - Version   = "2012-10-17"

            }

        ) -> null

      - create_date           = "2026-01-04T18:44:06Z" -> null

      - force_detach_policies = false -> null

      - id                    = "churn-prediction-lambda-role" -> null

      - managed_policy_arns   = [

          - "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",

        ] -> null

      - max_session_duration  = 3600 -> null

      - name                  = "churn-prediction-lambda-role" -> null

      - path                  = "/" -> null

      - tags                  = {} -> null

      - tags_all              = {} -> null

      - unique_id             = "AROAX5N35FJ4DHGOFYRAG" -> null

        # (3 unchanged attributes hidden)

    }



  # aws_iam_role_policy_attachment.basic_logs will be destroyed

  - resource "aws_iam_role_policy_attachment" "basic_logs" {

      - id         = "churn-prediction-lambda-role-20260104184406582500000001" -> null

      - policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" -> null

      - role       = "churn-prediction-lambda-role" -> null

    }



  # aws_lambda_function.churn_lambda will be destroyed

  - resource "aws_lambda_function" "churn_lambda" {

      - architectures                  = [

          - "x86_64",

        ] -> null

      - arn                            = "arn:aws:lambda:us-east-1:544244312696:function:churn-prediction" -> null

      - code_sha256                    = "9bce8fc227d08878d336be1c28d18a40a472d1b8c9dceb024ffa55a2b2202d9b" -> null

      - function_name                  = "churn-prediction" -> null

      - id                             = "churn-prediction" -> null

      - image_uri                      = "544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda:0f2bacac0942f7715c68395bc5249170ba3dd9ca68e4a85a148977ad654d069f" -> null

      - invoke_arn                     = "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:544244312696:function:churn-prediction/invocations" -> null

      - last_modified                  = "2026-01-04T18:45:59.721+0000" -> null

      - layers                         = [] -> null

      - memory_size                    = 1024 -> null

      - package_type                   = "Image" -> null

      - publish                        = false -> null

      - qualified_arn                  = "arn:aws:lambda:us-east-1:544244312696:function:churn-prediction:$LATEST" -> null

      - qualified_invoke_arn           = "arn:aws:apigateway:us-east-1:lambda:path/2015-03-31/functions/arn:aws:lambda:us-east-1:544244312696:function:churn-prediction:$LATEST/invocations" -> null

      - reserved_concurrent_executions = -1 -> null

      - role                           = "arn:aws:iam::544244312696:role/churn-prediction-lambda-role" -> null

      - skip_destroy                   = false -> null

      - source_code_size               = 0 -> null

      - tags                           = {} -> null

      - tags_all                       = {} -> null

      - timeout                        = 30 -> null

      - version                        = "$LATEST" -> null

        # (8 unchanged attributes hidden)



      - ephemeral_storage {

          - size = 512 -> null

        }



      - logging_config {

          - log_format            = "Text" -> null

          - log_group             = "/aws/lambda/churn-prediction" -> null

            # (2 unchanged attributes hidden)

        }



      - tracing_config {

          - mode = "PassThrough" -> null

        }

    }



  # docker_image.lambda_image will be destroyed

  - resource "docker_image" "lambda_image" {

      - id          = "sha256:c8c0790d688fa293b6d2806471ff3da2603e76b7f8f30eb1f7d69f27b4bf969c544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda:0f2bacac0942f7715c68395bc5249170ba3dd9ca68e4a85a148977ad654d069f" -> null

      - image_id    = "sha256:c8c0790d688fa293b6d2806471ff3da2603e76b7f8f30eb1f7d69f27b4bf969c" -> null

      - name        = "544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda:0f2bacac0942f7715c68395bc5249170ba3dd9ca68e4a85a148977ad654d069f" -> null

      - repo_digest = "544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda@sha256:9bce8fc227d08878d336be1c28d18a40a472d1b8c9dceb024ffa55a2b2202d9b" -> null



      - build {

          - build_args      = {} -> null

          - cache_from      = [] -> null

          - context         = "./../app" -> null

          - cpu_period      = 0 -> null

          - cpu_quota       = 0 -> null

          - cpu_shares      = 0 -> null

          - dockerfile      = "Dockerfile" -> null

          - extra_hosts     = [] -> null

          - force_remove    = false -> null

          - label           = {} -> null

          - labels          = {} -> null

          - memory          = 0 -> null

          - memory_swap     = 0 -> null

          - no_cache        = false -> null

          - platform        = "linux/amd64" -> null

          - pull_parent     = false -> null

          - remove          = true -> null

          - security_opt    = [] -> null

          - shm_size        = 0 -> null

          - squash          = false -> null

          - suppress_output = false -> null

          - tag             = [] -> null

            # (12 unchanged attributes hidden)

        }

    }



  # docker_registry_image.lambda_image will be destroyed

  - resource "docker_registry_image" "lambda_image" {

      - id                   = "sha256:9bce8fc227d08878d336be1c28d18a40a472d1b8c9dceb024ffa55a2b2202d9b" -> null

      - insecure_skip_verify = false -> null

      - keep_remotely        = true -> null

      - name                 = "544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda:0f2bacac0942f7715c68395bc5249170ba3dd9ca68e4a85a148977ad654d069f" -> null

      - sha256_digest        = "sha256:9bce8fc227d08878d336be1c28d18a40a472d1b8c9dceb024ffa55a2b2202d9b" -> null

    }



Plan: 0 to add, 0 to change, 7 to destroy.



Changes to Outputs:

  - ecr_repository_url = "544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda" -> null

  - lambda_name        = "churn-prediction" -> null

aws_ecr_lifecycle_policy.cleanup: Destroying... [id=churn-prediction-lambda]

aws_iam_role_policy_attachment.basic_logs: Destroying... [id=churn-prediction-lambda-role-20260104184406582500000001]

aws_lambda_function.churn_lambda: Destroying... [id=churn-prediction]

aws_lambda_function.churn_lambda: Destruction complete after 1s

docker_registry_image.lambda_image: Destroying... [id=sha256:9bce8fc227d08878d336be1c28d18a40a472d1b8c9dceb024ffa55a2b2202d9b]

docker_registry_image.lambda_image: Destruction complete after 0s

docker_image.lambda_image: Destroying... [id=sha256:c8c0790d688fa293b6d2806471ff3da2603e76b7f8f30eb1f7d69f27b4bf969c544244312696.dkr.ecr.us-east-1.amazonaws.com/churn-prediction-lambda:0f2bacac0942f7715c68395bc5249170ba3dd9ca68e4a85a148977ad654d069f]

aws_iam_role_policy_attachment.basic_logs: Destruction complete after 1s

aws_iam_role.lambda_role: Destroying... [id=churn-prediction-lambda-role]

aws_ecr_lifecycle_policy.cleanup: Destruction complete after 1s

docker_image.lambda_image: Destruction complete after 0s

aws_ecr_repository.lambda_repo: Destroying... [id=churn-prediction-lambda]

aws_ecr_repository.lambda_repo: Destruction complete after 0s

aws_iam_role.lambda_role: Destruction complete after 0s



Destroy complete! Resources: 7 destroyed.