resource "aws_iam_role" "predict_updater" { path = "/service-role/" name = "predict-updater" assume_role_policy = < 0 else sys.exit(1)" ] timeout = 20 interval = 120 startPeriod = 30 } command = [ "/root/.local/bin/gunicorn", "-b", "0.0.0.0:8000", "--workers=1", "--timeout=3", "--keep-alive=65", "--threads=20", "tawhiri.api:app" ] dependsOn = [ { containerName = "downloader" condition = "SUCCESS" }, { containerName = "ruaumoko-copy" condition = "SUCCESS" } ] cpu = 0 environment = [] essential = true image = "${data.aws_caller_identity.current.account_id}.dkr.ecr.us-east-1.amazonaws.com/tawhiri:latest" logConfiguration = { logDriver = "awslogs" options = { awslogs-group = "/ecs/tawhiri" awslogs-region = "us-east-1" awslogs-stream-prefix = "ecs" } } mountPoints = [ { containerPath = "/srv" sourceVolume = "ruaumoko" }, { containerPath = "/srv/tawhiri-datasets" sourceVolume = "downloader" } ] name = "tawhiri" portMappings = [ { containerPort = 8000 hostPort = 8000 protocol = "tcp" }, ] volumesFrom = [] }, { cpu = 0 environment = [ { name = "TZ" value = "UTC" } ] essential = false image = "${data.aws_caller_identity.current.account_id}.dkr.ecr.us-east-1.amazonaws.com/tawhiri-downloader:latest" logConfiguration = { logDriver = "awslogs" options = { awslogs-group = "/ecs/tawhiri" awslogs-region = "us-east-1" awslogs-stream-prefix = "ecs" } } mountPoints = [ { containerPath = "/srv/tawhiri-datasets" sourceVolume = "downloader" }, ] name = "downloader" volumesFrom = [] }, { cpu = 0 environment = [] essential = false image = "amazon/aws-cli" command = [ "s3", "cp", "s3://ruaumoko/ruaumoko-dataset", "/ruaumoko/ruaumoko-dataset" ] logConfiguration = { logDriver = "awslogs" options = { awslogs-group = "/ecs/tawhiri" awslogs-region = "us-east-1" awslogs-stream-prefix = "ecs" } } mountPoints = [ { containerPath = "/ruaumoko" sourceVolume = "ruaumoko" }, ] name = "ruaumoko-copy" volumesFrom = [] } ] ) cpu = "512" execution_role_arn = aws_iam_role.ecs_execution.arn memory = "1024" network_mode = "awsvpc" requires_compatibilities = [ "FARGATE", ] tags = {} task_role_arn = aws_iam_role.ecs_execution.arn volume { name = "downloader" } volume { name = "ruaumoko" } } resource "aws_ecr_repository" "tawhiri" { name = "tawhiri" image_tag_mutability = "MUTABLE" image_scanning_configuration { scan_on_push = true } } resource "aws_ecr_repository" "tawhiri_downloader" { name = "tawhiri-downloader" image_tag_mutability = "MUTABLE" image_scanning_configuration { scan_on_push = true } } resource "aws_ecs_cluster" "tawhiri" { name = "Tawhiri" capacity_providers = ["FARGATE", "FARGATE_SPOT"] } resource "aws_lb_target_group" "tawhiri" { name = "tawhiri" port = 8000 protocol = "HTTP" vpc_id = aws_vpc.main.id target_type = "ip" health_check { enabled = true healthy_threshold = 2 unhealthy_threshold = 10 interval = 20 matcher = "200" path = "/api/datasetcheck" port = "traffic-port" protocol = "HTTP" timeout = 12 } } resource "aws_ecs_service" "tawhiri" { name = "tawhiri" cluster = aws_ecs_cluster.tawhiri.id task_definition = aws_ecs_task_definition.tawhiri.arn enable_ecs_managed_tags = true health_check_grace_period_seconds = 600 iam_role = "aws-service-role" launch_type = "FARGATE" platform_version = "LATEST" desired_count = 1 enable_execute_command = true deployment_maximum_percent = 400 load_balancer { container_name = "tawhiri" container_port = 8000 target_group_arn = aws_lb_target_group.tawhiri.arn } lifecycle { ignore_changes = [desired_count, task_definition] } network_configuration { assign_public_ip = true security_groups = [ aws_security_group.tawhiri_efs.id, aws_security_group.tawhiri.id ] subnets = [aws_subnet.public["us-east-1b"].id] } } resource "aws_appautoscaling_target" "tawhiri" { service_namespace = "ecs" scalable_dimension = "ecs:service:DesiredCount" resource_id = "service/Tawhiri/tawhiri" min_capacity = 1 max_capacity = 7 } resource "aws_appautoscaling_policy" "tawhiri" { name = "cpu" service_namespace = aws_appautoscaling_target.tawhiri.service_namespace scalable_dimension = aws_appautoscaling_target.tawhiri.scalable_dimension resource_id = aws_appautoscaling_target.tawhiri.resource_id policy_type = "TargetTrackingScaling" target_tracking_scaling_policy_configuration { predefined_metric_specification { predefined_metric_type = "ECSServiceAverageCPUUtilization" } target_value = 75 scale_in_cooldown = 240 scale_out_cooldown = 240 } } resource "aws_security_group" "tawhiri_efs" { name = "tawhiri-efs" ingress = [ { from_port = 2049 to_port = 2049 protocol = "tcp" cidr_blocks = [] ipv6_cidr_blocks = [] description = "" prefix_list_ids = [] self = true security_groups = [aws_vpc.main.default_security_group_id] } ] egress = [ { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] ipv6_cidr_blocks = ["::/0"] description = "" prefix_list_ids = [] self = false security_groups = [] } ] vpc_id = aws_vpc.main.id lifecycle { ignore_changes = [description, name] } } resource "aws_security_group" "tawhiri" { name = "tawhiri" ingress = [ { from_port = 8000 to_port = 8000 protocol = "tcp" cidr_blocks = [] ipv6_cidr_blocks = [] description = "" prefix_list_ids = [] self = true security_groups = [aws_security_group.tawhiri_alb.id, aws_security_group.lb.id] } ] egress = [ { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] ipv6_cidr_blocks = ["::/0"] description = "" prefix_list_ids = [] self = false security_groups = [] } ] vpc_id = aws_vpc.main.id lifecycle { ignore_changes = [description, name] } } resource "aws_security_group" "tawhiri_alb" { name = "tawhiri-alb" egress = [ { from_port = 0 to_port = 0 protocol = "-1" cidr_blocks = ["0.0.0.0/0"] ipv6_cidr_blocks = ["::/0"] description = "" prefix_list_ids = [] self = false security_groups = [] } ] ingress = [ { from_port = 443 to_port = 443 protocol = "tcp" cidr_blocks = ["0.0.0.0/0"] ipv6_cidr_blocks = ["::/0"] description = "" prefix_list_ids = [] self = false security_groups = [] } ] vpc_id = aws_vpc.main.id lifecycle { ignore_changes = [description, name] } } resource "aws_route53_record" "tawhiri_A" { name = "tawhiri" type = "A" alias { name = "dualstack.${aws_lb.ws.dns_name}." zone_id = aws_lb.ws.zone_id evaluate_target_health = true } zone_id = aws_route53_zone.Route53HostedZone.zone_id } resource "aws_route53_record" "tawhiri_AAAA" { name = "tawhiri" type = "AAAA" alias { name = "dualstack.${aws_lb.ws.dns_name}." zone_id = aws_lb.ws.zone_id evaluate_target_health = true } zone_id = aws_route53_zone.Route53HostedZone.zone_id } resource "aws_iam_role" "predictor_update_trigger_lambda" { path = "/service-role/" assume_role_policy = <