How do I use Flux with Amazon ECS?
Introduction
In this guide, we are going to integrate Flux with Amazon ECS to automate and manage our application deployments. Flux is a GitOps tool that synchronizes your desired state stored in Git with your actual state running in Kubernetes or other container orchestration systems. Amazon ECS (Elastic Container Service) is a fully managed container orchestration service provided by AWS.
By the end of this guide, you will have a setup where Flux continuously monitors your Git repository for changes and automatically deploys these changes to your ECS cluster.
Key Components in this Guide
- VPC - To provide a secured network environment.
- ECS Cluster - To host and manage our containerized applications.
- IAM Roles - To grant necessary permissions to ECS tasks and services.
Detailed Explanation
The following code block achieves our goal by performing the following steps:
- Create a VPC.
- Create an ECS cluster.
- Set up IAM roles for ECS tasks and services.
- Deploy an ECS service using a task definition that integrates Flux for GitOps.
import * as pulumi from "@pulumi/pulumi";
import * as aws from "@pulumi/aws";
import * as std from "@pulumi/std";
const main = new aws.ec2.Vpc("main", {cidrBlock: "10.0.0.0/16"});
const available = aws.getAvailabilityZonesOutput({});
const subnets: aws.ec2.Subnet[] = [];
for (const range = {value: 0}; range.value < 2; range.value++) {
subnets.push(new aws.ec2.Subnet(`subnets-${range.value}`, {
vpcId: main.id,
cidrBlock: std.cidrsubnetOutput({
input: main.cidrBlock,
newbits: 8,
netnum: range.value,
}).apply(invoke => invoke.result),
availabilityZone: available.apply(available => available.names[range.value]),
}));
}
const mainCluster = new aws.ecs.Cluster("main", {name: "my-cluster"});
const ecsTaskRole = new aws.iam.Role("ecs_task_role", {
name: "ecs_task_role",
assumeRolePolicy: JSON.stringify({
Version: "2012-10-17",
Statement: [{
Effect: "Allow",
Principal: {
Service: "ecs-tasks.amazonaws.com",
},
Action: "sts:AssumeRole",
}],
}),
});
const ecsTaskPolicy = new aws.iam.RolePolicy("ecs_task_policy", {
name: "ecs_task_policy",
role: ecsTaskRole.id,
policy: JSON.stringify({
Version: "2012-10-17",
Statement: [{
Effect: "Allow",
Action: [
"ecr:GetAuthorizationToken",
"ecr:BatchCheckLayerAvailability",
"ecr:GetDownloadUrlForLayer",
"ecr:BatchGetImage",
"logs:CreateLogStream",
"logs:PutLogEvents",
],
Resource: "*",
}],
}),
});
const mainTaskDefinition = new aws.ecs.TaskDefinition("main", {
family: "flux-task",
networkMode: "awsvpc",
requiresCompatibilities: ["FARGATE"],
cpu: "256",
memory: "512",
executionRoleArn: ecsTaskRole.arn,
taskRoleArn: ecsTaskRole.arn,
containerDefinitions: JSON.stringify([{
name: "flux",
image: "fluxcd/flux:latest",
cpu: 256,
memory: 512,
essential: true,
environment: [
{
name: "GIT_URL",
value: "https://github.com/your-org/your-repo",
},
{
name: "GIT_BRANCH",
value: "main",
},
],
logConfiguration: {
logDriver: "awslogs",
options: {
"awslogs-group": "/ecs/flux",
"awslogs-region": "us-west-2",
"awslogs-stream-prefix": "ecs",
},
},
}]),
});
const mainSecurityGroup = new aws.ec2.SecurityGroup("main", {
name: "ecs-security-group",
description: "Allow all inbound traffic",
vpcId: main.id,
ingress: [{
fromPort: 0,
toPort: 0,
protocol: "-1",
cidrBlocks: ["0.0.0.0/0"],
}],
egress: [{
fromPort: 0,
toPort: 0,
protocol: "-1",
cidrBlocks: ["0.0.0.0/0"],
}],
});
const mainService = new aws.ecs.Service("main", {
name: "flux-service",
cluster: mainCluster.id,
taskDefinition: mainTaskDefinition.arn,
desiredCount: 1,
launchType: "FARGATE",
networkConfiguration: {
subnets: subnets.map(__item => __item.id),
securityGroups: [mainSecurityGroup.id],
assignPublicIp: true,
},
});
export const ecsClusterId = mainCluster.id;
export const ecsServiceId = mainService.id;
export const vpcId = main.id;
Key Points
- Created a VPC to host the ECS cluster.
- Set up an ECS cluster to manage our containerized services.
- Configured IAM roles to provide necessary permissions to ECS tasks.
- Deployed an ECS service that runs Flux, to synchronize with a Git repository.
Summary
In this guide, we successfully set up an Amazon ECS cluster with a service that runs Flux. Flux helps automate the deployment process by continuously monitoring and synchronizing the desired state defined in your Git repository with the actual state of your ECS services. This integration leverages the power of GitOps to maintain consistency and reliability in your application deployments.
Deploy this code
Want to deploy this code? Sign up for a free Pulumi account to deploy in a few clicks.
Sign upNew to Pulumi?
Want to deploy this code? Sign up with Pulumi to deploy in a few clicks.
Sign upThank you for your feedback!
If you have a question about how to use Pulumi, reach out in Community Slack.
Open an issue on GitHub to report a problem or suggest an improvement.