
An ECS deployment can be:
- EC2 - apps run in EC2 instance
- FARGATE - serverless (no EC2 instances)
So you wouldn't need to create or register EC2 Instances if you going with FARGATE. If you would like your ECS deployments to run on EC2 Instances, let's say you have the following files on your Terraform server.
├── ec2_instance.tf
├── iam_profile.tf
├── provider.tf
├── required_providers.tf
├── vpc_subnets.tf
required_providers.tf will almost always have this.
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
}
}
}
Let's say provider.tf has the following. In this example, the "default" profile in /home/username/.aws/config and /home/username/.aws/credentials is being used. This assumes you have setup Terraform as described in Amazon Web Services (AWS) - Getting Started with Terraform.
provider "aws" {
alias = "default"
profile = "default"
region = "default"
}
And iam_profile.tf could have something like this, to create an IAM Role named ecsInstanceRole that contains the Policy Documented required for the EC2 Instance to be registered in ECS, and to then create an IAM Profile that maps to the ecsInstanceRole.
data "aws_iam_policy" "AmazonEC2ContainerServiceforEC2Role_policy" {
name = "AmazonEC2ContainerServiceforEC2Role"
}
data "aws_iam_policy_document" "assume_role" {
statement {
effect = "Allow"
actions = [
"sts:AssumeRole"
]
principals {
type = "Service"
identifiers = [
"ec2.amazonaws.com"
]
}
}
}
resource "aws_iam_role" "ecsInstanceRole" {
name = "ecsInstanceRole"
assume_role_policy = data.aws_iam_policy_document.assume_role.json
managed_policy_arns = [data.aws_iam_policy.AmazonEC2ContainerServiceforEC2Role_policy.arn]
}
resource "aws_iam_instance_profile" "ecs-instance-profile" {
name = "ecs-instance-profile"
role = data.terraform_remote_state.iam_role.outputs.role_name
}
And subnets.tf could have the following,
data "aws_vpc" "default-vpc" {
filter {
name = "tag:Name"
values = ["default"]
}
}
data "aws_subnets" "subnets" {
filter {
name = "vpc-id"
values = [data.aws_vpc.default-vpc.id]
}
}
And instance.tf could have something like this to create an EC2 Instance using the most recent Amazon ECS Optimized Image
data "aws_ami" "most-recent-ecs-optimized-image" {
most_recent = true
filter {
name = "name"
values = ["amzn-ami*ecs-optimized"]
}
}
resource "aws_instance" "ecs-ec2-optimized-instance" {
ami = data.aws_ami.most-recent-ecs-optimized-image.id
instance_type = "t3.micro"
subnet_id = data.aws_subnets.subnets.ids[0]
iam_instance_profile = aws_iam_instance_profile.ecs-instance-profile.name
associate_public_ip_address = true
user_data = <<EOF
#!/bin/bash
echo ECS_CLUSTER=<your ECS cluster name must go here> >> /etc/ecs/ecs.config
EOF
tags = {
Name = "ecs-ec2-optimized-instance"
}
}
Issue the terraform init command to initialize Terraform.
terraform init
And then the terraform apply command to:
- Create the IAM Role named ecsInstanceRole
- Create the IAM Profile named ecs-instance-profile
- Create the EC2 Instance named ec2-optimized-instance
terraform apply
And then the aws ecs list-container-instances command can be used to list the EC2 Instances that have been registered in the cluster. In this example, there is one EC2 Instance registered in the ECS cluster.
~]$ aws ecs list-container-instances --cluster arn:aws:ecs:us-east-1:123456789012:cluster/my-ecs-cluster
{
"containerInstanceArns": [
"arn:aws:ecs:us-east-1:123456789012:container-instance/my-ecs-cluster/296c9008473948f89c8b2398c914bf0b"
]
}
And the EC2 instance should be listed in Container Instances in the ECS console.
Did you find this article helpful?
If so, consider buying me a coffee over at