Deploy Code By Using AWS Continuous Integration And Continuous Delivery (CI/CD) Services | 🏗️ Build A Complete CI/CD Pipeline

Iniciado por joomlamz, Hoje at 02:25

Respostas: 1   |   Visualizações: 5

Tópico anterior - Tópico seguinte

0 Membros e 1 Visitante estão a ver este tópico.

Saudações a todos os membros do fórum **webmastersmz.com**!

Como especialista em tecnologia, é com enorme entusiasmo que trago uma análise técnica sobre o tópico **"Deploy Code By Using AWS Continuous Integration And Continuous Delivery (CI/CD) Services | 🏗️ Build A Complete CI/CD Pipeline"**.

Hoje em dia, no cenário de desenvolvimento de software em Moçambique e no mundo, a automação já não é um luxo, mas sim uma necessidade de sobrevivência para qualquer projeto sério. Vamos desestruturar tecnicamente os pontos principais abordados neste tema e perceber como podemos tirar o melhor proveito disso.

---

### Análise Técnica: Os Pilares de uma Pipeline CI/CD na AWS

O tópico foca-se na criação de um fluxo de trabalho automatizado desde o momento em que o programador faz o "commit" do código até à sua disponibilização em produção. Os pontos fulcrais a destacar são:

1. **A Fonte (Source) com AWS CodeCommit ou GitHub:**
   Tudo começa no repositório. A integração contínua (CI) exige que o código seja centralizado. A AWS facilita isto com o **CodeCommit**, mas na nossa realidade local, a integração com o **GitHub** ou **GitLab** acaba por ser a mais comum. O trigger automático (gatilho) configurado aqui garante que qualquer alteração na branch principal inicie o processo imediatamente.

2. **A Fase de Build com AWS CodeBuild:**
   Esta é a fase onde a magia da compilação e dos testes automáticos acontece. O **CodeBuild** corre num container gerido, compila o código, corre os testes unitários (essenciais para garantir que não estamos a enviar "bugs" para produção) e gera os artefactos prontos para o deploy. Para nós, isto elimina aquele velho problema do *"na minha máquina funciona"*.

3. **A Fase de Deploy com AWS CodeDeploy:**
   Fazer deploy manual via FTP ou aceder ao servidor por SSH para puxar o código (git pull) é uma prática propensa a erros e falhas de segurança. O **CodeDeploy** automatiza a distribuição do código para instâncias EC2, ECS (containers) ou funções AWS Lambda. Ele suporta estratégias como *Blue/Green Deployments*, garantindo que a aplicação não fique fora do ar (*zero downtime*) durante a atualização.

4. **A Orquestração com AWS CodePipeline:**
   O **CodePipeline** é o maestro deste concerto. Ele visualiza e automatiza todos os passos descritos acima. Se a fase de Build falhar, o pipeline pára e a equipa é notificada, impedindo que código quebrado chegue ao servidor.

### Benefícios para os Webmasters e Devs em Moçambique:
* **Rapidez e Consistência:** Menos tempo a fazer deploys manuais significa mais tempo focado em escrever código e melhorar o negócio.
* **Redução de Erros Humanos:** A automação garante que o processo de deploy seja idêntico todas as vezes.
* **Escalabilidade:** Ideal para startups e portais de notícias locais que precisam de atualizar os seus sistemas constantemente sem afetar a experiência do utilizador.

---

### Vamos ao Debate no WebmastersMZ! 🇲🇿

Gostaria de abrir o debate aqui no nosso fórum:
* **Quem aqui já utiliza serviços da AWS para CI/CD nos seus projetos em Moçambique?**
* Quais têm sido os vossos maiores desafios em termos de latência ou custos ao utilizar a cloud da AWS?
* Preferem usar as ferramentas nativas da AWS (CodePipeline, CodeBuild) ou optam por alternativas como GitHub Actions, GitLab CI ou Jenkins integrados com servidores VPS?

Partilhem as vossas experiências e as vossas configurações! O debate está aberto.

---

Para garantir que os vossos projetos e fóruns rodam sem falhas, convido-vos a conhecer as soluções de alojamento de alta performance da AplicHost em https://aplichost.com.

Deploy Code By Using AWS Continuous Integration And Continuous Delivery (CI/CD) Services | 🏗️ Build A Complete CI/CD Pipeline



Tópico: Deploy Code By Using AWS Continuous Integration And Continuous Delivery (CI/CD) Services | 🏗️ Build A Complete CI/CD Pipeline
Categoria: Tutoriais | Programação & Tecnologia
Idioma Principal: Português (Conteúdo de Tecnologia)

Descrição do Conteúdo / Informações:
-------------------------------------------------------------------------
Exam Guide: Developer - Associate

🏗️ Domain 3:  Deployment

📘 Task 4: Deploy Code By Using AWS Continuous Integration And Continuous Delivery (CI/CD) Services

This task tests your ability to build and manage CI/CD pipelines using AWS developer tools. You need to understand how CodeCommit, CodeBuild, CodeDeploy, and CodePipeline work together, how to write buildspec and appspec files, how deployment strategies differ, and how to configure automatic rollbacks. Deployment strategies for Lambda and EC2, SAM deployment preferences, and pipeline orchestration.



📘 Concepts




AWS CI/CD Pipeline Overview


The four AWS developer tools form a complete CI/CD pipeline:

Service
Role
Input
Output

CodeCommit
Source control
Git push
Source artifact

CodeBuild
Build and test
Source artifact
Build artifact

CodeDeploy
Deploy
Build artifact
Running application

CodePipeline
Orchestration
Trigger (push, schedule)
Coordinated pipeline execution

How they connect:

CodeCommit (source) → CodeBuild (build/test) → CodeDeploy (deploy)
↑                                              |
└──────── CodePipeline (orchestrates all) ─────┘

💡CodePipeline is the orchestrator. It doesn't build or deploy anything itself. It connects stages (source, build, test, deploy) and manages transitions between them. Each stage can use different providers (GitHub instead of CodeCommit, Jenkins instead of CodeBuild, etc.).



CodeCommit Fundamentals


Feature
Details

What It Is
Managed Git repository hosted in AWS

Authentication

HTTPS (Git credentials or credential helper) or SSH (SSH keys)

Encryption

Encrypted at rest (AWS managed keys) and in transit (HTTPS/SSH)

Triggers
SNS notifications or Lambda functions on repository events

Cross-account
Use IAM roles with AssumeRole for cross-account access

Branching

Standard Git branching: main, develop, feature branches

💡CodeCommit supports triggers for push events that can invoke Lambda functions or send SNS notifications. This is different from CodePipeline's source stage: triggers are repository-level events, while CodePipeline polls or uses CloudWatch Events to detect changes.



CodeBuild buildspec.yml Structure


The buildspec file tells CodeBuild what to do. It has four phases:

version: 0.2

env:
variables:
ENV_NAME: "production"
parameter-store:
DB_PASSWORD: "/myapp/db-password"
secrets-manager:
API_KEY: "myapp/api-key:API_KEY"

phases:
install:
runtime-versions:
python: 3.13
commands:
- pip install -r requirements.txt

pre_build:
commands:
- echo "Running tests..."
- python -m pytest tests/ -v

build:
commands:
- echo "Building..."
- sam build

post_build:
commands:
- echo "Packaging..."
- sam package --s3-bucket my-bucket --output-template-file packaged.yaml

artifacts:
files:
- packaged.yaml
- appspec.yml
discard-paths: yes

cache:
paths:
- '/root/.cache/pip/**/*'

reports:
test-reports:
files:
- "**/*.xml"
base-directory: test-results

Phase
When It Runs
Typical Use

install
First
Install dependencies, runtime versions

pre_build
Before build
Run tests, log in to ECR, lint code

build
Main phase
Compile code, run SAM build, create artifacts

post_build
After build
Package artifacts, push images, notifications

Section
Purpose

env.variables
Plain text environment variables

env.parameter-store
Values pulled from SSM Parameter Store at build time

env.secrets-manager
Values pulled from Secrets Manager at build time

artifacts
Files to pass to the next pipeline stage

cache
Paths to cache between builds (speeds up installs)

reports
Test report files for CodeBuild report groups

💡The buildspec file must be named buildspec.yml and placed in the root of your source directory (unless you override the name in the CodeBuild project settings).

The env section can pull secrets from Parameter Store and Secrets Manager. This is the secure way to use credentials in builds. Never hardcode secrets in the buildspec.



CodeDeploy appspec.yml Structure


The appspec file tells CodeDeploy how to deploy your application. The structure differs by compute platform:

For Lambda:

version: 0.0
Resources:
- MyFunction:
Type: AWS::Lambda::Function
Properties:
Name: my-function
Alias: prod
CurrentVersion: 1
TargetVersion: 2
Hooks:
- BeforeAllowTraffic: PreTrafficCheckFunction
- AfterAllowTraffic: PostTrafficCheckFunction

For EC2/On-Premises:

version: 0.0
os: linux
files:
- source: /
destination: /var/www/html
permissions:
- object: /var/www/html
owner: www-data
group: www-data
mode: "755"
hooks:
BeforeInstall:
- location: scripts/before_install.sh
timeout: 300
AfterInstall:
- location: scripts/after_install.sh
timeout: 300
ApplicationStart:
- location: scripts/start_server.sh
timeout: 300
ValidateService:
- location: scripts/validate.sh
timeout: 300



CodeDeploy Lifecycle Hooks


Lambda Deployment Hooks:

Hook
When It Runs
Purpose

BeforeAllowTraffic
Before traffic shifts to new version
Run validation tests against the new version

AfterAllowTraffic
After traffic shifts to new version
Run integration tests, verify health

EC2 Deployment Hooks (in order):

Hook
When It Runs
Purpose

BeforeInstall
Before files are copied
Clean up old files, stop services

AfterInstall
After files are copied
Configure app, set permissions

ApplicationStart
After AfterInstall
Start services, warm up

ValidateService
After ApplicationStart
Health checks, smoke tests

BeforeBlockTraffic
Before deregistering from ELB
Graceful connection draining

AfterBlockTraffic
After deregistering from ELB
Run tasks while instance is out of service

BeforeAllowTraffic
Before registering with ELB
Final checks before receiving traffic

AfterAllowTraffic
After registering with ELB
Verify instance is healthy in ELB

💡 For Lambda deployments, the hooks are Lambda functions themselves: they run your validation code and must return Succeeded or Failed to CodeDeploy.

For EC2, hooks are shell scripts that run on the instance.

If a hook fails (the deployment rolls back).



Deployment Strategies Comparison


Know each strategy of by heart:

Strategy
How It Works
Downtime
Rollback Speed
Risk
Best For

AllAtOnce
Deploy to all instances simultaneously
Brief
Redeploy previous version

High: all instances affected
Dev/test environments

Rolling

Deploy in batches (one batch at a time)

None (if batch size < total)
Redeploy previous version

Medium: one batch at a time
EC2 fleets with ELB

Rolling with additional batch
Adds new instances before removing old ones
None
Redeploy previous version

Low: maintains full capacity
Production EC2 fleets

Blue/Green
Create entirely new environment, switch traffic
None
Switch back to blue
Low
Production with zero downtime

Canary
Shift X% traffic, wait, then shift 100%
None
Shift back to 0%

Low: limited blast radius
Lambda, API Gateway

Linear
Shift X% every N minutes
None
Shift back to 0%

Low: gradual exposure
Lambda, API Gateway



SAM DeploymentPreference Types


SAM automates Lambda deployment strategies through CodeDeploy:

Type
Traffic Shift Pattern
Example

AllAtOnce
100% immediately
Instant cutover

Canary10Percent5Minutes
10% for 5 min, then 100%
Quick canary validation

Canary10Percent10Minutes
10% for 10 min, then 100%
Longer canary validation

Canary10Percent15Minutes
10% for 15 min, then 100%
Extended canary validation

Canary10Percent30Minutes
10% for 30 min, then 100%
Conservative canary

Linear10PercentEvery1Minute
+10% every minute (10 min total)
Fast linear rollout

Linear10PercentEvery2Minutes
+10% every 2 min (20 min total)
Moderate linear rollout

Linear10PercentEvery3Minutes
+10% every 3 min (30 min total)
Slow linear rollout

Linear10PercentEvery10Minutes
+10% every 10 min (100 min total)
Very conservative rollout

SAM Template Example:

MyFunction:
Type: AWS::Serverless::Function
Properties:
Handler: index.handler
Runtime: python3.13
AutoPublishAlias: live
DeploymentPreference:
Type: Canary10Percent5Minutes
Alarms:
- !Ref MyFunctionErrorAlarm
Hooks:
PreTraffic: !Ref PreTrafficHookFunction
PostTraffic: !Ref PostTrafficHookFunction

💡 AutoPublishAlias is required for DeploymentPreference to work. SAM automatically publishes a new version on each deploy and updates the alias. The Alarms section triggers automatic rollback if any alarm enters ALARM state during deployment. Canary shifts traffic in two steps (X% then 100%), while Linear shifts in equal increments.



API Gateway Stages and Custom Domains


Concept
What It Is
Use Case

Stage

A named reference to a deployment (dev, staging, prod)
Environment separation

Stage Variables
Key-value pairs available in the stage
Point to different Lambda aliases per stage

Canary Release
Split traffic between current and canary deployment
Test new API version with real traffic

Custom Domain
Map your domain to API Gateway

api.example.com instead of xyz.execute-api.region.amazonaws.com

Base Path Mapping
Map URL paths to different APIs

/v1 → API v1, /v2 → API v2

Stage Variables For Lambda Integration:

Stage: prod → stageVariables.lambdaAlias = "prod"
Stage: dev  → stageVariables.lambdaAlias = "dev"

Lambda ARN: arn:aws:lambda:region:account:function:name:${stageVariables.lambdaAlias}

API Gateway Canary Settings:

Setting
Description

Canary Percentage

% of traffic routed to canary deployment (0-100)

Stage Variable Overrides
Different stage variables for canary traffic

Promote Canary
Move canary deployment to production

Delete Canary
Remove canary and keep current production

💡API Gateway stages are not the same as Lambda aliases, but they work together. Use stage variables to point each stage to the corresponding Lambda alias.

A common pattern: API Gateway prod stage → stage variable lambdaAlias=prod → Lambda function prod alias → version 5.



Rollback Strategies


Rollback Type
How It Works
When It Triggers

Automatic (alarm-based)
CodeDeploy monitors CloudWatch alarms during deployment
Alarm enters ALARM state

Automatic (hook failure)
CodeDeploy rolls back if a lifecycle hook fails
Hook returns Failed

Manual
You stop the deployment and roll back
You detect an issue

SAM Automatic
SAM configures CodeDeploy with alarms from DeploymentPreference
Configured alarm triggers

CloudWatch Alarm For Automatic Rollback:

Metric
Threshold
Purpose

Errors
> 0 for 1 minute
Catch any Lambda errors

Duration
> timeout * 0.8 for 5 minutes
Catch performance degradation

Throttles
> 0 for 1 minute
Catch concurrency issues

5XXError (API GW)
> 1% for 5 minutes
Catch server errors

💡Automatic rollback with CloudWatch alarms is the recommended approach for production deployments.

SAM makes this easy: just add the Alarms list to DeploymentPreference.

CodeDeploy monitors the alarms during the deployment window. If any alarm fires, it automatically shifts all traffic back to the previous version. The rollback is fast because it just updates the alias pointer.



Pre/Post Traffic Hooks


Traffic hooks are Lambda functions that validate your deployment:

PreTraffic Hook Pattern:

import boto3
import json

codedeploy = boto3.client('codedeploy')

def handler(event, context):
deployment_id = event['DeploymentId']
lifecycle_event_hook_execution_id = event['LifecycleEventHookExecutionId']

# Run your validation tests here
try:
# Example: invoke the new version and check the response
lambda_client = boto3.client('lambda')
response = lambda_client.invoke(
FunctionName='my-function:live',  # the alias
Payload=json.dumps({'test': True})
)
result = json.loads(response['Payload'].read())

if result.get('statusCode') == 200:
status = 'Succeeded'
else:
status = 'Failed'
except Exception:
status = 'Failed'

# Report back to CodeDeploy
codedeploy.put_lifecycle_event_hook_execution_status(
deploymentId=deployment_id,
lifecycleEventHookExecutionId=lifecycle_event_hook_execution_id,
status=status
)

💡 The PreTraffic hook runs before any traffic shifts to the new version: use it for smoke tests and validation.

The PostTraffic hook runs after all traffic has shifted: use it for integration tests.

Both hooks must call put_lifecycle_event_hook_execution_status to tell CodeDeploy whether to proceed or roll back.

If a hook times out (default 1 hour), the deployment fails.



CodePipeline Concepts


Concept
Description

Pipeline
The overall workflow definition

Stage

A logical group of actions (Source, Build, Deploy)

Action

A task within a stage (CodeBuild action, CodeDeploy action)

Artifact

Files passed between stages (stored in S3)

Transition

The link between stages (can be disabled to pause the pipeline)

Approval action
Manual approval gate before proceeding

Pipeline Feature
Details

Trigger

CloudWatch Events (push to CodeCommit), webhook (GitHub), S3 upload

Cross-region
Actions can deploy to different regions

Cross-account
Use IAM roles for cross-account deployments

Parallel Actions
Multiple actions in the same stage run in parallel

Sequential stages

Stages run in order. A stage must complete before the next starts

💡 CodePipeline stores artifacts in an S3 bucket (created automatically or specified by you).

Each action produces output artifacts and consumes input artifacts.

If you need a manual approval before deploying to production, add an Approval action between the staging deploy and production deploy stages.



🏗️ Build A Complete CI/CD Pipeline


Build a Complete CI/CD Pipeline from scratch using the AWS Console.

• A CodeCommit repository with application code

• A CodeBuild project that runs tests and packages the application

• A CodePipeline that orchestrates source → build → deploy

• A Lambda function with canary deployment configured through SAM

• CloudWatch alarms for automatic rollback

• A working pipeline that triggers on code push



Prerequisites


• An AWS Account

• Basic familiarity with Python and YAML


Git



Part I


Create A Github Repository And Add Code

💡 Why GitHub instead of CodeCommit? AWS closed CodeCommit to new customers in July 2024. Even accounts that can create a CodeCommit repo often find it's not offered as a CodePipeline source provider. GitHub via CodeConnections is the reliable, current, real-world source integration. And it's fully supported by CodePipeline. CodeCommit, CodeBuild, CodeDeploy, and CodePipeline (If your account does offer CodeCommit and you'd rather use it, use it)

Step 01: Create the GitHub Repository

Go to GitHub → New → Repository name: cicd-demo-app → Choose Private (or Public)

⚠️ Don't initialize with a README (we'll push our own files)

Click Create repository

💡 Prefer CodeCommit? If your account offers CodeCommit and it appears as a CodePipeline source provider, you can use it instead: create the repo in the CodeCommit console, generate Git credentials in IAM (Security credentials → API keys → Generate API key → AWS CodeCommit), attach the AWSCodeCommitPowerUser policy to your user, then clone the HTTPS URL and push. HTTPS uses Git credentials. SSH uses an uploaded SSH key. Everything downstream (CodeBuild, CodePipeline, CodeDeploy) is identical. only the source provider changes.

Step By Step Guide For Setting Up CodeCommit

Step 1: Open the CodeCommit console → Create repository


Repository name: cicd-demo-app


Description - optional: Demo application for CI/CD pipeline

Click Create

Step 2:  Configure Git Credentials

💡 CodeCommit HTTPS access uses Git credentials tied to your IAM user (a generated username/password, separate from your AWS access keys).

Step 3: Open the IAM console → IAM users → select your IAM user

Step 4: Click the Security credentials tab

Step 5: In the API keys section, click Generate API key

Step 6: Service ▼: AWS CodeCommit

Click Generate API key

Step 7: Retrieve API key

⚠️ Copy or download the username and password now: This is the only time the password is shown. If you lose it, you must reset it.

Click Close

💡 Git Credentials vs Access Keys. CodeCommit HTTPS uses a  dedicated username/password (Git credentials), not your AWS_ACCESS_KEY_ID. These are IAM-managed and require a CodeCommit policy like AWSCodeCommitPowerUser on your user.  HTTPS = Git credentials or the credential helper. SSH = an uploaded SSH public key.

Step 8: Now attach a CodeCommit permissions policy to the same IAM user so it can actually use the repository.

Step 9: Still on the user's page, go to the Permissions tab → Add permissions ▼ → Attach policies directly → search for and select AWSCodeCommitPowerUser → Next → Add permissions.

Step 10: Clone And Add Application Code

git clone https://git-codecommit.us-east-1.amazonaws.com/v1/repos/cicd-demo-app
cd cicd-demo-app

python

Step 02: Add the Application Code Locally

mkdir cicd-demo-app
cd cicd-demo-app
git init
git branch -M main

Step 03: Create the Lambda function code app.py

import json

VERSION = "1.0.0"

def lambda_handler(event, context):
"""Order API handler with version tracking."""
return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps({
'message': 'Order API is running',
'version': VERSION,
'functionVersion': context.function_version
})
}

Step 04: Create the SAM template template.yaml

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: CI/CD Demo Application

Globals:
Function:
Timeout: 10
Runtime: python3.13

Resources:
OrderFunction:
Type: AWS::Serverless::Function
Properties:
Handler: app.lambda_handler
CodeUri: .
AutoPublishAlias: live
DeploymentPreference:
Type: Canary10Percent5Minutes
Alarms:
- !Ref OrderFunctionErrorAlarm

OrderFunctionErrorAlarm:
Type: AWS::CloudWatch::Alarm
Properties:
AlarmDescription: Errors on OrderFunction
Namespace: AWS/Lambda
MetricName: Errors
Dimensions:
- Name: FunctionName
Value: !Ref OrderFunction
Statistic: Sum
Period: 60
EvaluationPeriods: 1
Threshold: 1
ComparisonOperator: GreaterThanOrEqualToThreshold
TreatMissingData: notBreaching

Step 05: Create the buildspec buildspec.yml

version: 0.2

phases:
install:
runtime-versions:
python: 3.13
commands:
- pip install aws-sam-cli

build:
commands:
- sam build

post_build:
commands:
- sam package --s3-bucket ${ARTIFACT_BUCKET} --output-template-file packaged.yaml

artifacts:
files:
- packaged.yaml

Step 06: Push the code

git add .
git commit -m "Initial application code"

Step 07: Push to Github

git remote add origin `https://github.com/YOUR_USERNAME/cicd-demo-app.git`
git push -u origin main



Part II




Set Up a CodeBuild Project


Step 01: Create an S3 Bucket for Artifacts

Open the S3 console → Create bucket → Account Regional namespace (recommended) → Bucket name: cicd-demo-artifacts

Keep defaults → Create bucket

Step 02: Create the CodeBuild Project

Open the CodeBuild console → Create project

Project configuration:


Project name: cicd-demo-build


Project type: Default project

▼ Source:


Source provider ▼: GitHub


Repository: Repository in my GitHub account


Repository: cicd-demo-app

⚠️ If you used CodeCommit instead of GitHub: Set Source provider to CodeCommit

▼ Environment:


Provisioning model: On-demand


Environment image: Managed image


Compute: EC2


Running mode: Container


Operating system: Amazon Linux


Runtime(s): Standard


Image: aws/codebuild/amazonlinux-x86_64-standard:5.0


Image version: Always use the latest image for this runtime version


Service role: New service role

▶ Additional Configuration: → Environment variables:


Name: ARTIFACT_BUCKET → Value: your S3 bucket name

▼ Buildspec:


Build specifications: Use a buildspec file


Buildspec name - optional: buildspec.yml

▼ Artifacts:


Type: Amazon S3


Bucket name: cicd-demo-artifacts-...


Name: build-output

Click Create build project

⚠️ Grant the CodeBuild role access to your artifact bucket.

The auto-created CodeBuild service role can write to CodeBuild's default locations, but sam package uploads to your custom ARTIFACT_BUCKET, and the role won't have permission by default.

If the build fails at post_build with an AccessDenied on S3:

Step 1: Go to IAM → Roles → the codebuild-cicd-demo-build-service-role

Step 2: Add permissions → Attach policies → attach AmazonS3FullAccess (or a scoped inline policy allowing s3:PutObject, s3:GetObject, s3:GetBucketLocation on your bucket)

💡 Also confirm your S3 bucket and CodeBuild project are in the same region

Step 03: Run a Test Build

Click Start build

⚠️ Watch the build logs in real time

Verify each phase completes: INSTALL → PRE_BUILD → BUILD → POST_BUILD

Check the S3 bucket for the packaged.yaml artifact

💡 CodeBuild charges by the minute. Build environments are ephemeral. They're created fresh for each build. Use the cache section in buildspec.yml to cache dependencies between builds and speed up subsequent builds. CodeBuild can also pull secrets from Parameter Store and Secrets Manager using the env section.



Part III




Create a CodePipeline


Step 01: Build the Pipeline

Step 01.1: Open the CodePipeline console → Create pipeline

Step 01.2: Choose creation option


Category: Build custom pipeline

Click Next

Step 01.3: Choose Pipeline settings


Pipeline name: cicd-demo-pipeline


Execution mode: queued


Service role: New service role

Click Next

Step 01.4: Add a source stage


Source provider ▼: GitHub (via GitHub App)


Connection: click Connect to GitHub → authorize the CodeConnections connection (reuse the one from CodeBuild if you already made it)


Repository name: YOUR_USERNAME/cicd-demo-app


Default branch: main


Output artifact format: CodePipeline default

Click Next

💡 CodeConnections. A connection is a reusable, managed OAuth link between AWS and GitHub (or Bitbucket/GitLab). CodePipeline uses it to detect pushes and pull source. No Git credentials or webhooks to manage yourself. The same connection works across CodePipeline and CodeBuild.

Step 01.5: Add build stage - optional


Build provider: Other build providers


▼ AWS CodeBuild


Project name: cicd-demo-build

Click Next

Step 01.6: Add test stage - optional

Click Next

Step 01.7: Add deploy stage


Deploy provider ▼: AWS CloudFormation


Region: United States (North Virginia)


Input artifacts: BuildArtifact


Action mode: Create or update a stack


Stack name: cicd-demo-app


Artifact name: BuildArtifact


File name: packaged.yaml


Capabilities: CAPABILITY_IAM CAPABILITY_AUTO_EXPAND


Role name: create/select a CloudFormation deployment role (see the warning below)

Click Next → Create pipeline

Step 02: Watch the Pipeline Execute

The pipeline starts automatically after creation

⚠️ Watch each stage transition: Source → Build → Deploy

Click on each stage to see details and logs

The deploy stage creates a CloudFormation stack with your Lambda function

Step 03: Add a Manual Approval Stage

Step 03.1: Click Edit on the pipeline

Step 03.2: Click Add stage between Build and Deploy

Step 03.3 Stage name: Approval

Click Add stage

Step 03.4: Click Add action group:


Action name: ManualApproval


Action provider: Manual approval


Click: Done

Click Save

💡Now the pipeline pauses at the Approval stage and waits for someone to approve before deploying.



Part IV




Configure Canary Deployment with Alarms


Step 01: Verify the Deployment Configuration

Open the CodeDeploy console → Applications

💡 You should see a deployment group created by SAM (named something like cicd-demo-app-ServerlessDeploymentApplication-*)

Click on it to see the deployment configuration: CodeDeployDefault.LambdaCanary10Percent5Minutes

Step 02: View the CloudWatch Alarm

Open the CloudWatch console → Alarms

💡 Find the OrderFunctionErrorAlarm created by the SAM template

It should be in OK state (no errors yet)

Step 03: Trigger a Deployment

Step 03.1: Update app.py locally

import json

VERSION = "2.0.0"

def lambda_handler(event, context):
"""Order API handler v2 — added health check."""
action = event.get('action', 'default')

if action == 'health':
return {
'statusCode': 200,
'body': json.dumps({'status': 'healthy', 'version': VERSION})
}

return {
'statusCode': 200,
'headers': {'Content-Type': 'application/json'},
'body': json.dumps({
'message': 'Order API is running',
'version': VERSION,
'functionVersion': context.function_version,
'improvement': 'Added health check endpoint'
})
}

Step 03.2: Push the change

git add .
git commit -m "v2.0.0 - Add health check"
git push origin main

💡 The pipeline triggers automatically

Step 03.3: After the deploy stage, go to CodeDeploy → watch the canary deployment:

• 10% of traffic shifts to version 2

• CodeDeploy waits 5 minutes while monitoring the alarm

• If no alarm fires, 100% shifts to version 2

Step 04: Test Automatic Rollback

Push a broken version that throws errors

import json

VERSION = "3.0.0-broken"

def lambda_handler(event, context):
"""Intentionally broken to test rollback."""
raise Exception("Something went wrong!")

Push and let the pipeline deploy

💡 During the canary phase, the 10% of traffic hitting the new version generates errors

The CloudWatch alarm triggers → CodeDeploy automatically rolls back

All traffic returns to the previous working version



Part V




Set Up Automatic Rollback with CloudWatch Alarms


Step 01: Create Additional Alarms

Step 01.1: Open the CloudWatch console → Alarms → Create alarm

Step 01.2: Select metric: Lambda → By Function Name → OrderFunction → Duration

Step 01.3: Configure


Statistic: Average


Period: 60 seconds


Threshold: Greater than 5000 (5 seconds)


Evaluation periods: 2 of 3


Alarm name: OrderFunction-HighDuration

Click Create alarm

Step 01.4: Create another alarm for throttles


Metric: Throttles for OrderFunction


Threshold: Greater than 0


Period: 60 seconds


Alarm name: OrderFunction-Throttles

Step 02: Update the SAM Template template.yaml  with Multiple

DeploymentPreference:
Type: Canary10Percent5Minutes
Alarms:
- !Ref OrderFunctionErrorAlarm
- !Ref OrderFunctionDurationAlarm
- !Ref OrderFunctionThrottleAlarm

Push the change to trigger a pipeline run with the updated alarm configuration.

💡 You can attach multiple CloudWatch alarms to a deployment preference. If any single alarm fires during the deployment window, CodeDeploy rolls back.

This gives you defense in depth: catch errors, latency spikes, and throttling issues. The alarms are only monitored during the active deployment window, not permanently.



🏗️ What You Built | 📘 Exam Concepts Recap


What You Built
Exam Concept

Connected a GitHub repo via CodeConnections
Source stage, managed source integrations

Built a CodeBuild project with buildspec.yml
Build phases, environment variables, artifacts

Created a CodePipeline (source → build → deploy)
Pipeline orchestration and artifact flow

Added a manual approval stage
Human gates before production deployment

Configured Canary10Percent5Minutes in SAM
Gradual traffic shifting with DeploymentPreference

Attached CloudWatch alarms to the deployment
Automatic rollback on alarm breach

Pushed a broken version and watched it roll back
Defense-in-depth deployment safety

Used AutoPublishAlias: live
Required for SAM safe deployments



⚠️ Clean Up Protocol



CodePipeline → Delete cicd-demo-pipeline


CodeBuild → Delete cicd-demo-build project


CloudFormation → Delete the cicd-demo-app stack (removes Lambda, alarms, CodeDeploy resources)


Developer Tools → Settings → Connections → delete the GitHub CodeConnections connection (and optionally delete/keep the GitHub repo yourself)


S3 → Empty and delete the artifacts bucket


IAM → Delete the service roles created for CodeBuild, CodePipeline, and the CloudFormation deploy role


CloudWatch → Delete any remaining log groups and alarms



Key Takeaways



CodePipeline orchestrates the pipeline but doesn't build or deploy: it connects CodeCommit (source), CodeBuild (build), and CodeDeploy (deploy) stages.


buildspec.yml has four phases: install, pre_build, build, post_build.

• Use the env section to pull secrets from Parameter Store and Secrets Manager securely.


appspec.yml structure differs between Lambda (Resources + Hooks) and EC2 (files + permissions + hooks).


Canary shifts traffic in two steps (X% then 100%).


Linear shifts in equal increments.


Blue/Green creates a new environment and switches all traffic at once.


SAM DeploymentPreference requires AutoPublishAlias. It automatically creates CodeDeploy deployments with traffic shifting and alarm monitoring.


PreTraffic hooks run before traffic shifts: use for smoke tests. 10. PostTraffic hooks run after: use for integration tests. Both must call put_lifecycle_event_hook_execution_status.


Automatic rollback triggers when a CloudWatch alarm fires during deployment or when a lifecycle hook fails. This is the recommended approach for production.


API Gateway stage variables let you point different stages to different Lambda aliases: prod stage → prod alias, dev stage → dev alias.


CodePipeline artifacts are stored in S3. Each action consumes input artifacts and produces output artifacts that flow to the next stage.


Manual approval actions in CodePipeline create gates between stages: useful for requiring human sign-off before production deployments.



Additional Resources


• Setup for HTTPS users using Git credentials


What is AWS CodePipeline?

• Build specification reference for CodeBuild

• CodeDeploy AppSpec file reference

• Deploying serverless applications gradually with AWS SAM

• Set up an API Gateway canary release deployments

• Working with deployment configurations in CodeDeploy

⚠️ The Future of AWS CodeCommit ⚠️

🏗️


Joomlamz
Consultoria em Informática
-------------------------------------------------------
Especialista em Sistemas Web & Manutenção de Servidores.
A desenvolver o novo AplPortal com suporte a PHP 8.
Precisa de ajuda profissional? Contacte-me.

Tags: