ECS Service Deployer is a Golang application that helps you deploy AWS ECS services. It is designed to be used as an AWS Lambda function. While it is up to you how to use this Lambda function, a recommended use case is to invoke it from GitHub Actions CI/CD pipelines to automate your ECS service deployment process.
- Requirements
- Docker Images
- Getting Started
- Building the AWS Lambda Image
- Testing Lambda Locally
- Deployer CLI
- AWS Permissions
- Contributing
- License
- Motivation
- TODO
To use this Golang application for deploying AWS ECS services, you will need the following:
- Go 1.19+
- Docker (to build the ECR image)
- AWS CLI (to log in to Docker and push the image)
- AWS Account
- AWS ECR registry
Pre-built Docker images for the ECS Service Deployer are available on Docker Hub. Images are provided for both Linux amd64
and arm64
architectures.
To get started, clone the repository:
git clone https://github.com/falmar/ecs-service-deployer.git
cd ecs-service-deployer
You can build the AWS Lambda Docker image using the following command:
docker build -f ./build/lambda.Dockerfile -t <your-aws-ecr-registry-url>/ecs-service-deployer .
Replace with your own AWS ECR registry URL. This command will use the lambda.Dockerfile to build the Docker image.
To create a image for a different platform, follow the instructions in the Docker documentation.
You can test the application locally using Docker. The local.Dockerfile
is provided for this purpose.
- Build the local Docker image:
docker build -f ./build/local.Dockerfile -t <your-aws-ecr-registry-url>/ecs-service-deployer:local .
Replace <your-aws-ecr-registry-url>
with your own AWS ECR registry URL. This command will use the local.Dockerfile
to build the local Docker image.
- Run the local Docker container:
docker run --rm -it -p 9000:8080 -e DEBUG=1 -e AWS_LAMBDA_FUNCTION_MEMORY_SIZE=512 \
<your-aws-ecr-registry-url>/ecs-service-deployer:local
The application will be accessible at http://localhost:9000
. Make sure to set any required environment variables and configure your local AWS credentials for testing.
In addition to the Lambda function, you can also use the provided CLI to deploy your ECS services on demand. The CLI offers the same functionality as the Lambda function and can be executed locally.
To use the ECS Service Deployer CLI, run the following command:
$ go run ./cmd/standalone --service=<ECS_SERVICE> --cluster=<ECS_CLUSTER> --task=<ECS_TASK_FAMILY> --containers <CONTAINER_NAME>=<CONTAINER_IMAGE>
Replace <ECS_SERVICE>
, <ECS_CLUSTER>
, <ECS_TASK_FAMILY>
, <CONTAINER_NAME>
, and <CONTAINER_IMAGE>
with the appropriate values for your use case.
NOTE: You can also install the CLI on your system by running the following command:
$ go install .
Here's an example of how to use the CLI to deploy an ECS service:
$ go run ./cmd/standalone --service=ecs_deployer_test --cluster=ecs_deployer_test --task=ecs_deployer_test --containers test=nginx:alpine
This command will deploy the ecs_deployer_test
service on the ecs_deployer_test
cluster, using the ecs_deployer_test
task family and updating the container named test
with the nginx:alpine
image.
Make sure your AWS credentials and configuration are properly set up in your environment before using the CLI.
A Terraform template is provided in the ./terraform/ecs.tf file, which you can use to set up the required AWS resources for your ECS service. Make sure to customize the template according to your needs before using it.
$ terraform init
# change the service_count variable to the number of services you want to deploy or leave it as is to just create the resources
$ terraform apply --var service_count=0
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "SvcWrite",
"Effect": "Allow",
"Action": [
"ecs:UpdateService",
"ecs:DescribeServices"
],
"Resource": "arn:aws:ecs:<region>:<account>:service/<cluster>/<svc>",
"Condition": {
"ArnEquals": {
"ecs:cluster": "arn:aws:ecs:<region>:<account>:cluster/<cluster>"
},
"StringEqualsIfExists": {
"aws:ResourceTag/ECS_Deployer": "true"
}
}
},
{
"Sid": "TaskRead",
"Effect": "Allow",
"Action": [
"ecs:ListTaskDefinitions",
"ecs:DescribeTaskDefinition",
"ecs:DeregisterTaskDefinition"
],
"Resource": "*"
},
{
"Sid": "TaskWrite",
"Effect": "Allow",
"Action": [
"ecs:RegisterTaskDefinition"
],
"Resource": "*",
"Condition": {
"StringEqualsIfExists": {
"aws:ResourceTag/ECS_Deployer": "true"
}
}
}
]
}
Replace <region>
, <account>
, <cluster>
, <svc>
, and <TASK_FAMILY>
with the appropriate values for your use case.
"List, Describe and Deregister" for TaskDefinition doesn't allow conditions or resource level permissions see here, so they are allowed for all resources.
If you have suggestions or improvements, feel free to create a pull request or open an issue on the GitHub repository.
This project is licensed under the MIT License.
Why build my own ECS service deployer when there are already better tools and solutions out there? Well, the answer is simple: for the joy of learning by reinventing the wheel! This project was created to serve my own workflows. So, whether you're using this tool or just browsing the code, I hope you find it helpful or, at the very least, entertaining. Remember, there's never a wrong time to learn something new!
- Add which aws permissions are needed