# Task 045


create an aws_lex bot for ordering pizza with a followup question

## Intent

Has one resource "aws_lex_bot" and one resource "aws_lex_intent" with followup question block (slot block and "aws_lex_slot_type" is not mandatory)

## Reference Terraform solution

terraform {
  required_version = ">= 1.15.0"

  required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = "~> 6.0"
    }
  }
}

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


resource "aws_lex_bot" "pizza_order_bot" {
  name = "PizzaOrderBot"
  description = "Pizza order bot"
  idle_session_ttl_in_seconds = 600
  create_version = false
  child_directed = false

  abort_statement {
    message {
      content = "Sorry, I am not able to assist."
      content_type = "PlainText"
    }
  }

  clarification_prompt {
    max_attempts = 2
    message {
      content = "I'm sorry, I didn't understand that. Can you try again?"
      content_type = "PlainText"
    }
  }

  intent {
    intent_name = aws_lex_intent.OrderPizzaIntent.name
    intent_version = aws_lex_intent.OrderPizzaIntent.version
  }
}

resource "aws_lex_intent" "OrderPizzaIntent" {
  name = "OrderPizzaIntent"
  create_version = true

  sample_utterances = [
    "I would like to pick up a pizza",
    "I would like to order some pizzas",
  ]

  slot {
    name = "PizzaType"
    description = "Type of pizza to order"
    priority = 1  # must be in [1, 100]
    slot_type = aws_lex_slot_type.PizzaType.name
    slot_type_version = aws_lex_slot_type.PizzaType.version
    slot_constraint = "Required"

    sample_utterances = ["I want a {PizzaType} pizza.", "A {PizzaType} pizza please."]

    value_elicitation_prompt {
      max_attempts = 2
      message {
        content = "What type of pizza would you like to order?"
        content_type = "PlainText"
      }
    }
  }

  confirmation_prompt {
    max_attempts = 2
    message {
      content = "So, you would like to order a pizza. Is that correct?"
      content_type = "PlainText"
    }
  }

  rejection_statement {
    message {
        content = "Sorry, I don't know how to help then"
        content_type = "PlainText"
      }
    }

  follow_up_prompt {
    prompt {
      max_attempts = 2
      message {
        content = "Would you like anything else with your order?"
        content_type = "PlainText"
      }
    }
    rejection_statement {
      message {
        content = "OK, Your pizza is on its way."
        content_type = "PlainText"
      }
    }
  }

  fulfillment_activity {
    type = "ReturnIntent"
  }
}

resource "aws_lex_slot_type" "PizzaType" {
  create_version = true
  description = "Types of pizza available to order"
  name = "PizzaTypes"
  enumeration_value {
    value = "Margherita"
  }
  enumeration_value {
    value = "Pepperoni"
  }
}


## OPA Rego validation policy

package terraform.policy

import rego.v1

default has_valid_resources = false

# Rule for multiple aws_lex_intent resources
has_valid_lex_intents if {
    count([intent | intent := input.planned_values.root_module.resources[_]; intent.type == "aws_lex_intent"; intent.values.name; intent.values.fulfillment_activity; intent.values.follow_up_prompt; intent.values.conclusion_statement == false])
}

# Rule for aws_lex_bot resource with specific arguments
has_valid_lex_bot_instance if {
    some i
    resource := input.planned_values.root_module.resources[i]
    resource.type == "aws_lex_bot"
    is_boolean(resource.values.child_directed)
    resource.values.clarification_prompt
    resource.values.abort_statement
    resource.values.name
    # is_boolean(resource.values.create_version)
    # resource.values.description
    # is_boolean(resource.values.detect_sentiment)
    # resource.values.idle_session_ttl_in_seconds
    # resource.values.process_behavior
    # resource.values.voice_id
    # resource.values.locale
}

# Combined rule to ensure all conditions are met
has_valid_resources if {
    has_valid_lex_intents
    has_valid_lex_bot_instance
}

main if {
    has_valid_lex_intents
    has_valid_lex_bot_instance
    has_valid_resources
}