# get default vpc
data "aws_vpc" "default" {
default = true
}
# get all the subnets
data "aws_subnets" "all" {
filter {
name = "vpc-id"
values = [data.aws_vpc.default.id]
}
}
# role that the instance could assume
resource "aws_iam_role" "ecs_instance_role" {
name = "ecs_instance_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ec2.amazonaws.com"
}
}
]
}
EOF
}
# attach a managed policy to the role
resource "aws_iam_role_policy_attachment" "ecs_instance_role" {
role = aws_iam_role.ecs_instance_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
}
# create an instance profile from the role
resource "aws_iam_instance_profile" "ecs_instance_role" {
name = "ecs_instance_role"
role = aws_iam_role.ecs_instance_role.name
}
# create role for the batch service to assume
resource "aws_iam_role" "aws_batch_service_role" {
name = "aws_batch_service_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "batch.amazonaws.com"
}
}
]
}
EOF
}
# attach a managed policy to the batch role
resource "aws_iam_role_policy_attachment" "aws_batch_service_role" {
role = aws_iam_role.aws_batch_service_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBatchServiceRole"
}
# ec2 instances need to have a security group
resource "aws_security_group" "sg" {
name = "aws_batch_compute_environment_security_group"
# open up egress
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
}
# create batch compute environment
resource "aws_batch_compute_environment" "ce" {
compute_environment_name = "batch-ce"
compute_resources {
instance_role = aws_iam_instance_profile.ecs_instance_role.arn
subnets = data.aws_subnets.all.ids
instance_type = ["optimal"]
max_vcpus = 3
min_vcpus = 0
bid_percentage = 100
security_group_ids = [
aws_security_group.sg.id,
]
type = "SPOT"
allocation_strategy = "BEST_FIT"
# needs to be created first
# check out https://docs.aws.amazon.com/batch/latest/userguide/spot_fleet_IAM_role.html
spot_iam_fleet_role = "arn:aws:iam::690521436457:role/AmazonEC2SpotFleetTaggingRole"
}
type = "MANAGED"
service_role = aws_iam_role.aws_batch_service_role.arn
depends_on = [aws_iam_role_policy_attachment.aws_batch_service_role]
}
# create batch job definition
resource "aws_batch_job_definition" "jd" {
name = "batch-jd"
type = "container"
container_properties = <<CONTAINER_PROPERTIES
{
"image": "${aws_ecr_repository.my_awesome_repo.repository_url}:latest",
"resourceRequirements": [
{"type": "VCPU", "value": "1"},
{"type": "MEMORY", "value": "1024"}
]
}
CONTAINER_PROPERTIES
}
# create ecr repo to push docker image too
resource "aws_ecr_repository" "repo" {
name = "my-awesome-repo"
}
# create batch job queue
resource "aws_batch_job_queue" "queue" {
name = "job-queue"
state = "ENABLED"
priority = 1
compute_environments = [
aws_batch_compute_environment.ce.arn,
]
}
# create event rule to run the batch job
resource "aws_cloudwatch_event_rule" "sample" {
name = "sample"
description = "Sample Batch Job"
schedule_expression = "rate(10 minutes)"
}
# create target for the event rule
resource "aws_cloudwatch_event_target" "target" {
rule = aws_cloudwatch_event_rule.sample.name
target_id = "to-batch"
arn = aws_batch_job_queue.queue.arn
role_arn = aws_iam_role.eb_role.arn
batch_target {
job_definition = aws_batch_job_definition.jd.arn
job_name = "schedule"
job_attempts = 1
}
depends_on = [
aws_iam_role_policy_attachment.eb_attachment
]
}
# create role for eventbridge to assume
resource "aws_iam_role" "eb_role" {
name = "eb_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Service": "events.amazonaws.com"
},
"Action": "sts:AssumeRole"
}
]
}
EOF
}
# create policy for event eventbridge role
resource "aws_iam_policy" "policy" {
name = "eb_policy"
description = "eb_policy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"batch:SubmitJob",
]
Effect = "Allow"
Resource = "*"
},
]
})
}
# attach policy to role
resource "aws_iam_role_policy_attachment" "eb_attachment" {
role = aws_iam_role.eb_role.name
policy_arn = aws_iam_policy.policy.arn
}