# Terraform configuration to deploy a simple Python web application to AWS Elastic Beanstalk.

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

# --- 1. Create Source Bundle ---
# Create a local directory for the application
resource "null_resource" "app_dir" {
  provisioner "local-exec" {
    command = "mkdir -p webapp"
  }
  provisioner "local-exec" {
    command = "echo 'from flask import Flask\napplication = Flask(__name__)\n\n@application.route(\'/\')\ndef hello_world():\n    return \'Hello, World from Elastic Beanstalk Terraform!\'

if __name__ == \'__main__\':\n    application.run(debug=True)' > webapp/application.py"
  }
  provisioner "local-exec" {
    command = "echo 'Flask==2.0.2' > webapp/requirements.txt"
  }
  provisioner "local-exec" {
    command = "mkdir -p webapp/.ebextensions"
  }
  provisioner "local-exec" {
    command = "echo 'option_settings:\n  aws:elasticbeanstalk:container:python:\n    WSGIPath: application.py' > webapp/.ebextensions/python.config"
  }
}

# Archive the application files into a zip file
data "archive_file" "webapp_zip" {
  type        = "zip"
  source_dir  = "webapp"
  output_path = "webapp.zip"
  depends_on  = [null_resource.app_dir]
}

# --- 2. Elastic Beanstalk Application ---
resource "aws_elastic_beanstalk_application" "my_app" {
  name        = "MyTerraformWebApp"
  description = "My Terraform Python Web App"
}

# --- 3. Application Version ---
# S3 bucket for Elastic Beanstalk application versions
resource "aws_s3_bucket" "eb_bucket" {
  bucket = "elasticbeanstalk-${var.aws_region}-${data.aws_caller_identity.current.account_id}"
  acl    = "private" # Best practice
  force_destroy = true # For easy cleanup in demo
}

resource "aws_s3_bucket_versioning" "eb_bucket_versioning" {
  bucket = aws_s3_bucket.eb_bucket.id
  versioning_configuration {
    status = "Enabled"
  }
}

resource "aws_s3_object" "app_source_bundle" {
  bucket       = aws_s3_bucket.eb_bucket.id
  key          = data.archive_file.webapp_zip.output_file_md5
  source       = data.archive_file.webapp_zip.output_path
  etag         = filemd5(data.archive_file.webapp_zip.output_path)
  content_type = "application/zip"
  depends_on   = [aws_s3_bucket_versioning.eb_bucket_versioning]
}

resource "aws_elastic_beanstalk_application_version" "my_app_version" {
  name        = "v1"
  application = aws_elastic_beanstalk_application.my_app.name
  description = "Initial application version"
  bucket      = aws_s3_bucket.eb_bucket.id
  key         = aws_s3_object.app_source_bundle.key
  depends_on  = [aws_s3_object.app_source_bundle]
}

# --- 4. Elastic Beanstalk Environment ---
resource "aws_elastic_beanstalk_environment" "my_env" {
  name                = "my-terraform-webapp-env"
  application         = aws_elastic_beanstalk_application.my_app.name
  solution_stack_name = "64bit Amazon Linux 2 v3.9.1 running Python 3.9" # Check AWS docs for latest
  version_label       = aws_elastic_beanstalk_application_version.my_app_version.name

  setting {
    namespace = "aws:autoscaling:launchconfiguration"
    name      = "InstanceType"
    value     = "t2.micro"
  }
  setting {
    namespace = "aws:autoscaling:asg"
    name      = "MinSize"
    value     = "1"
  }
  setting {
    namespace = "aws:autoscaling:asg"
    name      = "MaxSize"
    value     = "1"
  }
  setting {
    namespace = "aws:elasticbeanstalk:environment"
    name      = "EnvironmentType"
    value     = "SingleInstance" # For demo, use SingleInstance
  }

  depends_on = [aws_elastic_beanstalk_application_version.my_app_version]
}

# --- Outputs ---
output "environment_url" {
  value       = aws_elastic_beanstalk_environment.my_env.cname
  description = "The URL of the deployed Elastic Beanstalk application."
}

output "application_name" {
  value       = aws_elastic_beanstalk_application.my_app.name
  description = "The name of the Elastic Beanstalk application."
}

# Data sources for dynamic bucket name
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
variable "aws_region" {
  default = "us-east-1"
}
