This article describes how you can set up Amazon’s EC2 Container Service (ECS) with only a single instance. ECS lets you run applications packaged in Docker containers on a managed cluster of EC2 instances.
Single Instance & Cluster?
The word “cluster” implies having multiple instances, so why would you want to have a single instance? Your application or service might not have high traffic load. In the world of microservices that can easily be the case. One instance is enough.
I strongly recommend using ECS if your application, or even parts of it, is running on Docker. Unlike an EC2 instance where you set up Docker yourself, ECS gives you an API and the ability to program your infrastructure. And since this is a single instance you do not have to pay for the AutoScaler or LoadBalancer.
People far smarter than me have said it many times: all regular tasks in the production environment must be automated. As with any other application code, you should also put it under version control.
Requirements
You require valid AWS account credentials and the AWS CLI before you can set up an ECS instance. If you haven’t installed it, you can easily run it with Docker by:
docker run -it --rm \ -e AWS_ACCESS_KEY_ID=[ACCESS_KEY_ID] \ -e AWS_SECRET_ACCESS_KEY=[SECRET_ACCESS_KEY] \ -e AWS_DEFAULT_REGION=eu-central-1 \ fstab/aws-cli
That’s quite handy and I advise you to put it as an alias in your ~/.bashrc.
Commands to set up and run
You should find yourself now within the aws cli and can boot up a Grafana instance using the following:
aws ecs create-cluster --cluster-name single-cluster aws iam create-role --role-name ecsRole --assume-role-policy-document \ '{"Version": "2012-10-17", "Statement": { "Effect": "Allow", "Principal": {"Service": "ec2.amazonaws.com"}, "Action": "sts:AssumeRole"}}' aws iam attach-role-policy --role-name ecsRole --policy-arn \ "arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role" aws iam create-instance-profile --instance-profile-name ecsInstanceProfile aws iam add-role-to-instance-profile --instance-profile-name ecsInstanceProfile \ --role-name ecsRole sleep 5 #https://github.com/hashicorp/terraform/issues/1885 taskDefinition=`aws ecs register-task-definition --family grafanaTasks \ --query taskDefinition.taskDefinitionArn --output text --container-definitions \ '[{ "name": "grafana", "image": "grafana/grafana", "memoryReservation": 256, "portMappings": [{"containerPort": 3000, "hostPort": 80}]}]'` securityGroup=`aws ec2 create-security-group --group-name grafana \ --description "Security Group for Grafana" --query GroupId --output text` aws ec2 authorize-security-group-ingress --group-id $securityGroup \ --protocol tcp --port 80 --cidr 0.0.0.0/0 instanceId=`aws ec2 run-instances --security-groups grafana \ --image-id ami-ec2be583 \ --iam-instance-profile "Name=ecsInstanceProfile" --user-data ' #!/bin/bash echo ECS_CLUSTER=single-cluster >> /etc/ecs/ecs.config' \ --query "Instances[0].InstanceId" --output text` aws ec2 wait instance-status-ok --instance-ids $instanceId aws ecs create-service --cluster single-cluster \ --service-name grafanaService \ --task-definition grafanaTasks --desired-count 1
Please note the "sleep 5" command. It is required since there seem to be some asynchronous processes in place.
Accessing the instance
By now Grafana should be up and running. You have created an ECS cluster called "single-cluster" along an IAM policy that allows EC2 instances to register themselves to the cluster. The Grafana container is registered as a task and the cluster has a service that runs that task.
You can request the public DNS of the instance by:
aws ec2 describe-instances --instance-ids $instanceId \ --query Reservations[0].Instances[0].PublicDnsName --output text
Commands to clean up
To remove everything you’ve setup before, simply run the following commands within the AWS CLI:
containerInstanceId=`aws ecs list-container-instances \ --cluster single-cluster --query containerInstanceArns[0] \ --output text` instanceId=`aws ecs describe-container-instances \ --cluster single-cluster \ --container-instances $containerInstanceId \ --query containerInstances[0].ec2InstanceId --output text` aws ec2 terminate-instances --instance-ids $instanceId aws ec2 wait instance-terminated --instance-ids $instanceId aws ec2 delete-security-group --group-name grafana aws ecs update-service --cluster single-cluster --service grafanaService --desired-count 0 aws ecs delete-service --cluster single-cluster --service grafanaService aws ecs delete-cluster --cluster single-cluster aws iam remove-role-from-instance-profile --instance-profile ecsInstanceProfile \ --role-name ecsRole aws iam delete-instance-profile --instance-profile-name ecsInstanceProfile aws iam detach-role-policy --role-name ecsRole \ --policy-arn arn:aws:iam::aws:policy/service-role/AmazonEC2ContainerServiceforEC2Role aws iam delete-role --role-name ecsRole taskDefinitions=`aws ecs list-task-definitions --output text --query taskDefinitionArns[0]` aws ecs deregister-task-definition --task-definition $taskDefinition