Setup CI/CD for AWS Deployer
This skill automates the setup of CI/CD for projects that will be deployed using AWS Deployer.
Overview
You will help set up a complete CI/CD pipeline that:
- •Auto-detects the project's programming language
- •Creates or validates CloudFormation templates
- •Generates GitHub Actions workflows
- •Configures AWS authentication and S3 artifact uploads
Step 1: Detect Project Language
Check for the following files to determine the project language:
- •Go:
go.mod,main.go, or*.gofiles - •Rust:
Cargo.toml,Cargo.lock, or*.rsfiles - •Node.js/TypeScript:
package.json,tsconfig.json - •Python:
requirements.txt,setup.py,pyproject.toml
If multiple languages are detected, ask the user which is the primary language for deployment.
Step 2: Determine Deployment Mode
Ask the user: "Is this for single-account or multi-account deployment?"
- •Single-account: Deploys CloudFormation stacks directly to a single AWS account. Requires
Envparameter. - •Multi-account: Deploys via CloudFormation StackSets across multiple accounts/regions. Does NOT use
Envparameter.
Store this choice as it affects subsequent steps.
Step 3: Gather Configuration
Collect the following information from environment variables or by prompting the user:
- •
S3_ARTIFACT_BUCKET: The S3 bucket for storing build artifacts
- •Try:
echo $S3_ARTIFACT_BUCKETor check GitHub secrets - •If not found, prompt: "What is your S3 artifacts bucket name?"
- •Try:
- •
ENV (single-account mode only): The environment name (dev, staging, prod)
- •Try:
echo $ENV - •If not found, prompt: "What environment is this for? (dev/staging/prod)"
- •Try:
- •
Repository info:
- •Owner and repo name for GitHub OIDC setup (e.g., "owner/repo")
- •Derive from:
git remote get-url originor prompt user
Step 4: Check/Create CloudFormation Template
Check for existing template
Look for cloudformation.template in the project root.
If template exists:
Verify it has the required parameters:
- •
Version(Type: String) - Build version - •
S3Bucket(Type: String) - S3 bucket name - •
S3Prefix(Type: String) - S3 path prefix - •
Env(Type: String) - Only for single-account mode
If any are missing, add them to the Parameters section while preserving existing content.
If template does NOT exist:
Create a minimal CloudFormation template with the required parameters based on deployment mode:
For single-account mode:
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Application deployment via AWS Deployer'
Parameters:
Env:
Type: String
Description: Environment name (dev, staging, prod)
Version:
Type: String
Description: Build version (e.g., 123.abc456)
S3Bucket:
Type: String
Description: S3 bucket containing build artifacts
S3Prefix:
Type: String
Description: S3 key prefix for artifacts (e.g., myapp/main/123.abc456/)
Resources:
# Add your AWS resources here
PlaceholderResource:
Type: AWS::CloudFormation::WaitConditionHandle
For multi-account mode:
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Application deployment via AWS Deployer (multi-account)'
Parameters:
Version:
Type: String
Description: Build version (e.g., 123.abc456)
S3Bucket:
Type: String
Description: S3 bucket containing build artifacts
S3Prefix:
Type: String
Description: S3 key prefix for artifacts (e.g., myapp/main/123.abc456/)
Resources:
# Add your AWS resources here
PlaceholderResource:
Type: AWS::CloudFormation::WaitConditionHandle
Inform the user they'll need to add actual AWS resources to the template.
Step 5: Generate GitHub Actions Workflow
Create .github/workflows/deploy.yml with the following structure:
Language-specific build steps:
Go:
- name: Build Go binaries
run: |
GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -ldflags="-s -w" -o build/bootstrap .
cd build && zip -r ../app.zip .
Rust:
- name: Install Rust toolchain
uses: actions-rs/toolchain@v1
with:
toolchain: stable
target: x86_64-unknown-linux-musl
- name: Build Rust binary
run: |
cargo build --release --target x86_64-unknown-linux-musl
mkdir -p build
cp target/x86_64-unknown-linux-musl/release/bootstrap build/
cd build && zip -r ../app.zip .
Node.js/TypeScript:
- name: Install dependencies
run: npm ci
- name: Build application
run: npm run build
- name: Package application
run: |
mkdir -p build
cp -r dist/* build/
cp package.json package-lock.json build/
cd build && npm ci --production && zip -r ../app.zip .
Python:
- name: Install dependencies
run: |
pip install -r requirements.txt -t build/
cp -r *.py build/
- name: Package application
run: cd build && zip -r ../app.zip .
Complete workflow template:
name: Deploy to AWS
on:
push:
branches:
- main
- develop
env:
S3_ARTIFACT_BUCKET: ${{ secrets.S3_ARTIFACT_BUCKET }}
AWS_REGION: us-east-1
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v2
with:
role-to-assume: ${{ secrets.AWS_ROLE_ARN }}
aws-region: ${{ env.AWS_REGION }}
# [INSERT LANGUAGE-SPECIFIC BUILD STEPS HERE]
- name: Generate version
id: version
run: |
VERSION="${{ github.run_number }}.${GITHUB_SHA:0:6}"
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"
- name: Get repository name
id: repo
run: |
REPO_NAME=$(basename $(git rev-parse --show-toplevel))
echo "name=$REPO_NAME" >> $GITHUB_OUTPUT
echo "Repository: $REPO_NAME"
- name: Generate CloudFormation parameters
run: |
BRANCH_NAME=${GITHUB_REF#refs/heads/}
S3_PREFIX="${{ steps.repo.outputs.name }}/${BRANCH_NAME}/${{ steps.version.outputs.version }}"
cat > cloudformation-params.json <<EOF
{
"Parameters": {
"Version": "${{ steps.version.outputs.version }}",
"S3Bucket": "${{ env.S3_ARTIFACT_BUCKET }}",
"S3Prefix": "${S3_PREFIX}/"
}
}
EOF
cat cloudformation-params.json
- name: Upload artifacts to S3
run: |
BRANCH_NAME=${GITHUB_REF#refs/heads/}
S3_PATH="s3://${{ env.S3_ARTIFACT_BUCKET }}/${{ steps.repo.outputs.name }}/${BRANCH_NAME}/${{ steps.version.outputs.version }}"
# Upload application artifacts (all .zip files)
aws s3 cp app.zip "$S3_PATH/" --region ${{ env.AWS_REGION }}
# Upload CloudFormation template
aws s3 cp cloudformation.template "$S3_PATH/" --region ${{ env.AWS_REGION }}
# Upload CloudFormation parameters (this triggers deployment)
aws s3 cp cloudformation-params.json "$S3_PATH/" --region ${{ env.AWS_REGION }}
echo "Deployed to: $S3_PATH"
For single-account mode, add the Env parameter to cloudformation-params.json:
- name: Generate CloudFormation parameters
run: |
BRANCH_NAME=${GITHUB_REF#refs/heads/}
S3_PREFIX="${{ steps.repo.outputs.name }}/${BRANCH_NAME}/${{ steps.version.outputs.version }}"
# Determine environment from branch
if [ "$BRANCH_NAME" = "main" ]; then
ENV="prod"
elif [ "$BRANCH_NAME" = "staging" ]; then
ENV="staging"
else
ENV="dev"
fi
cat > cloudformation-params.json <<EOF
{
"Parameters": {
"Env": "$ENV",
"Version": "${{ steps.version.outputs.version }}",
"S3Bucket": "${{ env.S3_ARTIFACT_BUCKET }}",
"S3Prefix": "${S3_PREFIX}/"
}
}
EOF
cat cloudformation-params.json
Step 6: AWS IAM Setup Instructions
Inform the user they need to set up AWS IAM roles for GitHub Actions OIDC authentication:
# Run from the aws-deployer repository root: go run ./cmd/aws-deployer github \ --repo OWNER/REPOSITORY \ --bucket S3_ARTIFACT_BUCKET \ --github-token-secret github/pat-token
Replace:
- •
OWNER/REPOSITORYwith their GitHub repo (e.g., "myorg/myapp") - •
S3_ARTIFACT_BUCKETwith their S3 bucket name - •
github/pat-tokenwith the Secrets Manager secret containing their GitHub PAT
This command will:
- •Create an IAM role for GitHub OIDC authentication
- •Grant the role permissions to upload to S3
- •Output the role ARN to add as
AWS_ROLE_ARNGitHub secret
Step 7: Configure GitHub Secrets
Instruct the user to add these secrets to their GitHub repository (Settings → Secrets and variables → Actions):
Required:
- •
AWS_ROLE_ARN: The IAM role ARN from theaws-deployer githubcommand - •
S3_ARTIFACT_BUCKET: The S3 bucket name for artifacts
Optional:
- •
AWS_REGION: Override default region (defaults to us-east-1)
Step 8: Environment-Specific Parameters (Optional, Single-Account Only)
For single-account deployments, explain that users can create environment-specific parameter files:
Create cloudformation-params.dev.json, cloudformation-params.staging.json, or cloudformation-params.prod.json to override base parameters for specific environments.
These files are merged with the base cloudformation-params.json, allowing environment-specific customization while keeping the workflow simple.
Summary
Once complete, summarize what was created/modified:
- •✅ CloudFormation template (
cloudformation.template) - •✅ GitHub workflow (
.github/workflows/deploy.yml) - •✅ Deployment mode: [single-account/multi-account]
- •✅ Build steps for: [detected language]
Next steps for the user:
- •Run
aws-deployer githubcommand to create IAM roles - •Add GitHub secrets (
AWS_ROLE_ARN,S3_ARTIFACT_BUCKET) - •Push code to trigger the workflow
- •Monitor deployment in AWS Deployer console
Important Notes
- •The version format is
{github.run_number}.{first 6 chars of commit SHA} - •S3 path structure:
{repo-basename}/{branch}/{version}/ - •Uploading
cloudformation-params.jsontriggers the AWS Deployer - •All
.zipfiles in the build should be uploaded to S3 - •The CloudFormation template must accept the standard parameters