I am trying to setup a batch compute environment following these tutorial
From JosephMin and Template MIME Handling
My main.tf looks like this
# https://medium.com/swlh/terraform-aws-batch-and-aws-efs-8682c112d742
# │ 135: "${aws_s3_bucket.results_s3.arn}",
variable "s3_arn" {
type = string
}
variable "ecr_repository_url" {
type = string
}
provider "aws" {
region = "ca-central-1"
}
# Security Setup
# Retrieves the default vpc for this region
data "aws_vpc" "default" {
default = true
}
# Retrieves the subnet ids in the default vpc
data "aws_subnet_ids" "all_default_subnets" {
vpc_id = data.aws_vpc.default.id
}
# IAM Role for batch processing
resource "aws_iam_role" "batch_role" {
name = "batch_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement":
[
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "batch.amazonaws.com"
}
}
]
}
EOF
tags = {
created-by = "terraform"
}
}
# Attach the Batch policy to the Batch role
resource "aws_iam_role_policy_attachment" "policy_attachment" {
role = aws_iam_role.batch_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AWSBatchServiceRole"
}
# Security Group for batch processing
resource "aws_security_group" "batch_security_group" {
name = "batch_security_group"
description = "AWS Batch Security Group for batch jobs"
vpc_id = data.aws_vpc.default.id
egress {
from_port = 0
to_port = 65535
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
tags = {
created-by = "terraform"
}
}
# IAM Role for underlying EC2 instances
resource "aws_iam_role" "ec2_role" {
name = "ec2_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
tags = {
created-by = "terraform"
}
}
# Assign the EC2 role to the EC2 profile
resource "aws_iam_instance_profile" "ec2_profile" {
name = "ec2_profile"
role = aws_iam_role.ec2_role.name
}
# Attach the EC2 container service policy to the EC2 role
resource "aws_iam_role_policy_attachment" "ec2_policy_attachment" {
role = aws_iam_role.ec2_role.name
policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role"
}
# IAM Role for jobs
resource "aws_iam_role" "job_role" {
name = "job_role"
assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement":
[
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"Service": "ecs-tasks.amazonaws.com"
}
}
]
}
EOF
tags = {
created-by = "terraform"
}
}
# S3 read/write policy
resource "aws_iam_policy" "s3_policy" {
name = "s3_policy"
policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:Get*",
"s3:List*",
"s3:Put*"
],
"Resource": [
"${var.s3_arn}",
"${var.s3_arn}/*"
]
}
]
}
EOF
}
# Attach the policy to the job role
resource "aws_iam_role_policy_attachment" "job_policy_attachment" {
role = aws_iam_role.job_role.name
policy_arn = aws_iam_policy.s3_policy.arn
}
resource "aws_security_group" "efs_security_group" {
name = "efs_security_group"
description = "Allow NFS traffic."
vpc_id = data.aws_vpc.default.id
lifecycle {
create_before_destroy = true
}
ingress {
from_port = "2049"
to_port = "2049"
protocol = "tcp"
security_groups = [aws_security_group.batch_security_group.id]
}
egress {
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
description = "No Outbound Restrictions"
}
}
# EFS for sharing protein databases
resource "aws_efs_file_system" "efs" {
creation_token = "efs"
performance_mode = "generalPurpose"
encrypted = "true"
}
resource "aws_efs_mount_target" "efs_mount_target" {
count = length(data.aws_subnet_ids.all_default_subnets.ids)
file_system_id = aws_efs_file_system.efs.id
subnet_id = element(tolist(data.aws_subnet_ids.all_default_subnets.ids), count.index)
security_groups = [
aws_security_group.efs_security_group.id,
aws_security_group.batch_security_group.id
]
}
resource "aws_launch_template" "launch_template" {
name = "launch_template"
update_default_version = true
user_data = base64encode(data.template_file.efs_template_file.rendered)
}
data "template_file" "efs_template_file" {
template = "${file("${path.module}/launch_template_user_data.tpl")}"
vars = {
efs_id = aws_efs_file_system.efs.id
efs_directory = "/mnt/efs"
}
}
resource "aws_batch_compute_environment" "batch_environment" {
compute_environment_name = "batch-environment2"
compute_resources {
instance_role = aws_iam_instance_profile.ec2_profile.arn
launch_template {
launch_template_id = aws_launch_template.launch_template.id
version = "$Latest"
}
instance_type = [
"optimal"
]
max_vcpus = 2
min_vcpus = 0
security_group_ids = [
aws_security_group.batch_security_group.id,
aws_security_group.efs_security_group.id
]
subnets = data.aws_subnet_ids.all_default_subnets.ids
type = "EC2"
}
service_role = aws_iam_role.batch_role.arn
type = "MANAGED"
tags = {
created-by = "terraform"
}
}
resource "aws_batch_job_queue" "job_queue" {
name = "job_queue"
state = "ENABLED"
priority = 1
compute_environments = [
aws_batch_compute_environment.batch_environment.arn
]
depends_on = [aws_batch_compute_environment.batch_environment]
tags = {
created-by = "terraform"
}
}
resource "aws_batch_job_definition" "job" {
name = "job"
type = "container"
parameters = {}
container_properties = <<CONTAINER_PROPERTIES
{
"image": "var.ecr_repository_url",
"jobRoleArn": "${aws_iam_role.job_role.arn}",
"vcpus": 2,
"memory": 1024,
"environment": [],
"volumes": [
{
"host": {
"sourcePath": "/mnt/efs"
},
"name": "efs"
}
],
"mountPoints": [
{
"containerPath": "/mnt/efs",
"sourceVolume": "efs",
"readOnly": false
}
],
"command": []
}
CONTAINER_PROPERTIES
tags = {
created-by = "terraform"
}
}
But I keep getting
Error: error waiting for Batch Compute Environment (batch-environment) disable: unexpected state 'INVALID', wanted target 'VALID'. last error: CLIENT_ERROR - Launch Template UserData is not MIME multipart format
My template file looks like this
MIME-Version: 1.0
Content-Type: multipart/mixed; boundary="==BOUNDARY=="
--==BOUNDARY==
Content-Type: text/cloud-boothook; charset="us-ascii"
#cloud-boothook
#!/bin/bash
cloud-init-per once docker_options echo 'OPTIONS="$${OPTIONS} --storage-opt dm.basesize=20G"' >> /etc/sysconfig/docker
--==BOUNDARY==
Content-Type: text/cloud-config; charset="us-ascii"
packages:
- amazon-efs-utils
runcmd:
- mkdir -p ${efs_directory}
- echo "${efs_id}:/ ${efs_directory} efs _netdev,tls,iam 0 0" >> /etc/fstab
- mount -a -t efs defaults
--==BOUNDARY==--
Any suggestions on where I have made mistakes ?
Cheers