A two-in-one DevOps toolkit:
deployagent— CLI tool to deploy any Dockerized app to AWS ECS with a single command- GitHub Repo Analyzer — AI-powered tool that clones, analyzes, and auto-fixes Kubernetes/Docker configs
Deploy any Dockerized project to AWS ECS Fargate with four commands: plan, apply, rollback, status.
Your project + deploy.yaml
↓
deployagent apply
↓
1. Builds Docker image
2. Pushes to ECR
3. Registers new ECS task definition
4. Updates ECS service
5. Applies CloudFormation changes (optional)
6. Waits for service stability
7. Runs health check
8. Saves deploy snapshot to SQLite (for rollback)
If the health check fails, it automatically rolls back to the last known-good state.
- Python 3.11+
- Docker Desktop (must be running during deploy)
- AWS account with IAM user credentials
- AWS CLI installed
# Clone the repo
git clone https://github.com/chiman45/Custom-CICD.git
cd Custom-CICD
# Install deployagent
pip install -e .
# Verify installation
deployagent --helpCreate a .env file in the project root (already gitignored):
AWS_ACCESS_KEY_ID=your_access_key_here
AWS_SECRET_ACCESS_KEY=your_secret_key_here
AWS_DEFAULT_REGION=us-east-1Or use the AWS CLI:
aws configureVerify credentials work:
aws sts get-caller-identityYour IAM user needs these permissions (attach in AWS Console → IAM → Users → your user → Add permissions):
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ecs:DescribeServices", "ecs:DescribeTaskDefinition",
"ecs:RegisterTaskDefinition", "ecs:UpdateService",
"ecr:GetAuthorizationToken", "ecr:BatchCheckLayerAvailability",
"ecr:PutImage", "ecr:InitiateLayerUpload",
"ecr:UploadLayerPart", "ecr:CompleteLayerUpload",
"ecr:DescribeImages", "ecr:DescribeRepositories",
"cloudformation:DescribeStacks", "cloudformation:CreateChangeSet",
"cloudformation:DescribeChangeSet", "cloudformation:ExecuteChangeSet",
"cloudformation:UpdateStack",
"logs:DescribeLogStreams", "logs:GetLogEvents",
"iam:PassRole"
],
"Resource": "*"
}
]
}Run these once before your first deploy:
# Get your AWS account ID
aws sts get-caller-identity --query Account --output text
# Create ECR repository (replace YOUR_ACCOUNT_ID)
aws ecr create-repository --repository-name my-app --region us-east-1
# Create ECS cluster
aws ecs create-cluster --cluster-name my-cluster --region us-east-1
# Create IAM execution role for ECS tasks
aws iam create-role \
--role-name ecsTaskExecutionRole \
--assume-role-policy-document '{"Version":"2012-10-17","Statement":[{"Effect":"Allow","Principal":{"Service":"ecs-tasks.amazonaws.com"},"Action":"sts:AssumeRole"}]}'
aws iam attach-role-policy \
--role-name ecsTaskExecutionRole \
--policy-arn arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy
# Get your default VPC and subnet
VPC=$(aws ec2 describe-vpcs --filters Name=isDefault,Values=true --query "Vpcs[0].VpcId" --output text)
SUBNET=$(aws ec2 describe-subnets --filters Name=vpc-id,Values=$VPC --query "Subnets[0].SubnetId" --output text)
SG=$(aws ec2 describe-security-groups --filters Name=vpc-id,Values=$VPC Name=group-name,Values=default --query "SecurityGroups[0].GroupId" --output text)
echo "VPC: $VPC | Subnet: $SUBNET | SG: $SG"
# Create CloudWatch log group
aws logs create-log-group --log-group-name /ecs/my-app-task --region us-east-1
# Register placeholder task definition (replace YOUR_ACCOUNT_ID)
aws ecs register-task-definition \
--family my-app-task \
--network-mode awsvpc \
--requires-compatibilities FARGATE \
--cpu 256 --memory 512 \
--execution-role-arn arn:aws:iam::YOUR_ACCOUNT_ID:role/ecsTaskExecutionRole \
--container-definitions '[{"name":"my-app","image":"YOUR_ACCOUNT_ID.dkr.ecr.us-east-1.amazonaws.com/my-app:latest","essential":true,"portMappings":[{"containerPort":8080,"protocol":"tcp"}],"logConfiguration":{"logDriver":"awslogs","options":{"awslogs-group":"/ecs/my-app-task","awslogs-region":"us-east-1","awslogs-stream-prefix":"ecs"}}}]'
# Create ECS service (replace SUBNET and SG with values from above)
aws ecs create-service \
--cluster my-cluster \
--service-name my-app-service \
--task-definition my-app-task \
--desired-count 1 \
--launch-type FARGATE \
--network-configuration "awsvpcConfiguration={subnets=[SUBNET],securityGroups=[SG],assignPublicIp=ENABLED}"Add a deploy.yaml to your project root:
service: my-app # label used for deploy history
region: us-east-1 # AWS region
cluster: my-cluster # ECS cluster name
image:
repository: 123456789.dkr.ecr.us-east-1.amazonaws.com/my-app # ECR repo URI
tag: latest # image tag — use git SHA for unique deploys
dockerfile: ./Dockerfile # path to your Dockerfile
build_context: . # Docker build context
ecs:
service_name: my-app-service # ECS service name
task_family: my-app-task # task definition family
container_name: my-app # container name inside task definition
container_port: 8080 # port your app listens on
cpu: 256 # 256 = 0.25 vCPU
memory: 512 # MB
desired_count: 1 # number of running containers
# Optional — remove if not using CloudFormation
cloudformation:
stack_name: my-app-infra
template_file: ./infra/template.yaml
parameters:
Environment: production
health:
endpoint: /health
timeout: 30
retries: 5Tip: Use git commit SHA as the tag so every deploy is unique and traceable:
# Linux/macOS
TAG=$(git rev-parse --short HEAD)
sed -i "s/tag: .*/tag: $TAG/" deploy.yaml
# Windows PowerShell
$TAG = git rev-parse --short HEAD
(Get-Content deploy.yaml) -replace 'tag: .*', "tag: $TAG" | Set-Content deploy.yamldeployagent plan deploy.yamlShows a colour-coded table of what will be created, updated, or left unchanged.
# With confirmation prompt
deployagent apply deploy.yaml
# Skip prompt (for CI/CD pipelines)
deployagent apply deploy.yaml --yes# Live health check
deployagent status deploy.yaml
# View full deploy history
deployagent status deploy.yaml --history# Revert to last successful deploy
deployagent rollback deploy.yaml
# Revert two deploys back
deployagent rollback deploy.yaml --steps 2# 1. Go to your project
cd /path/to/your-project
# 2. Copy deploy.yaml and fill in your AWS resource names
cp /path/to/Custom-CICD/deploy.yaml ./deploy.yaml
# 3. Tag with current commit
TAG=$(git rev-parse --short HEAD)
sed -i "s/tag: .*/tag: $TAG/" deploy.yaml # Linux/macOS
# 4. Preview changes
deployagent plan deploy.yaml
# 5. Deploy
deployagent apply deploy.yaml
# 6. Verify health
deployagent status deploy.yaml
# 7. If something goes wrong
deployagent rollback deploy.yamlAI-powered tool that clones any GitHub repository, analyzes Dockerfiles and Kubernetes manifests for errors, auto-fixes common issues, and commits the fixes to a new branch.
- Clones any public or private GitHub repository
- Builds a RAG (Retrieval-Augmented Generation) search index over the codebase
- Detects errors in Dockerfiles, docker-compose files, and Kubernetes YAML
- Auto-fixes common issues using pattern matching and local AI (Ollama)
- Generates a detailed
ANALYSIS_REPORT.md - Commits fixes and pushes to a new branch with a PR link
# Windows
winget install Ollama.Ollama
# macOS
brew install ollama
# Linux
curl -fsSL https://ollama.ai/install.sh | shPull the required models:
ollama pull llama3 # general analysis
ollama pull codellama # code and Dockerfile analysis
ollama pull mistral # fast scanningpip install -r requirements.txtGITHUB_TOKEN=ghp_your_github_personal_access_tokenCreate a GitHub token at: https://github.com/settings/tokens (needs repo scope)
python new.pyYou will be prompted for:
- GitHub repository URL (e.g.
https://github.com/username/my-project) - Whether to build and run Docker containers after analysis
- A branch name and commit message for the fixes
The tool will:
- Clone the repository
- Scan all Dockerfiles, YAML, and K8s manifests
- Report all issues with severity levels
- Auto-fix what it can
- Save an
ANALYSIS_REPORT.mdin the repo - Push fixes to your chosen branch
| Error | Fix |
|---|---|
docker: error during connect |
Start Docker Desktop |
AccessDeniedException on AWS |
Add missing IAM permissions (see AWS Setup section) |
Nothing to deploy in plan |
Change the image tag — same tag = no change detected |
Failed to connect to github.com port 443 |
Check internet connection, disable VPN |
cannot pull with rebase: You have unstaged changes |
Run git stash before git pull |
Ollama not available |
Run ollama serve then ollama pull llama3 |
Can't remove temp_repo (Windows) |
Run Remove-Item -Recurse -Force ./temp_repo |
- Fork the repository
- Create a feature branch:
git checkout -b feature/my-feature - Commit your changes:
git commit -m "Add my feature" - Push the branch:
git push origin feature/my-feature - Open a pull request
MIT License — free to use in personal and commercial projects.
Built by chiman45
Tools used:
- Typer — CLI framework
- boto3 — AWS SDK
- Rich — terminal output
- Ollama — local AI models
- LangChain — RAG implementation
- ChromaDB — vector storage
Email: chimanesda@gmail.com