<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: miruky</title>
    <description>The latest articles on DEV Community by miruky (@miruky).</description>
    <link>https://dev.to/miruky</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3944262%2F8032babd-171e-4c07-abf6-5ba2bdea6e53.png</url>
      <title>DEV Community: miruky</title>
      <link>https://dev.to/miruky</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/miruky"/>
    <language>en</language>
    <item>
      <title>A Field Guide to AWS CI/CD: CodeBuild, CodeDeploy, and CodePipeline End to End</title>
      <dc:creator>miruky</dc:creator>
      <pubDate>Tue, 26 May 2026 12:09:17 +0000</pubDate>
      <link>https://dev.to/miruky/a-field-guide-to-aws-cicd-codebuild-codedeploy-and-codepipeline-end-to-end-53n9</link>
      <guid>https://dev.to/miruky/a-field-guide-to-aws-cicd-codebuild-codedeploy-and-codepipeline-end-to-end-53n9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hi, I'm miruky.&lt;/p&gt;

&lt;p&gt;If you have ever tried to wire up CI/CD on AWS, you already know the names: CodeCommit, CodeBuild, CodeDeploy, CodePipeline. Individually each one is small. The real question is how to glue them into a flow that actually ships software safely.&lt;/p&gt;

&lt;p&gt;Where does the source live? Where does the build run? How do artifacts move? How do you deploy to EC2, ECS, or Lambda? Who approves the production push? What happens when something fails? CI/CD only starts paying back when all of these connect in a single line.&lt;/p&gt;

&lt;p&gt;This article walks through that end to end, from the fundamentals of CI/CD to each service, the config files, a complete hands-on pipeline, and day-2 operations.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Status note as of mid-2026&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AWS CodeCommit was restricted to existing customers from July 2024, then returned to full general availability on November 24, 2025. Amazon CodeCatalyst and Amazon CodeGuru Reviewer remain restricted for new customers. This article reflects the post-GA state, so CodeCommit is back on the table next to GitHub integration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Scope
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Area&lt;/th&gt;
&lt;th&gt;Contents&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD fundamentals&lt;/td&gt;
&lt;td&gt;CI, Continuous Delivery, Continuous Deployment, the base flow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeCommit&lt;/td&gt;
&lt;td&gt;Service overview, GA return, migration to GitHub, comparisons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitHub integration&lt;/td&gt;
&lt;td&gt;Git setup, SSH keys, CodeConnections, connection checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeBuild&lt;/td&gt;
&lt;td&gt;How it works, pricing, compute types, project creation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;buildspec.yml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Phases, environment variables, secrets, cache, Docker, batch, reports, webhooks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeDeploy for EC2&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;appspec.yml&lt;/code&gt;, lifecycle, agent, EC2 deployment, deployment groups&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment strategies&lt;/td&gt;
&lt;td&gt;In-Place, Blue/Green, load balancers, automatic rollback, CloudWatch alarms&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS and Lambda&lt;/td&gt;
&lt;td&gt;Blue/Green, Canary, Linear, test hooks, Lambda aliases&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodePipeline&lt;/td&gt;
&lt;td&gt;Stages, actions, artifacts, V1 vs V2, pricing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodePipeline V2&lt;/td&gt;
&lt;td&gt;Trigger filters, variables, manual approval, SNS, EventBridge, JSON definitions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Advanced layouts&lt;/td&gt;
&lt;td&gt;Multi-stage, parallel actions, multi-source, CloudFormation, cross-account, cross-region, Lambda Invoke&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;End-to-end hands-on&lt;/td&gt;
&lt;td&gt;GitHub to EC2 CI/CD, validation, failure behavior, cleanup&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production operations&lt;/td&gt;
&lt;td&gt;IAM, secrets, S3/KMS, cost, monitoring, logs, troubleshooting, team practices&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;CI/CD fundamentals&lt;/li&gt;
&lt;li&gt;The AWS Code family at a glance&lt;/li&gt;
&lt;li&gt;Source control and where CodeCommit stands now&lt;/li&gt;
&lt;li&gt;GitHub and CodeConnections setup&lt;/li&gt;
&lt;li&gt;CodeBuild fundamentals&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;buildspec.yml&lt;/code&gt; in practice&lt;/li&gt;
&lt;li&gt;CodeDeploy fundamentals&lt;/li&gt;
&lt;li&gt;Deploying to EC2&lt;/li&gt;
&lt;li&gt;Deployment strategies and rollback&lt;/li&gt;
&lt;li&gt;Canary deployments to ECS and Lambda&lt;/li&gt;
&lt;li&gt;CodePipeline fundamentals&lt;/li&gt;
&lt;li&gt;CodePipeline V2 in practice&lt;/li&gt;
&lt;li&gt;Advanced pipeline design&lt;/li&gt;
&lt;li&gt;Building a CI/CD pipeline from scratch&lt;/li&gt;
&lt;li&gt;Security and IAM design&lt;/li&gt;
&lt;li&gt;Cost, monitoring, and logs&lt;/li&gt;
&lt;li&gt;Troubleshooting&lt;/li&gt;
&lt;li&gt;Patterns and team practices&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. CI/CD fundamentals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1-1. CI
&lt;/h3&gt;

&lt;p&gt;CI stands for Continuous Integration: developers merge code into the repository often, and every merge triggers builds, tests, and static analysis automatically.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Goal&lt;/td&gt;
&lt;td&gt;Catch integration bugs fast&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Triggers&lt;/td&gt;
&lt;td&gt;push, pull request, manual run&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Automated steps&lt;/td&gt;
&lt;td&gt;Compile, unit tests, lint, format check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Central AWS service&lt;/td&gt;
&lt;td&gt;CodeBuild&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Without CI, missed tests, environment drift, and post-merge breakage tend to surface late. The point of CI is to verify small changes quickly.&lt;/p&gt;

&lt;h3&gt;
  
  
  1-2. CD
&lt;/h3&gt;

&lt;p&gt;CD has two meanings, and they are not interchangeable.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Term&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;th&gt;Production push&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Continuous Delivery&lt;/td&gt;
&lt;td&gt;Keep production-ready at all times&lt;/td&gt;
&lt;td&gt;Manual approval gate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Continuous Deployment&lt;/td&gt;
&lt;td&gt;Auto-promote to production after tests&lt;/td&gt;
&lt;td&gt;Fully automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;In practice, most teams want a human gate before production, so Continuous Delivery is more common. CodePipeline's manual approval stage maps cleanly to that.&lt;/p&gt;

&lt;h3&gt;
  
  
  1-3. End-to-end CI/CD flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart TB
    A[Source control] --&amp;gt; B[Build]
    B --&amp;gt; C[Test]
    C --&amp;gt; D[Artifact storage]
    D --&amp;gt; E[Staging deploy]
    E --&amp;gt; F[Manual approval]
    F --&amp;gt; G[Production deploy]
    G --&amp;gt; H[Monitoring and logs]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On AWS, source lives in CodeCommit or GitHub, builds run in CodeBuild, deployments are driven by CodeDeploy, and CodePipeline orchestrates the whole flow.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The AWS Code family at a glance
&lt;/h2&gt;

&lt;h3&gt;
  
  
  2-1. The four core services
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Main config file&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS CodeCommit&lt;/td&gt;
&lt;td&gt;Managed Git repository&lt;/td&gt;
&lt;td&gt;none&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS CodeBuild&lt;/td&gt;
&lt;td&gt;Build and test&lt;/td&gt;
&lt;td&gt;&lt;code&gt;buildspec.yml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS CodeDeploy&lt;/td&gt;
&lt;td&gt;Deploy to EC2, ECS, Lambda&lt;/td&gt;
&lt;td&gt;&lt;code&gt;appspec.yml&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AWS CodePipeline&lt;/td&gt;
&lt;td&gt;Orchestrate the CI/CD flow&lt;/td&gt;
&lt;td&gt;Pipeline JSON, console config&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;CodePipeline does not build or deploy by itself. It chains actions like Source, Build, Deploy, and Approval, and manages order, artifacts, and what happens on failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  2-2. CI/CD steps mapped to AWS services
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Step&lt;/th&gt;
&lt;th&gt;AWS service&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Source control&lt;/td&gt;
&lt;td&gt;CodeCommit, GitHub, GitLab, Bitbucket&lt;/td&gt;
&lt;td&gt;CodeConnections is the bridge for non-AWS sources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build&lt;/td&gt;
&lt;td&gt;CodeBuild&lt;/td&gt;
&lt;td&gt;EC2 compute or Lambda compute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Artifact storage&lt;/td&gt;
&lt;td&gt;S3, ECR&lt;/td&gt;
&lt;td&gt;ZIPs, static files, Docker images&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy&lt;/td&gt;
&lt;td&gt;CodeDeploy, CloudFormation, ECS, S3&lt;/td&gt;
&lt;td&gt;The right action depends on the target&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Approval&lt;/td&gt;
&lt;td&gt;CodePipeline Manual approval&lt;/td&gt;
&lt;td&gt;Pre-production gate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notifications&lt;/td&gt;
&lt;td&gt;SNS, EventBridge, AWS Chatbot&lt;/td&gt;
&lt;td&gt;Failure alerts, approval requests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Observability&lt;/td&gt;
&lt;td&gt;CloudWatch, CloudTrail&lt;/td&gt;
&lt;td&gt;Logs, metrics, audit trail&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  2-3. Choosing services in 2026
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Goal&lt;/th&gt;
&lt;th&gt;First choice&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Stay fully inside AWS for Git&lt;/td&gt;
&lt;td&gt;CodeCommit&lt;/td&gt;
&lt;td&gt;Returned to GA in November 2025&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Develop primarily on GitHub&lt;/td&gt;
&lt;td&gt;GitHub + CodeConnections&lt;/td&gt;
&lt;td&gt;Most common in practice&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Only the build in AWS&lt;/td&gt;
&lt;td&gt;CodeBuild&lt;/td&gt;
&lt;td&gt;Plays well alongside GitHub Actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Safe EC2 rollout&lt;/td&gt;
&lt;td&gt;CodeDeploy&lt;/td&gt;
&lt;td&gt;Needs agent and &lt;code&gt;appspec.yml&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Staged rollout for ECS or Lambda&lt;/td&gt;
&lt;td&gt;CodeDeploy&lt;/td&gt;
&lt;td&gt;Canary, Linear, AllAtOnce&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tie multiple steps together&lt;/td&gt;
&lt;td&gt;CodePipeline V2&lt;/td&gt;
&lt;td&gt;Default to V2 for new pipelines&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  2-4. Alternatives outside the Code family
&lt;/h3&gt;

&lt;p&gt;CI/CD on AWS does not have to use the Code family. GitHub Actions, GitLab CI/CD, Bitbucket Pipelines, Terraform Cloud, and CircleCI are all valid options.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Option&lt;/th&gt;
&lt;th&gt;Good for&lt;/th&gt;
&lt;th&gt;Watch out for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GitHub Actions&lt;/td&gt;
&lt;td&gt;GitHub-centric workflows&lt;/td&gt;
&lt;td&gt;Use OIDC to minimize AWS permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GitLab CI/CD&lt;/td&gt;
&lt;td&gt;Source + CI integrated in GitLab&lt;/td&gt;
&lt;td&gt;AWS-side permissioning is separate&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitbucket Pipelines&lt;/td&gt;
&lt;td&gt;Atlassian-aligned stacks&lt;/td&gt;
&lt;td&gt;Confirm AWS integration design&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodePipeline + CodeBuild&lt;/td&gt;
&lt;td&gt;Want the runtime inside AWS&lt;/td&gt;
&lt;td&gt;CodeConnections and IAM design matter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeCommit + CodePipeline&lt;/td&gt;
&lt;td&gt;Stay fully inside AWS&lt;/td&gt;
&lt;td&gt;Collaboration features are lighter than GitHub or GitLab&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Amazon CodeCatalyst once bundled source control, issue tracking, and CI/CD into a single managed service. New customer signups stopped on November 7, 2025, so treat it as an option for existing users rather than a default for new builds.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Source control and where CodeCommit stands now
&lt;/h2&gt;

&lt;h3&gt;
  
  
  3-1. CodeCommit overview
&lt;/h3&gt;

&lt;p&gt;AWS CodeCommit is a managed private Git repository service. The strengths are IAM-driven access control, KMS encryption at rest, TLS in transit, and CloudTrail-based auditing, all controllable from inside AWS.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Protocols&lt;/td&gt;
&lt;td&gt;HTTPS, SSH&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;IAM, Git credentials, SSH public key&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Encryption&lt;/td&gt;
&lt;td&gt;At rest and in transit&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Notifications&lt;/td&gt;
&lt;td&gt;SNS, Lambda, EventBridge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Integrations&lt;/td&gt;
&lt;td&gt;CodeBuild, CodePipeline, CloudTrail&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best fit&lt;/td&gt;
&lt;td&gt;Teams that want to keep development inside AWS, regulated industries, IAM-centric governance&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  3-2. CodeCommit timeline
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Date&lt;/th&gt;
&lt;th&gt;Event&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;2024-07-25&lt;/td&gt;
&lt;td&gt;New customer access paused&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;2025-11-24&lt;/td&gt;
&lt;td&gt;Full GA return announced&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mid-2026&lt;/td&gt;
&lt;td&gt;Safe to put CodeCommit back on the shortlist for new builds&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;If you migrated to GitHub or GitLab during the pause, you can keep using them. But if you care about staying inside AWS, IAM governance, VPC endpoints, or CloudTrail auditing, CodeCommit is once again a reasonable pick.&lt;/p&gt;

&lt;h3&gt;
  
  
  3-3. CodeCommit vs GitHub, GitLab, Bitbucket
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lens&lt;/th&gt;
&lt;th&gt;CodeCommit&lt;/th&gt;
&lt;th&gt;GitHub&lt;/th&gt;
&lt;th&gt;GitLab&lt;/th&gt;
&lt;th&gt;Bitbucket&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;AWS integration&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;Via CodeConnections&lt;/td&gt;
&lt;td&gt;Via CodeConnections&lt;/td&gt;
&lt;td&gt;Via CodeConnections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;IAM control&lt;/td&gt;
&lt;td&gt;Strong&lt;/td&gt;
&lt;td&gt;OIDC + GitHub controls&lt;/td&gt;
&lt;td&gt;OIDC + GitLab controls&lt;/td&gt;
&lt;td&gt;Atlassian controls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Collaboration&lt;/td&gt;
&lt;td&gt;Basic&lt;/td&gt;
&lt;td&gt;Strong (Issues, Projects, PRs)&lt;/td&gt;
&lt;td&gt;Strong (Issue, Board, CI)&lt;/td&gt;
&lt;td&gt;Strong Jira integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CI/CD&lt;/td&gt;
&lt;td&gt;Pairs with CodeBuild&lt;/td&gt;
&lt;td&gt;GitHub Actions also viable&lt;/td&gt;
&lt;td&gt;GitLab CI/CD also viable&lt;/td&gt;
&lt;td&gt;Bitbucket Pipelines also viable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Fully inside AWS&lt;/td&gt;
&lt;td&gt;Easy&lt;/td&gt;
&lt;td&gt;Hard&lt;/td&gt;
&lt;td&gt;Hard&lt;/td&gt;
&lt;td&gt;Hard&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The hands-on in this article uses GitHub. If you prefer CodeCommit, swap the Source action; the CodeBuild, CodeDeploy, and CodePipeline thinking is the same.&lt;/p&gt;

&lt;h3&gt;
  
  
  3-4. Migrating off CodeCommit
&lt;/h3&gt;

&lt;p&gt;To move history, branches, and tags in one shot, use a mirror clone.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Mirror-clone the CodeCommit repository&lt;/span&gt;
git clone &lt;span class="nt"&gt;--mirror&lt;/span&gt; https://git-codecommit.ap-northeast-1.amazonaws.com/v1/repos/my-repo temp-repo

&lt;span class="c"&gt;# Point the mirror at the empty GitHub repo&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;temp-repo
git remote set-url origin git@github.com:my-org/my-repo.git

&lt;span class="c"&gt;# Push every branch and tag&lt;/span&gt;
git push &lt;span class="nt"&gt;--mirror&lt;/span&gt;

&lt;span class="c"&gt;# Clean up the working directory&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; ..
&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; temp-repo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After the move, revisit branch protection, CODEOWNERS, CI/CD configs, webhooks, secrets, and the Source action of every pipeline.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. GitHub and CodeConnections setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  4-1. Git and SSH key setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Configure Git identity&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.name &lt;span class="s2"&gt;"your-name"&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; user.email &lt;span class="s2"&gt;"your-email@example.com"&lt;/span&gt;

&lt;span class="c"&gt;# Default new repositories to main&lt;/span&gt;
git config &lt;span class="nt"&gt;--global&lt;/span&gt; init.defaultBranch main

&lt;span class="c"&gt;# Generate an SSH key&lt;/span&gt;
ssh-keygen &lt;span class="nt"&gt;-t&lt;/span&gt; ed25519 &lt;span class="nt"&gt;-C&lt;/span&gt; &lt;span class="s2"&gt;"your-email@example.com"&lt;/span&gt;

&lt;span class="c"&gt;# Verify the connection&lt;/span&gt;
ssh &lt;span class="nt"&gt;-T&lt;/span&gt; git@github.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create the repository on GitHub and push an initial file to &lt;code&gt;main&lt;/code&gt; before moving on.&lt;/p&gt;

&lt;h3&gt;
  
  
  4-2. Creating the GitHub repository
&lt;/h3&gt;

&lt;p&gt;Keep the demo repository minimal at first, ideally just a README. Reusing the same repo across CodeBuild, CodeDeploy, and CodePipeline makes the end-to-end flow easier to follow.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Clone the repository&lt;/span&gt;
git clone git@github.com:your-name/aws-code-series-demo.git
&lt;span class="nb"&gt;cd &lt;/span&gt;aws-code-series-demo

&lt;span class="c"&gt;# Add a starter file&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; README.md &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
# aws-code-series-demo

A demo repository for AWS Code family CI/CD experiments.
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Commit and push&lt;/span&gt;
git add README.md
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"Add initial README"&lt;/span&gt;
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Branch protection, required reviews, and required status checks can be layered on later. Start permissive, get the pipeline working, then harden.&lt;/p&gt;

&lt;h3&gt;
  
  
  4-3. What CodeConnections does
&lt;/h3&gt;

&lt;p&gt;AWS CodeConnections is the bridge between AWS and GitHub, GitLab, Bitbucket, and friends. It was renamed from AWS CodeStar Connections on March 29, 2024.&lt;/p&gt;

&lt;p&gt;When you use GitHub in CodePipeline, the Source action typically uses the &lt;code&gt;CodeStarSourceConnection&lt;/code&gt; provider. The legacy name lives on in the action, but the service itself is AWS CodeConnections.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Targets&lt;/td&gt;
&lt;td&gt;GitHub, GitHub Enterprise Server, GitLab, Bitbucket, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Role&lt;/td&gt;
&lt;td&gt;Detect repo changes and fetch source on AWS' behalf&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Required permission&lt;/td&gt;
&lt;td&gt;&lt;code&gt;codeconnections:UseConnection&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Output&lt;/td&gt;
&lt;td&gt;ZIP, or a full-clone reference for CodeBuild&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Caveat&lt;/td&gt;
&lt;td&gt;Some regions restrict the connection action&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  4-4. Creating and verifying the connection
&lt;/h3&gt;

&lt;p&gt;From the Developer Tools Connections console, pick GitHub, install the GitHub App, and grant access to the target repositories. Once the connection status reads &lt;code&gt;AVAILABLE&lt;/code&gt;, the Source action in CodePipeline can use it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# List your connections&lt;/span&gt;
aws codeconnections list-connections &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--provider-type&lt;/span&gt; GitHub &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Connections[*].{Name:ConnectionName,Status:ConnectionStatus,Arn:ConnectionArn}'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; table
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Older CLI versions and existing resources may still surface the &lt;code&gt;codestar-connections&lt;/code&gt; namespace. For new work, design around &lt;code&gt;codeconnections&lt;/code&gt; from the start.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. CodeBuild fundamentals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  5-1. What CodeBuild is
&lt;/h3&gt;

&lt;p&gt;AWS CodeBuild is a fully managed build, test, and packaging service. You do not run or maintain build servers.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Trait&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Server management&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Scaling&lt;/td&gt;
&lt;td&gt;Auto-scales with build demand&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;A fresh container per build&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Configuration&lt;/td&gt;
&lt;td&gt;Declared in &lt;code&gt;buildspec.yml&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Outputs&lt;/td&gt;
&lt;td&gt;S3, ECR, or CodePipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Logs&lt;/td&gt;
&lt;td&gt;CloudWatch Logs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The default flow is: fetch source, start the environment, run &lt;code&gt;install&lt;/code&gt;, &lt;code&gt;pre_build&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt;, &lt;code&gt;post_build&lt;/code&gt;, emit artifacts, tear down.&lt;/p&gt;

&lt;h3&gt;
  
  
  5-2. Compute types
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Trait&lt;/th&gt;
&lt;th&gt;Good for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EC2 on-demand&lt;/td&gt;
&lt;td&gt;Minute-billed, supports Docker and long builds&lt;/td&gt;
&lt;td&gt;General builds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda on-demand&lt;/td&gt;
&lt;td&gt;Second-billed, shorter max runtime&lt;/td&gt;
&lt;td&gt;Light builds and quick tests&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EC2 reserved capacity&lt;/td&gt;
&lt;td&gt;Dedicated fleet&lt;/td&gt;
&lt;td&gt;High-volume builds, predictable queue times&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Docker image builds need EC2 compute with privileged mode enabled. Lambda compute is lightweight but cannot run Docker-in-Docker workloads.&lt;/p&gt;

&lt;h3&gt;
  
  
  5-3. Pricing at a glance
&lt;/h3&gt;

&lt;p&gt;As of mid-2026, CodeBuild is pay-as-you-go: EC2 on-demand is minute-based, Lambda on-demand is second-based.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Free tier&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EC2 on-demand&lt;/td&gt;
&lt;td&gt;100 build minutes per month on &lt;code&gt;general1.small&lt;/code&gt; or &lt;code&gt;arm1.small&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda on-demand&lt;/td&gt;
&lt;td&gt;6,000 build seconds per month on &lt;code&gt;lambda.arm.1GB&lt;/code&gt; or &lt;code&gt;lambda.x86-64.1GB&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;code&gt;general1.small&lt;/code&gt; will keep this hands-on close to free. CloudWatch Logs, S3, KMS, and ECR are billed separately, so watch those independently.&lt;/p&gt;

&lt;h3&gt;
  
  
  5-4. Your first CodeBuild project
&lt;/h3&gt;

&lt;p&gt;A minimal setup: a Python app, a test, and &lt;code&gt;buildspec.yml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app.py
&lt;/span&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, AWS CodeBuild!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
    &lt;span class="nf"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1 + 2 = &lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# test_app.py
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;unittest&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;add&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hello&lt;/span&gt;


&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TestApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;TestCase&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_hello&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Hello, AWS CodeBuild!&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;assertEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;__main__&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="n"&gt;unittest&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;main&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you create the CodeBuild project, you pick the source provider, the GitHub connection, the branch, the runtime, the service role, the &lt;code&gt;buildspec&lt;/code&gt;, the artifact target, and the log destination.&lt;/p&gt;

&lt;h3&gt;
  
  
  5-5. First build and log check
&lt;/h3&gt;

&lt;p&gt;After creating the project, start the first build manually. The goal of run #1 is not "my app works", it is "CodeBuild can fetch the source, read &lt;code&gt;buildspec.yml&lt;/code&gt;, and stream logs to CloudWatch Logs".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Start a build&lt;/span&gt;
aws codebuild start-build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--project-name&lt;/span&gt; code-series-demo-build

&lt;span class="c"&gt;# Grab the latest build ID&lt;/span&gt;
&lt;span class="nv"&gt;BUILD_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws codebuild list-builds-for-project &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--project-name&lt;/span&gt; code-series-demo-build &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'ids[0]'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Inspect the build state&lt;/span&gt;
aws codebuild batch-get-builds &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--ids&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BUILD_ID&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'builds[0].{Status:buildStatus,Start:startTime,End:endTime}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If it fails, look at Phase details in the CodeBuild console and at CloudWatch Logs. &lt;code&gt;DOWNLOAD_SOURCE_FAILED&lt;/code&gt; points at the connection or repo permissions, &lt;code&gt;CLIENT_ERROR&lt;/code&gt; usually means a &lt;code&gt;buildspec.yml&lt;/code&gt; syntax issue, and &lt;code&gt;UPLOAD_ARTIFACTS_FAILED&lt;/code&gt; is almost always S3 permissions.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. &lt;code&gt;buildspec.yml&lt;/code&gt; in practice
&lt;/h2&gt;

&lt;h3&gt;
  
  
  6-1. Base structure
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;buildspec.yml&lt;/code&gt; declares what CodeBuild runs. Put it at the repository root by default.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;

&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ENVIRONMENT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dev"&lt;/span&gt;

&lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;install&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runtime-versions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;python&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;3.12&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Installing dependencies"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;pip install -r requirements.txt&lt;/span&gt;
  &lt;span class="na"&gt;pre_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Running tests"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;python -m unittest discover -v&lt;/span&gt;
    &lt;span class="na"&gt;finally&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "pre_build cleanup"&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Running the application"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;python app.py&lt;/span&gt;
  &lt;span class="na"&gt;post_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Build complete"&lt;/span&gt;

&lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/*'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;finally&lt;/code&gt; runs even when the phase's &lt;code&gt;commands&lt;/code&gt; fail, which makes it a good place for log collection and temp cleanup.&lt;/p&gt;

&lt;h3&gt;
  
  
  6-2. Environment variables and secrets
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kind&lt;/th&gt;
&lt;th&gt;Syntax&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Plain environment variable&lt;/td&gt;
&lt;td&gt;&lt;code&gt;env.variables&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Environment name, non-sensitive config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parameter Store&lt;/td&gt;
&lt;td&gt;&lt;code&gt;env.parameter-store&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;API keys, configuration values&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets Manager&lt;/td&gt;
&lt;td&gt;&lt;code&gt;env.secrets-manager&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DB passwords, external service credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Exported variables&lt;/td&gt;
&lt;td&gt;&lt;code&gt;env.exported-variables&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pass values to downstream CodePipeline actions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;ENVIRONMENT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;production"&lt;/span&gt;
  &lt;span class="na"&gt;parameter-store&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;API_ENDPOINT&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/app/prod/api-endpoint"&lt;/span&gt;
  &lt;span class="na"&gt;secrets-manager&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;DB_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;prod/db:password"&lt;/span&gt;
  &lt;span class="na"&gt;exported-variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;IMAGE_TAG&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;BUILD_VERSION&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Never hardcode secrets in &lt;code&gt;buildspec.yml&lt;/code&gt;. Pull them from Parameter Store or Secrets Manager. And resist the urge to leave &lt;code&gt;echo $DB_PASSWORD&lt;/code&gt; lines in for debugging, they end up in CloudWatch.&lt;/p&gt;

&lt;h3&gt;
  
  
  6-3. Built-in environment variables
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Contents&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CODEBUILD_BUILD_ID&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Unique build ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CODEBUILD_BUILD_NUMBER&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Build number&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CODEBUILD_SOURCE_VERSION&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;The requested source version&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CODEBUILD_RESOLVED_SOURCE_VERSION&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Resolved commit hash&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CODEBUILD_SRC_DIR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Source code directory&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CODEBUILD_WEBHOOK_HEAD_REF&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Branch ref from a webhook trigger&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Using a short slice of &lt;code&gt;CODEBUILD_RESOLVED_SOURCE_VERSION&lt;/code&gt; as the Docker image tag makes it trivial to trace any artifact back to a commit.&lt;/p&gt;

&lt;h3&gt;
  
  
  6-4. Cache
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kind&lt;/th&gt;
&lt;th&gt;Trait&lt;/th&gt;
&lt;th&gt;Caveat&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;S3 cache&lt;/td&gt;
&lt;td&gt;Easy to share across projects&lt;/td&gt;
&lt;td&gt;Pays the cost of S3 round-trips&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Local cache&lt;/td&gt;
&lt;td&gt;Fast on the same host&lt;/td&gt;
&lt;td&gt;Cold when the host changes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Local cache supports source cache, Docker layer cache, and custom cache. Docker layer caching requires Linux and privileged mode.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;paths&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/root/.cache/pip/**/*'&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;node_modules/**/*'&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;/root/.m2/**/*'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6-5. Building Docker images and pushing to ECR
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;

&lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pre_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Logging in to ECR"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $ECR_REPO&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Building the Docker image"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker build -t $ECR_REPO:$IMAGE_TAG .&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker tag $ECR_REPO:$IMAGE_TAG $ECR_REPO:latest&lt;/span&gt;
  &lt;span class="na"&gt;post_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Pushing the Docker image"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker push $ECR_REPO:$IMAGE_TAG&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;docker push $ECR_REPO:latest&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;printf '[{"name":"app","imageUri":"%s"}]' $ECR_REPO:$IMAGE_TAG &amp;gt; imagedefinitions.json&lt;/span&gt;

&lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;imagedefinitions.json&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pushing to ECR requires the ECR-related permissions on the CodeBuild service role.&lt;/p&gt;

&lt;h3&gt;
  
  
  6-6. Batch builds and reports
&lt;/h3&gt;

&lt;p&gt;Batch builds let you run multiple environment combinations in parallel or build a dependency graph of related builds.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Build matrix&lt;/td&gt;
&lt;td&gt;Test on Node.js 20, 22, and 24 in parallel&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build graph&lt;/td&gt;
&lt;td&gt;Run unit and integration tests in parallel after the main build&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Reports&lt;/td&gt;
&lt;td&gt;JUnit XML, Cucumber JSON, TRX, TestNG, NUnit&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;reports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;pytest-reports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;test-results.xml'&lt;/span&gt;
    &lt;span class="na"&gt;base-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;reports'&lt;/span&gt;
    &lt;span class="na"&gt;file-format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;JUNITXML&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once test results land as a report, the CodeBuild console gives you pass/fail/skip counts and trend graphs for free.&lt;/p&gt;

&lt;h3&gt;
  
  
  6-7. Webhook-driven builds
&lt;/h3&gt;

&lt;p&gt;CodeBuild can subscribe to webhooks on its own. Trigger events include push, pull request creation, and pull request updates. Branch and path filters keep useless builds out of the queue.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Filter&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Branch&lt;/td&gt;
&lt;td&gt;&lt;code&gt;refs/heads/main&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pull Request&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;PULL_REQUEST_CREATED&lt;/code&gt;, &lt;code&gt;PULL_REQUEST_UPDATED&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Path&lt;/td&gt;
&lt;td&gt;Include &lt;code&gt;src/**&lt;/code&gt;, exclude &lt;code&gt;docs/**&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  7. CodeDeploy fundamentals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7-1. What CodeDeploy is
&lt;/h3&gt;

&lt;p&gt;AWS CodeDeploy automates deployments to EC2, on-premises hosts, ECS, and Lambda.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;Common strategies&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EC2, on-premises&lt;/td&gt;
&lt;td&gt;Required&lt;/td&gt;
&lt;td&gt;In-Place, Blue/Green&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS&lt;/td&gt;
&lt;td&gt;Not required&lt;/td&gt;
&lt;td&gt;Blue/Green, Canary, Linear, AllAtOnce&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda&lt;/td&gt;
&lt;td&gt;Not required&lt;/td&gt;
&lt;td&gt;Canary, Linear, AllAtOnce&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For EC2 and on-prem, the CodeDeploy Agent runs on the instance and executes the steps in &lt;code&gt;appspec.yml&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  7-2. Key components
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Application&lt;/td&gt;
&lt;td&gt;Logical container for a deployable thing&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment group&lt;/td&gt;
&lt;td&gt;The set of instances or ECS services it targets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment configuration&lt;/td&gt;
&lt;td&gt;How many or what percentage to roll at a time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Revision&lt;/td&gt;
&lt;td&gt;The deployable artifact&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;appspec.yml&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;File layout, hooks, and target resources&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeDeploy Agent&lt;/td&gt;
&lt;td&gt;Runs on EC2 or on-prem hosts&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  7-3. &lt;code&gt;appspec.yml&lt;/code&gt; for EC2
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.0&lt;/span&gt;
&lt;span class="na"&gt;os&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux&lt;/span&gt;

&lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
    &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/www/html&lt;/span&gt;

&lt;span class="na"&gt;permissions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;object&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/www/html&lt;/span&gt;
    &lt;span class="na"&gt;owner&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apache&lt;/span&gt;
    &lt;span class="na"&gt;group&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;apache&lt;/span&gt;
    &lt;span class="na"&gt;mode&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;755&lt;/span&gt;
    &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;directory&lt;/span&gt;

&lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ApplicationStop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/stop_server.sh&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;
      &lt;span class="na"&gt;runas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;BeforeInstall&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/install_dependencies.sh&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;
      &lt;span class="na"&gt;runas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;AfterInstall&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/after_install.sh&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;
      &lt;span class="na"&gt;runas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;ApplicationStart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/start_server.sh&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;
      &lt;span class="na"&gt;runas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;ValidateService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/validate_service.sh&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt;
      &lt;span class="na"&gt;runas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;files&lt;/code&gt; defines the destination, &lt;code&gt;permissions&lt;/code&gt; sets ownership, and &lt;code&gt;hooks&lt;/code&gt; wires lifecycle events to scripts.&lt;/p&gt;

&lt;h3&gt;
  
  
  7-4. Lifecycle events
&lt;/h3&gt;

&lt;p&gt;An In-Place deployment runs the following events in order:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ApplicationStop
DownloadBundle
BeforeInstall
Install
AfterInstall
ApplicationStart
ValidateService
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CodeDeploy handles &lt;code&gt;DownloadBundle&lt;/code&gt; and &lt;code&gt;Install&lt;/code&gt; itself. The hook scripts you write live in the other events.&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Deploying to EC2
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8-1. Preparing the EC2 side
&lt;/h3&gt;

&lt;p&gt;To deploy with CodeDeploy on EC2, you need an instance role, a CodeDeploy service role, instance tags, and the CodeDeploy Agent.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Item&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;EC2 instance role&lt;/td&gt;
&lt;td&gt;Permission to fetch revisions from S3, plus SSM permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeDeploy service role&lt;/td&gt;
&lt;td&gt;Permission to read EC2 tags, ASG, and ELB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tags&lt;/td&gt;
&lt;td&gt;Filter to scope which instances are targeted&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agent&lt;/td&gt;
&lt;td&gt;The on-host process that executes the deployment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;On Amazon Linux 2023, pulling the latest AMI ID from SSM Parameter Store avoids the trap of an AMI ID that quietly goes stale.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;AMI_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;aws ssm get-parameters &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--names&lt;/span&gt; /aws/service/ami-amazon-linux-latest/al2023-ami-kernel-default-x86_64 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'Parameters[0].Value'&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--output&lt;/span&gt; text&lt;span class="si"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8-2. CodeDeploy Agent
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Fetch the installer&lt;/span&gt;
&lt;span class="nb"&gt;cd&lt;/span&gt; /tmp
wget https://aws-codedeploy-ap-northeast-1.s3.ap-northeast-1.amazonaws.com/latest/install

&lt;span class="c"&gt;# Install&lt;/span&gt;
&lt;span class="nb"&gt;chmod&lt;/span&gt; +x ./install
&lt;span class="nb"&gt;sudo&lt;/span&gt; ./install auto

&lt;span class="c"&gt;# Verify&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;systemctl status codedeploy-agent
&lt;span class="nb"&gt;sudo &lt;/span&gt;codedeploy-agent &lt;span class="nt"&gt;--version&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the agent is not running, the deployment will not progress. When things go wrong, check &lt;code&gt;/var/log/aws/codedeploy-agent/&lt;/code&gt; and &lt;code&gt;/opt/codedeploy-agent/deployment-root/&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  8-3. Deployment file layout
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws-code-series-demo/
├── appspec.yml
├── index.html
└── scripts/
    ├── application_stop.sh
    ├── before_install.sh
    ├── after_install.sh
    ├── application_start.sh
    └── validate_service.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Running ValidateService"&lt;/span&gt;

&lt;span class="nb"&gt;sleep &lt;/span&gt;5

&lt;span class="nv"&gt;HTTP_CODE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-o&lt;/span&gt; /dev/null &lt;span class="nt"&gt;-w&lt;/span&gt; &lt;span class="s2"&gt;"%{http_code}"&lt;/span&gt; http://localhost/&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HTTP_CODE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"200"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Validation passed"&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Validation failed"&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always include a &lt;code&gt;ValidateService&lt;/code&gt; hook. Detecting trouble here is what lets CodeDeploy fail loudly and roll back cleanly.&lt;/p&gt;

&lt;h3&gt;
  
  
  8-4. Deployment groups
&lt;/h3&gt;

&lt;p&gt;EC2 deployment groups select target instances by tag or by Auto Scaling Group.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Application name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;code-series-demo-app&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment group name&lt;/td&gt;
&lt;td&gt;&lt;code&gt;code-series-demo-dg&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment type&lt;/td&gt;
&lt;td&gt;In-Place&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target&lt;/td&gt;
&lt;td&gt;EC2 tag &lt;code&gt;Name=CodeDeploy-Demo&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deployment configuration&lt;/td&gt;
&lt;td&gt;&lt;code&gt;CodeDeployDefault.AllAtOnce&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback&lt;/td&gt;
&lt;td&gt;Enabled on deployment failure&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For production, prefer &lt;code&gt;OneAtATime&lt;/code&gt; or Blue/Green over &lt;code&gt;AllAtOnce&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  8-5. Running the deployment
&lt;/h3&gt;

&lt;p&gt;Once the CodeDeploy application and deployment group exist, kick off a deployment with a specified revision. With GitHub as the revision source, pass the repo and commit ID. Through CodePipeline, the pipeline hands an S3 artifact to CodeDeploy on your behalf.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Grab the latest commit ID&lt;/span&gt;
git rev-parse HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;While the deployment runs, watch the progress through ApplicationStop, DownloadBundle, BeforeInstall, Install, AfterInstall, ApplicationStart, and ValidateService. Once ValidateService passes, visit the EC2 public IP or the ALB DNS name to confirm the app works.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://&amp;lt;EC2 public IP&amp;gt;/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To try an update, bump a version string in &lt;code&gt;index.html&lt;/code&gt;, push, and deploy again. To see what failure looks like, deliberately fail &lt;code&gt;validate_service.sh&lt;/code&gt; and watch automatic rollback fire.&lt;/p&gt;

&lt;h2&gt;
  
  
  9. Deployment strategies and rollback
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9-1. In-Place vs Blue/Green
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lens&lt;/th&gt;
&lt;th&gt;In-Place&lt;/th&gt;
&lt;th&gt;Blue/Green&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Approach&lt;/td&gt;
&lt;td&gt;Update the existing environment&lt;/td&gt;
&lt;td&gt;Spin up a new environment, swap traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Downtime&lt;/td&gt;
&lt;td&gt;Possible&lt;/td&gt;
&lt;td&gt;Largely avoidable&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;td&gt;Temporarily higher&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback&lt;/td&gt;
&lt;td&gt;Requires a redeploy&lt;/td&gt;
&lt;td&gt;Flip traffic back&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pre-test&lt;/td&gt;
&lt;td&gt;Hard&lt;/td&gt;
&lt;td&gt;Possible via a test listener&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Best fit&lt;/td&gt;
&lt;td&gt;Dev, small footprints&lt;/td&gt;
&lt;td&gt;Production, blast-radius-sensitive workloads&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Blue/Green on EC2 leans heavily on load balancer, target group, and Auto Scaling Group design.&lt;/p&gt;

&lt;h3&gt;
  
  
  9-2. Load balancer integration
&lt;/h3&gt;

&lt;p&gt;For Blue/Green on EC2 with CodeDeploy, the load balancer handles the swap between blue and green. Pair it with an Application Load Balancer or Network Load Balancer.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Element&lt;/th&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ALB&lt;/td&gt;
&lt;td&gt;Accept HTTP/HTTPS traffic from users&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production listener&lt;/td&gt;
&lt;td&gt;Serve normal traffic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test listener&lt;/td&gt;
&lt;td&gt;Verify the new environment before cutover&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Target groups&lt;/td&gt;
&lt;td&gt;Registered targets for blue and green&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auto Scaling Group&lt;/td&gt;
&lt;td&gt;Provisions the green environment&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The ALB Blue/Green flow is: build green, verify on the test listener, swap the production listener to green, keep blue around for a while.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Blue
  Currently serving production traffic

Green
  New version deployed, verified on the test listener

Switch
  Repoint the production listener at green

Retain
  Keep blue alive for a window so you can roll back fast
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9-3. EC2 deployment configurations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CodeDeployDefault.AllAtOnce&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update all instances at once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CodeDeployDefault.HalfAtATime&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update half at a time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CodeDeployDefault.OneAtATime&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;One instance at a time&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom&lt;/td&gt;
&lt;td&gt;Specify minimum healthy hosts as a count or percentage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Production decisions weigh instance count, load balancer, Auto Scaling, and health checks together.&lt;/p&gt;

&lt;h3&gt;
  
  
  9-4. Automatic rollback
&lt;/h3&gt;

&lt;p&gt;CodeDeploy can roll back automatically on deployment failure or when a CloudWatch alarm fires.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws cloudwatch put-metric-alarm &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--alarm-name&lt;/span&gt; codedeploy-5xx-alarm &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--namespace&lt;/span&gt; AWS/ApplicationELB &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--metric-name&lt;/span&gt; HTTPCode_Target_5XX_Count &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--statistic&lt;/span&gt; Sum &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--period&lt;/span&gt; 60 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--threshold&lt;/span&gt; 10 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--comparison-operator&lt;/span&gt; GreaterThanOrEqualToThreshold &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--evaluation-periods&lt;/span&gt; 2 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--treat-missing-data&lt;/span&gt; notBreaching
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For Blue/Green, hold the old environment for a while instead of decommissioning right away, so cutting back is fast if you need to.&lt;/p&gt;

&lt;h2&gt;
  
  
  10. Canary deployments to ECS and Lambda
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10-1. ECS Blue/Green
&lt;/h3&gt;

&lt;p&gt;With CodeDeploy on ECS the default is Blue/Green. No agent is required. Traffic is swapped via the ALB listener and target groups.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.0&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;TargetService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::ECS::Service&lt;/span&gt;
      &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;TaskDefinition&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:ecs:ap-northeast-1:123456789012:task-definition/my-task:1"&lt;/span&gt;
        &lt;span class="na"&gt;LoadBalancerInfo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;ContainerName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;app"&lt;/span&gt;
          &lt;span class="na"&gt;ContainerPort&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;80&lt;/span&gt;

&lt;span class="na"&gt;Hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;AfterAllowTestTraffic&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;arn:aws:lambda:ap-northeast-1:123456789012:function:ecs-test-hook"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A new task set serves the test listener; after verification, the production listener is swapped over.&lt;/p&gt;

&lt;h3&gt;
  
  
  10-2. ECS deployment configurations
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Configuration&lt;/th&gt;
&lt;th&gt;Behavior&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CodeDeployDefault.ECSAllAtOnce&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Cut all traffic at once&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CodeDeployDefault.ECSCanary10Percent5Minutes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Send 10%, wait 5 minutes, then the rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CodeDeployDefault.ECSCanary10Percent15Minutes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Send 10%, wait 15 minutes, then the rest&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CodeDeployDefault.ECSLinear10PercentEvery1Minutes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add 10% every minute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CodeDeployDefault.ECSLinear10PercentEvery3Minutes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Add 10% every 3 minutes&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With NLB, only &lt;code&gt;CodeDeployDefault.ECSAllAtOnce&lt;/code&gt; is supported among the predefined options.&lt;/p&gt;

&lt;h3&gt;
  
  
  10-3. Lambda deployments
&lt;/h3&gt;

&lt;p&gt;For Lambda, function versions plus an alias let you shift traffic incrementally.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.0&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;myFunction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::Lambda::Function&lt;/span&gt;
      &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;Name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;my-function"&lt;/span&gt;
        &lt;span class="na"&gt;Alias&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;live"&lt;/span&gt;
        &lt;span class="na"&gt;CurrentVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1"&lt;/span&gt;
        &lt;span class="na"&gt;TargetVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2"&lt;/span&gt;

&lt;span class="na"&gt;Hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;BeforeAllowTraffic&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;before-allow-traffic-hook"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;AfterAllowTraffic&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;after-allow-traffic-hook"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Lambda supports AllAtOnce, Canary10Percent variants, and Linear10PercentEvery variants. In production, Canary or Linear is easier to roll out safely while you watch metrics.&lt;/p&gt;

&lt;h3&gt;
  
  
  10-4. ECS and Lambda hooks
&lt;/h3&gt;

&lt;p&gt;Both ECS and Lambda support Lambda hooks for verification before and after the traffic shift.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Common hook&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ECS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AfterAllowTestTraffic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Verify the new task set on the test listener&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BeforeAllowTraffic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Final pre-cutover check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;ECS&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AfterAllowTraffic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Post-cutover verification&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda&lt;/td&gt;
&lt;td&gt;&lt;code&gt;BeforeAllowTraffic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Pre-traffic-shift check&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Lambda&lt;/td&gt;
&lt;td&gt;&lt;code&gt;AfterAllowTraffic&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Post-traffic-shift metric check&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Hook functions return success or failure. A failure halts the deployment and triggers rollback per configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  11. CodePipeline fundamentals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  11-1. What CodePipeline is
&lt;/h3&gt;

&lt;p&gt;AWS CodePipeline orchestrates source, build, test, approval, and deployment as connected stages.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline&lt;/td&gt;
&lt;td&gt;The whole workflow&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stage&lt;/td&gt;
&lt;td&gt;Logical grouping like Source, Build, Deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Action&lt;/td&gt;
&lt;td&gt;A single step inside a stage&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Artifact&lt;/td&gt;
&lt;td&gt;The thing passed between stages&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Transition&lt;/td&gt;
&lt;td&gt;The handoff between stages&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  11-2. Source, build, and deploy providers
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Common providers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Source&lt;/td&gt;
&lt;td&gt;CodeCommit, GitHub, GitLab, Bitbucket, S3, ECR&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build&lt;/td&gt;
&lt;td&gt;CodeBuild, Jenkins&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Test&lt;/td&gt;
&lt;td&gt;CodeBuild, Manual approval, Lambda Invoke&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy&lt;/td&gt;
&lt;td&gt;CodeDeploy, CloudFormation, ECS, S3, Elastic Beanstalk, AppConfig&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Invoke&lt;/td&gt;
&lt;td&gt;Lambda&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;With GitHub, the Source action references a CodeConnections connection.&lt;/p&gt;

&lt;h3&gt;
  
  
  11-3. V1 vs V2
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lens&lt;/th&gt;
&lt;th&gt;V1&lt;/th&gt;
&lt;th&gt;V2&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pricing&lt;/td&gt;
&lt;td&gt;Per active pipeline&lt;/td&gt;
&lt;td&gt;Per action-minute&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Trigger filters&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline-level variables&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Git tag triggers&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;PR, branch, path filters&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stage conditions&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stage rollback&lt;/td&gt;
&lt;td&gt;Not supported&lt;/td&gt;
&lt;td&gt;Supported&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For new pipelines, V2 is the default. For typical workloads running a moderate number of times per month, V2 can also work out cheaper.&lt;/p&gt;

&lt;h3&gt;
  
  
  11-4. Pricing notes
&lt;/h3&gt;

&lt;p&gt;CodePipeline V1 is billed monthly per active pipeline. V2 is billed per action-minute, excluding manual approvals and custom actions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Free tier&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;V1&lt;/td&gt;
&lt;td&gt;1 active pipeline per month&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;V2&lt;/td&gt;
&lt;td&gt;100 action-minutes per month&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For example, a V2 pipeline that runs Source, Build, and Deploy for 2 minutes each comes out to roughly 6 action-minutes per run. The real billing rounds per action, so always check the latest pricing page for the actual rules.&lt;/p&gt;

&lt;h2&gt;
  
  
  12. CodePipeline V2 in practice
&lt;/h2&gt;

&lt;h3&gt;
  
  
  12-1. Trigger filters
&lt;/h3&gt;

&lt;p&gt;V2 lets you gate connection-based sources (like GitHub) on branch, tag, file path, or pull request conditions.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Filter&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Branch&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;main&lt;/code&gt;, &lt;code&gt;release/*&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tag&lt;/td&gt;
&lt;td&gt;Match &lt;code&gt;v*&lt;/code&gt;, exclude &lt;code&gt;*-beta&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;File path&lt;/td&gt;
&lt;td&gt;Only when &lt;code&gt;src/**&lt;/code&gt; changes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pull request&lt;/td&gt;
&lt;td&gt;Created, updated, closed&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To keep documentation-only changes from triggering production pipelines, exclude &lt;code&gt;docs/**&lt;/code&gt; and &lt;code&gt;*.md&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  12-2. Pipeline variables
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Kind&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline-level variables&lt;/td&gt;
&lt;td&gt;&lt;code&gt;DEPLOY_ENV=staging&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Action output variables&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;IMAGE_TAG&lt;/code&gt; from CodeBuild&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Namespaced variables&lt;/td&gt;
&lt;td&gt;&lt;code&gt;#{SourceVariables.CommitId}&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;To pass values from CodeBuild downstream, use &lt;code&gt;exported-variables&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;env&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;exported-variables&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;IMAGE_TAG&lt;/span&gt;

&lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;IMAGE_TAG=$(echo $CODEBUILD_RESOLVED_SOURCE_VERSION | cut -c 1-7)&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "IMAGE_TAG=$IMAGE_TAG"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12-3. Manual approval
&lt;/h3&gt;

&lt;p&gt;Always put a Manual approval action in front of production.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Setting&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;SNS notification&lt;/td&gt;
&lt;td&gt;Send the approval request to email or chat&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review URL&lt;/td&gt;
&lt;td&gt;Link to staging, change set, or dashboard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Comment&lt;/td&gt;
&lt;td&gt;Capture reason on approve or reject&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Timeout&lt;/td&gt;
&lt;td&gt;Up to 7 days&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws codepipeline put-approval-result &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--pipeline-name&lt;/span&gt; my-pipeline &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stage-name&lt;/span&gt; Approval &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--action-name&lt;/span&gt; ManualApproval &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--token&lt;/span&gt; &amp;lt;approval-token&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--result&lt;/span&gt; &lt;span class="nv"&gt;summary&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"LGTM"&lt;/span&gt;,status&lt;span class="o"&gt;=&lt;/span&gt;Approved
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12-4. Notifications and EventBridge
&lt;/h3&gt;

&lt;p&gt;CodePipeline state changes flow through EventBridge. Trigger a Lambda on failure, or push to SNS or AWS Chatbot.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws events put-rule &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; codepipeline-failed-rule &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--event-pattern&lt;/span&gt; &lt;span class="s1"&gt;'{
    "source": ["aws.codepipeline"],
    "detail": {
      "state": ["FAILED"]
    }
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A clean split is SNS for approval-style notifications and EventBridge + Chatbot for pipeline-wide failure alerts.&lt;/p&gt;

&lt;p&gt;SNS is well suited to emailing reviewers. For Slack or Microsoft Teams, pair AWS Chatbot with an SNS topic.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Create an SNS topic&lt;/span&gt;
aws sns create-topic &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; codepipeline-approval-topic

&lt;span class="c"&gt;# Subscribe an email address&lt;/span&gt;
aws sns subscribe &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--topic-arn&lt;/span&gt; arn:aws:sns:ap-northeast-1:123456789012:codepipeline-approval-topic &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--protocol&lt;/span&gt; email &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--notification-endpoint&lt;/span&gt; reviewer@example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  12-5. JSON definitions and IaC management
&lt;/h3&gt;

&lt;p&gt;Console-built pipelines can be exported as JSON and version-controlled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Export the pipeline definition&lt;/span&gt;
aws codepipeline get-pipeline &lt;span class="nt"&gt;--name&lt;/span&gt; my-pipeline &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; pipeline.json

&lt;span class="c"&gt;# Create from JSON&lt;/span&gt;
aws codepipeline create-pipeline &lt;span class="nt"&gt;--cli-input-json&lt;/span&gt; file://pipeline.json

&lt;span class="c"&gt;# Update an existing pipeline&lt;/span&gt;
aws codepipeline update-pipeline &lt;span class="nt"&gt;--cli-input-json&lt;/span&gt; file://pipeline.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In production, manage the pipeline itself with CloudFormation, CDK, or Terraform.&lt;/p&gt;

&lt;h3&gt;
  
  
  12-6. From staging to production
&lt;/h3&gt;

&lt;p&gt;Pipelines that touch production deploy to staging first, validate, and then promote.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source
Build
DeployToStaging
SmokeTest
ManualApproval
DeployToProduction
PostDeployCheck
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pack the manual approval request with everything the reviewer needs: staging URL, change summary, commit ID, CodeBuild test report, CloudFormation change set. The reviewer must be able to answer "what am I approving?".&lt;/p&gt;

&lt;h2&gt;
  
  
  13. Advanced pipeline design
&lt;/h2&gt;

&lt;h3&gt;
  
  
  13-1. Multi-stage layouts
&lt;/h3&gt;

&lt;p&gt;Real pipelines almost never go Build straight to production. Insert multiple stages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source
Build
UnitTest
IntegrationTest
DeployToStaging
Approval
DeployToProduction
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Separating responsibilities makes failures easy to localize.&lt;/p&gt;

&lt;h3&gt;
  
  
  13-2. Parallel actions
&lt;/h3&gt;

&lt;p&gt;Within a stage, actions with the same &lt;code&gt;runOrder&lt;/code&gt; run in parallel.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;runOrder 1: UnitTest, Lint, SecurityScan
runOrder 2: SmokeTest
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parallelizing tests cuts wall-clock time. When actions have artifact dependencies, split them across &lt;code&gt;runOrder&lt;/code&gt; values.&lt;/p&gt;

&lt;h3&gt;
  
  
  13-3. Multiple sources and artifacts
&lt;/h3&gt;

&lt;p&gt;When the front end and back end, or the app and infra, live in separate repos, use multiple Source actions.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;

&lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Main source is at $CODEBUILD_SRC_DIR"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Infra source is at $CODEBUILD_SRC_DIR_infra"&lt;/span&gt;

&lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;secondary-artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;app-artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/*'&lt;/span&gt;
      &lt;span class="na"&gt;base-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dist&lt;/span&gt;
    &lt;span class="na"&gt;cfn-artifact&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/*'&lt;/span&gt;
      &lt;span class="na"&gt;base-directory&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;infra&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Name artifacts clearly. Downstream actions will reference them.&lt;/p&gt;

&lt;h3&gt;
  
  
  13-4. CloudFormation integration
&lt;/h3&gt;

&lt;p&gt;CodePipeline supports a CloudFormation deploy action.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Action mode&lt;/th&gt;
&lt;th&gt;Use&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CREATE_UPDATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create or update a stack directly&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DELETE_ONLY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Delete a stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;REPLACE_ON_FAILURE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Replace a failed stack&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CHANGE_SET_CREATE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create a change set&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CHANGE_SET_EXECUTE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Execute a change set&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For safe production rollouts, do CHANGE_SET_CREATE, then manual approval, then CHANGE_SET_EXECUTE.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2010-09-09"&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Simple S3 bucket for the CodePipeline demo&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;DemoBucket&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AWS::S3::Bucket&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;BucketEncryption&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;ServerSideEncryptionConfiguration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;ServerSideEncryptionByDefault&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
              &lt;span class="na"&gt;SSEAlgorithm&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AES256&lt;/span&gt;
      &lt;span class="na"&gt;PublicAccessBlockConfiguration&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;BlockPublicAcls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;BlockPublicPolicy&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;IgnorePublicAcls&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
        &lt;span class="na"&gt;RestrictPublicBuckets&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Running CloudFormation directly is fine, but the change-set-then-approve-then-execute pattern is safer for production.&lt;/p&gt;

&lt;h3&gt;
  
  
  13-5. Cross-account deployment
&lt;/h3&gt;

&lt;p&gt;When the dev account's CodePipeline deploys into a production account, design S3, KMS, AssumeRole, and the target-service permissions across accounts.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Element&lt;/th&gt;
&lt;th&gt;Setup&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Dev account S3&lt;/td&gt;
&lt;td&gt;Allow access from the production role&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dev account KMS&lt;/td&gt;
&lt;td&gt;Grant decrypt to the production role&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production account IAM&lt;/td&gt;
&lt;td&gt;Role assumable by CodePipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production account targets&lt;/td&gt;
&lt;td&gt;CodeDeploy, CloudFormation, ECS, etc.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Set &lt;code&gt;roleArn&lt;/code&gt; on the Deploy action in the production account to point at the cross-account role.&lt;/p&gt;

&lt;h3&gt;
  
  
  13-6. Cross-region and Lambda Invoke
&lt;/h3&gt;

&lt;p&gt;For cross-region deployments, set &lt;code&gt;region&lt;/code&gt; on the action. Each region needs its own artifact store.&lt;/p&gt;

&lt;p&gt;Lambda Invoke actions are great for Slack notifications, DB migrations, external API calls, and pre-deploy checks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;

&lt;span class="n"&gt;codepipeline&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;boto3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;client&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;codepipeline&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;lambda_handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="n"&gt;job_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;CodePipeline.job&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="c1"&gt;# Custom logic goes here
&lt;/span&gt;        &lt;span class="n"&gt;codepipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put_job_success_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;jobId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;job_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;codepipeline&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;put_job_failure_result&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
            &lt;span class="n"&gt;jobId&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;job_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="n"&gt;failureDetails&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;type&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;JobFailed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;message&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;exc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Always send either success or failure back to CodePipeline. Without it, the action waits until it times out.&lt;/p&gt;

&lt;h2&gt;
  
  
  14. Building a CI/CD pipeline from scratch
&lt;/h2&gt;

&lt;h3&gt;
  
  
  14-1. The setup
&lt;/h3&gt;

&lt;p&gt;The reference setup in this article uses GitHub, CodePipeline V2, CodeBuild, CodeDeploy, and EC2.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart LR
    G[GitHub] --&amp;gt; P[CodePipeline V2]
    P --&amp;gt; S[Source]
    S --&amp;gt; B[CodeBuild]
    B --&amp;gt; D[CodeDeploy]
    D --&amp;gt; E[EC2 Apache]
    B --&amp;gt; A[(S3 Artifacts)]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  14-2. Resources you will create
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Category&lt;/th&gt;
&lt;th&gt;Resources&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Source&lt;/td&gt;
&lt;td&gt;GitHub repo, CodeConnections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build&lt;/td&gt;
&lt;td&gt;CodeBuild project, CloudWatch Logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Artifacts&lt;/td&gt;
&lt;td&gt;S3 artifact bucket&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy&lt;/td&gt;
&lt;td&gt;CodeDeploy application, deployment group&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Runtime&lt;/td&gt;
&lt;td&gt;EC2, security group, IAM instance profile&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Orchestration&lt;/td&gt;
&lt;td&gt;CodePipeline V2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permissions&lt;/td&gt;
&lt;td&gt;EC2, CodeBuild, CodeDeploy, CodePipeline roles&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  14-3. Repository layout
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;aws-code-series-handson/
├── buildspec.yml
├── appspec.yml
├── index.html
├── css/
│   └── style.css
├── js/
│   └── app.js
├── tests/
│   └── test_app.sh
└── scripts/
    ├── install_dependencies.sh
    ├── stop_server.sh
    ├── start_server.sh
    └── validate_service.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;buildspec.yml&lt;/code&gt; runs the tests and emits the artifact for CodePipeline. &lt;code&gt;appspec.yml&lt;/code&gt; defines the on-EC2 layout and lifecycle scripts.&lt;/p&gt;

&lt;h3&gt;
  
  
  14-4. &lt;code&gt;buildspec.yml&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.2&lt;/span&gt;

&lt;span class="na"&gt;phases&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;install&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Preparing dependencies"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chmod +x tests/test_app.sh&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;chmod +x scripts/*.sh&lt;/span&gt;
  &lt;span class="na"&gt;pre_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Running tests"&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./tests/test_app.sh&lt;/span&gt;
  &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Producing artifacts"&lt;/span&gt;
  &lt;span class="na"&gt;post_build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;commands&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;echo "Build complete"&lt;/span&gt;

&lt;span class="na"&gt;artifacts&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;**/*'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  14-5. &lt;code&gt;appspec.yml&lt;/code&gt;
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0.0&lt;/span&gt;
&lt;span class="na"&gt;os&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;linux&lt;/span&gt;

&lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;source&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/&lt;/span&gt;
    &lt;span class="na"&gt;destination&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/var/www/html&lt;/span&gt;

&lt;span class="na"&gt;hooks&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;BeforeInstall&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/install_dependencies.sh&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;
      &lt;span class="na"&gt;runas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;ApplicationStop&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/stop_server.sh&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;
      &lt;span class="na"&gt;runas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;ApplicationStart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/start_server.sh&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;
      &lt;span class="na"&gt;runas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
  &lt;span class="na"&gt;ValidateService&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;location&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;scripts/validate_service.sh&lt;/span&gt;
      &lt;span class="na"&gt;timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;300&lt;/span&gt;
      &lt;span class="na"&gt;runas&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;root&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  14-6. Validating the flow
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;Expected result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Healthy commit&lt;/td&gt;
&lt;td&gt;Source, Build, Deploy all succeed after push&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failed test&lt;/td&gt;
&lt;td&gt;Build halts, no Deploy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Failed deploy&lt;/td&gt;
&lt;td&gt;Deploy fails, rollback if configured&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Manual re-run&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;start-pipeline-execution&lt;/code&gt; re-triggers&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stage retry&lt;/td&gt;
&lt;td&gt;Retry only the failed stage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check pipeline state&lt;/span&gt;
aws codepipeline get-pipeline-state &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; code-series-demo-pipeline &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--query&lt;/span&gt; &lt;span class="s1"&gt;'stageStates[*].{Stage:stageName,Status:latestExecution.status}'&lt;/span&gt;

&lt;span class="c"&gt;# Manual run&lt;/span&gt;
aws codepipeline start-pipeline-execution &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; code-series-demo-pipeline

&lt;span class="c"&gt;# Retry only the failed actions&lt;/span&gt;
aws codepipeline retry-stage-execution &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--pipeline-name&lt;/span&gt; code-series-demo-pipeline &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stage-name&lt;/span&gt; Deploy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--pipeline-execution-id&lt;/span&gt; &amp;lt;execution-id&amp;gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--retry-mode&lt;/span&gt; FAILED_ACTIONS
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  14-7. Cleanup
&lt;/h3&gt;

&lt;p&gt;Wrong delete order will leave you blocked by dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CodePipeline
CodeDeploy deployment group
CodeDeploy application
CodeBuild project
EC2 instance
Security group
S3 bucket objects
S3 bucket
IAM instance profile
IAM role
CodeConnections connection
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Empty the S3 bucket before deleting it. Detach the IAM role from the instance profile before deleting the role.&lt;/p&gt;

&lt;h2&gt;
  
  
  15. Security and IAM design
&lt;/h2&gt;

&lt;h3&gt;
  
  
  15-1. CI/CD security layers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;flowchart TB
    A[IAM and authentication] --&amp;gt; B[Secrets management]
    B --&amp;gt; C[S3 and KMS encryption]
    C --&amp;gt; D[VPC and network controls]
    D --&amp;gt; E[CloudTrail and CloudWatch]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A CI/CD pipeline is a privileged path into production, so it deserves the same level of protection as the application itself.&lt;/p&gt;

&lt;h3&gt;
  
  
  15-2. Service role design
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Role&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;th&gt;Avoid&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeBuild&lt;/td&gt;
&lt;td&gt;S3, CloudWatch Logs, ECR when needed&lt;/td&gt;
&lt;td&gt;Admin permissions, unneeded EC2 access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeDeploy&lt;/td&gt;
&lt;td&gt;EC2 tag read, ELB, ASG, S3 read&lt;/td&gt;
&lt;td&gt;EC2 create or delete&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodePipeline&lt;/td&gt;
&lt;td&gt;CodeBuild start, CodeDeploy start, S3, CodeConnections&lt;/td&gt;
&lt;td&gt;Direct server operations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EC2&lt;/td&gt;
&lt;td&gt;Fetch revisions from S3, SSM&lt;/td&gt;
&lt;td&gt;Admin permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;It is tempting to start broad. Just make sure you tighten down after things work.&lt;/p&gt;

&lt;h3&gt;
  
  
  15-3. A CodeBuild custom policy
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Version"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"Statement"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CloudWatchLogs"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"logs:CreateLogGroup"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"logs:CreateLogStream"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"logs:PutLogEvents"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:logs:ap-northeast-1:123456789012:log-group:/aws/codebuild/*"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Sid"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"S3Artifacts"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Effect"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Allow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Action"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:PutObject"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"s3:GetBucketLocation"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"Resource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-artifact-bucket"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="s2"&gt;"arn:aws:s3:::my-artifact-bucket/*"&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For ECR pushes, add &lt;code&gt;ecr:GetAuthorizationToken&lt;/code&gt;, &lt;code&gt;ecr:BatchCheckLayerAvailability&lt;/code&gt;, &lt;code&gt;ecr:InitiateLayerUpload&lt;/code&gt;, &lt;code&gt;ecr:UploadLayerPart&lt;/code&gt;, &lt;code&gt;ecr:CompleteLayerUpload&lt;/code&gt;, and &lt;code&gt;ecr:PutImage&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  15-4. Secrets management
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Approach&lt;/th&gt;
&lt;th&gt;Good for&lt;/th&gt;
&lt;th&gt;Watch out for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Plain environment variables&lt;/td&gt;
&lt;td&gt;Non-sensitive settings&lt;/td&gt;
&lt;td&gt;Never use for secrets&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SSM Parameter Store&lt;/td&gt;
&lt;td&gt;API keys, per-environment values&lt;/td&gt;
&lt;td&gt;Use SecureString&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets Manager&lt;/td&gt;
&lt;td&gt;DB credentials&lt;/td&gt;
&lt;td&gt;Account for cost and rotation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KMS&lt;/td&gt;
&lt;td&gt;Encryption keys&lt;/td&gt;
&lt;td&gt;Lock down key policies&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;CI/CD logs live longer than you think. Never let secrets land in build logs, and watch out for failure-time debug output too.&lt;/p&gt;

&lt;h3&gt;
  
  
  15-5. Encrypting the artifact bucket
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3api put-bucket-encryption &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--bucket&lt;/span&gt; my-artifact-bucket &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--server-side-encryption-configuration&lt;/span&gt; &lt;span class="s1"&gt;'{
    "Rules": [{
      "ApplyServerSideEncryptionByDefault": {
        "SSEAlgorithm": "aws:kms"
      },
      "BucketKeyEnabled": true
    }]
  }'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Force HTTPS, block unintended public access, and for cross-account use, do not forget the KMS key policy.&lt;/p&gt;

&lt;h2&gt;
  
  
  16. Cost, monitoring, and logs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  16-1. Cost levers
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Target&lt;/th&gt;
&lt;th&gt;Optimization&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeBuild&lt;/td&gt;
&lt;td&gt;Cache, right-size compute, set timeouts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodePipeline V2&lt;/td&gt;
&lt;td&gt;Branch, tag, and path filters to skip useless runs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeDeploy&lt;/td&gt;
&lt;td&gt;Spin verification EC2 only when needed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3&lt;/td&gt;
&lt;td&gt;Lifecycle rules for old artifacts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CloudWatch Logs&lt;/td&gt;
&lt;td&gt;Configure retention&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KMS&lt;/td&gt;
&lt;td&gt;Avoid an exploding key count&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For V2, every avoided execution is direct cost savings. Excluding &lt;code&gt;docs/**&lt;/code&gt; and README changes from production pipelines pays for itself fast.&lt;/p&gt;

&lt;h3&gt;
  
  
  16-2. Metrics to watch
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Watch&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeBuild&lt;/td&gt;
&lt;td&gt;Build failures, build duration, queue wait&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeDeploy&lt;/td&gt;
&lt;td&gt;Deployment failures, rollback counts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodePipeline&lt;/td&gt;
&lt;td&gt;Pipeline failures, stage failures, pending approvals&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;EC2, ALB&lt;/td&gt;
&lt;td&gt;5xx, latency, target health&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3&lt;/td&gt;
&lt;td&gt;Artifact bucket usage&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;For production, alert on even one CodePipeline or CodeDeploy failure.&lt;/p&gt;

&lt;h3&gt;
  
  
  16-3. Where logs live
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Service&lt;/th&gt;
&lt;th&gt;Location&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CodeBuild&lt;/td&gt;
&lt;td&gt;CloudWatch Logs &lt;code&gt;/aws/codebuild/&amp;lt;project&amp;gt;&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeDeploy Agent&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/var/log/aws/codedeploy-agent/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeDeploy deployment&lt;/td&gt;
&lt;td&gt;&lt;code&gt;/opt/codedeploy-agent/deployment-root/&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodePipeline&lt;/td&gt;
&lt;td&gt;CloudTrail, EventBridge, console history&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;CloudWatch Logs Insights makes failure searches easy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fields @timestamp, @message
| filter @message like /ERROR|FAIL|Exception/
| sort @timestamp desc
| limit 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  16-4. Cost monitoring
&lt;/h3&gt;

&lt;p&gt;Set up AWS Budgets to track CodeBuild, CodePipeline, S3, CloudWatch Logs, and KMS spend. The classic hands-on cost traps are forgotten EC2 instances, S3 buckets, CloudWatch Logs, and ECR images.&lt;/p&gt;

&lt;h2&gt;
  
  
  17. Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  17-1. CodeBuild
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;DOWNLOAD_SOURCE_FAILED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;GitHub connection or repo permission&lt;/td&gt;
&lt;td&gt;Check the CodeConnections status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLIENT_ERROR&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;buildspec.yml&lt;/code&gt; syntax&lt;/td&gt;
&lt;td&gt;Look for YAML, indentation, and tab issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;BUILD_FAILED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Test failure or missing dependency&lt;/td&gt;
&lt;td&gt;Read CloudWatch Logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;UPLOAD_ARTIFACTS_FAILED&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Insufficient S3 permissions&lt;/td&gt;
&lt;td&gt;Check the CodeBuild role's S3 access&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Docker daemon error&lt;/td&gt;
&lt;td&gt;Missing privileged mode&lt;/td&gt;
&lt;td&gt;Enable Privileged mode&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Out of memory&lt;/td&gt;
&lt;td&gt;Compute too small&lt;/td&gt;
&lt;td&gt;Bump compute size or split tests&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  17-2. CodeDeploy
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Agent unresponsive&lt;/td&gt;
&lt;td&gt;Agent stopped or not installed&lt;/td&gt;
&lt;td&gt;&lt;code&gt;systemctl status codedeploy-agent&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ScriptFailed&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Hook script failure&lt;/td&gt;
&lt;td&gt;Read logs under &lt;code&gt;deployment-root&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;ScriptTimedOut&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Timeout too short, or hung process&lt;/td&gt;
&lt;td&gt;Extend timeout or fix the script&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;HEALTH_CONSTRAINTS&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Not enough healthy instances&lt;/td&gt;
&lt;td&gt;Recheck deployment config and health checks&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;S3 403&lt;/td&gt;
&lt;td&gt;EC2 role lacks S3 access&lt;/td&gt;
&lt;td&gt;Check role permissions and bucket policy&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;First-deploy ApplicationStop fails&lt;/td&gt;
&lt;td&gt;No previous revision&lt;/td&gt;
&lt;td&gt;Often expected on the first run&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  17-3. CodePipeline
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Error&lt;/th&gt;
&lt;th&gt;Cause&lt;/th&gt;
&lt;th&gt;Fix&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Source failed&lt;/td&gt;
&lt;td&gt;GitHub connection or repo permission&lt;/td&gt;
&lt;td&gt;Recheck CodeConnections&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build failed&lt;/td&gt;
&lt;td&gt;CodeBuild-side failure&lt;/td&gt;
&lt;td&gt;Read CodeBuild logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy failed&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;appspec&lt;/code&gt;, agent, or permission issue&lt;/td&gt;
&lt;td&gt;Read CodeDeploy logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Insufficient permissions&lt;/td&gt;
&lt;td&gt;Service role too narrow&lt;/td&gt;
&lt;td&gt;Check the CodePipeline role&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Action configuration error&lt;/td&gt;
&lt;td&gt;Action misconfigured&lt;/td&gt;
&lt;td&gt;Check provider, artifact, and region&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  17-4. CLI you will use a lot
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Block transitions into the Deploy stage&lt;/span&gt;
aws codepipeline disable-stage-transition &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--pipeline-name&lt;/span&gt; my-pipeline &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stage-name&lt;/span&gt; Deploy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transition-type&lt;/span&gt; Inbound &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--reason&lt;/span&gt; &lt;span class="s2"&gt;"Maintenance"&lt;/span&gt;

&lt;span class="c"&gt;# Re-enable transitions&lt;/span&gt;
aws codepipeline enable-stage-transition &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--pipeline-name&lt;/span&gt; my-pipeline &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--stage-name&lt;/span&gt; Deploy &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--transition-type&lt;/span&gt; Inbound

&lt;span class="c"&gt;# Re-run with a specific commit&lt;/span&gt;
aws codepipeline start-pipeline-execution &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--name&lt;/span&gt; my-pipeline &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--source-revisions&lt;/span&gt; &lt;span class="nv"&gt;actionName&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;Source,revisionType&lt;span class="o"&gt;=&lt;/span&gt;COMMIT_ID,revisionValue&lt;span class="o"&gt;=&lt;/span&gt;abc1234
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  18. Patterns and team practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  18-1. Pipeline design patterns
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Pattern&lt;/th&gt;
&lt;th&gt;Good for&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Single branch&lt;/td&gt;
&lt;td&gt;Solo work, small experiments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Branch-based&lt;/td&gt;
&lt;td&gt;Typical team development&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Multi-account&lt;/td&gt;
&lt;td&gt;Organizations that isolate production permissions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Microservice-per-pipeline&lt;/td&gt;
&lt;td&gt;Independently releasable services&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;A branch-based layout is the easiest starting point.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;feature/*
  Run tests only on pull requests

develop
  Auto-deploy to dev

main
  Auto-deploy to staging
  Manual approval, then auto-deploy to production

release/*
  Lock release candidates and verify
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  18-2. Team rules
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Rule&lt;/th&gt;
&lt;th&gt;Detail&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;main&lt;/code&gt; protection&lt;/td&gt;
&lt;td&gt;No direct push, PR required&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Review&lt;/td&gt;
&lt;td&gt;At least one approval&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tests&lt;/td&gt;
&lt;td&gt;Required checks must pass before merge&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Production approval&lt;/td&gt;
&lt;td&gt;Manual approval in CodePipeline&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback&lt;/td&gt;
&lt;td&gt;Documented procedure and on-call owner&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Naming convention&lt;/td&gt;
&lt;td&gt;&lt;code&gt;&amp;lt;env&amp;gt;-&amp;lt;service&amp;gt;-&amp;lt;purpose&amp;gt;-pipeline&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tagging&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Project&lt;/code&gt;, &lt;code&gt;Environment&lt;/code&gt;, &lt;code&gt;Owner&lt;/code&gt;, &lt;code&gt;CostCenter&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  18-3. Incident response flow
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Alert detected
Assess blast radius
Identify root cause
Roll back or pause the pipeline
Apply a workaround
Apply the real fix
Postmortem
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a pipeline fails, do not stop at "fix the failure". Cover detection, notification, rollback, and prevention.&lt;/p&gt;

&lt;h3&gt;
  
  
  18-4. Pre-flight checklist
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Lens&lt;/th&gt;
&lt;th&gt;Check&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Source&lt;/td&gt;
&lt;td&gt;CodeCommit or GitHub, connection method decided&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Build&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;buildspec.yml&lt;/code&gt; defines tests and artifacts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Deploy&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;appspec.yml&lt;/code&gt; and hooks are organized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Pipeline&lt;/td&gt;
&lt;td&gt;V2, trigger filters, manual approval considered&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rollback&lt;/td&gt;
&lt;td&gt;CodeDeploy paired with a CloudWatch alarm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Permissions&lt;/td&gt;
&lt;td&gt;Every service role minimized&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Secrets&lt;/td&gt;
&lt;td&gt;Stored in Parameter Store or Secrets Manager&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;EventBridge, SNS, Chatbot, CloudWatch wired up&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cost&lt;/td&gt;
&lt;td&gt;Wasted runs, log retention, S3 residue under control&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Operations&lt;/td&gt;
&lt;td&gt;Naming, tagging, incident response, cleanup defined&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;Thanks for reading this far.&lt;/p&gt;

&lt;p&gt;Looked at one at a time, the AWS Code family is a collection of fairly modest services. CodeCommit handles source. CodeBuild builds. CodeDeploy deploys. CodePipeline glues them together.&lt;/p&gt;

&lt;p&gt;The real value shows up when you combine them. A push triggers tests, an artifact is stored, staging gets updated, an approver signs off, production receives the change, failures stop the train, and logs let you find the root cause. Once all of that holds together, CI/CD stops being "nice automation" and becomes "a safe way to release".&lt;/p&gt;

&lt;p&gt;As of 2026, CodeCommit's return to GA puts the "fully inside AWS" option back on the table. Pairing GitHub or GitLab with CodeBuild, CodeDeploy, and CodePipeline as the AWS-side runtime is also still very much a real choice.&lt;/p&gt;

&lt;p&gt;What matters more than service selection is the shape of the flow: small changes, automated verification, deliberate approval, deliberate rollback, and a system you can learn from when it fails.&lt;/p&gt;

&lt;p&gt;See you in the next one.&lt;/p&gt;

&lt;h2&gt;
  
  
  About this article
&lt;/h2&gt;

&lt;p&gt;This article is the English adaptation of a Japanese post I originally wrote on Qiita, a developer community popular in Japan.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://qiita.com/miruky/items/REPLACE_WITH_QIITA_ID" rel="noopener noreferrer"&gt;https://qiita.com/miruky/items/REPLACE_WITH_QIITA_ID&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;h3&gt;
  
  
  AWS Code family official docs
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/products/developer-tools/" rel="noopener noreferrer"&gt;AWS Developer Tools - AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/codecommit/" rel="noopener noreferrer"&gt;AWS CodeCommit - AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/devops/aws-codecommit-returns-to-general-availability/" rel="noopener noreferrer"&gt;The Future of AWS CodeCommit - AWS DevOps Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html" rel="noopener noreferrer"&gt;AWS CodeBuild User Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/codebuild/pricing/" rel="noopener noreferrer"&gt;AWS CodeBuild pricing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codebuild/latest/userguide/build-spec-ref.html" rel="noopener noreferrer"&gt;Build specification reference for CodeBuild - AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codebuild/latest/userguide/build-caching.html" rel="noopener noreferrer"&gt;Cache builds to improve performance - AWS CodeBuild&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codedeploy/latest/userguide/welcome.html" rel="noopener noreferrer"&gt;AWS CodeDeploy User Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codedeploy/latest/userguide/deployment-configurations.html" rel="noopener noreferrer"&gt;Working with deployment configurations in CodeDeploy - AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html" rel="noopener noreferrer"&gt;AWS CodePipeline User Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codepipeline/latest/userguide/pipeline-types.html" rel="noopener noreferrer"&gt;Pipeline types - AWS CodePipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codepipeline/latest/userguide/pipelines-triggers.html" rel="noopener noreferrer"&gt;Automate starting pipelines using triggers and filtering - AWS CodePipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/codepipeline/pricing/" rel="noopener noreferrer"&gt;AWS CodePipeline pricing&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Connections, adjacent services, and operations
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2025/10/aws-service-availability/" rel="noopener noreferrer"&gt;AWS Service Availability Updates - AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/about-aws/whats-new/2024/03/aws-codeconnections-formerly-codestar-connections/" rel="noopener noreferrer"&gt;Introducing AWS CodeConnections, formerly known as AWS CodeStar Connections - AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/dtconsole/latest/userguide/rename.html" rel="noopener noreferrer"&gt;Connections rename - AWS Developer Tools console&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codepipeline/latest/userguide/action-reference-CodestarConnectionSource.html" rel="noopener noreferrer"&gt;CodeStarSourceConnection for GitHub, GitLab, Bitbucket - AWS CodePipeline&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codecatalyst/latest/userguide/doc-history.html" rel="noopener noreferrer"&gt;Amazon CodeCatalyst document history&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/codeguru/latest/reviewer-ug/codeguru-reviewer-availability-change.html" rel="noopener noreferrer"&gt;Amazon CodeGuru Reviewer availability change&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/whitepapers/latest/practicing-continuous-integration-continuous-delivery/welcome.html" rel="noopener noreferrer"&gt;Practicing Continuous Integration and Continuous Delivery on AWS&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>cicd</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>A Roundup of Engineering “Laws” from the English-Speaking World That Are Surprisingly Well-Known in Japan</title>
      <dc:creator>miruky</dc:creator>
      <pubDate>Thu, 21 May 2026 14:28:56 +0000</pubDate>
      <link>https://dev.to/miruky/a-roundup-of-engineering-laws-from-the-english-speaking-world-that-are-surprisingly-well-known-in-3lkg</link>
      <guid>https://dev.to/miruky/a-roundup-of-engineering-laws-from-the-english-speaking-world-that-are-surprisingly-well-known-in-3lkg</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Hi, I'm miruky.&lt;/p&gt;

&lt;p&gt;Over a recent long weekend, I went out for drinks with an older friend from high school who works as a tech lead. We ended up talking about a project of his that had recently gone sideways, and at some point he said something like, "honestly, it was a textbook case of Brooks's Law." I had seen the term in a book before, but, embarrassingly enough, I could not quite recall what it actually meant.&lt;/p&gt;

&lt;p&gt;This is not just about Brooks's Law. There is a long list of "the Law of X", "the X Principle", and "the X Effect" that every engineer seems to know. Other professions have their own proverbs and rules of thumb, but our field is unusually fond of inventing them. Probably some of it comes from English-speaking software culture, which has always enjoyed naming patterns.&lt;/p&gt;

&lt;p&gt;A few off the top of my head: Brooks's Law, Conway's Law, Hyrum's Law, the Joshua Tree Principle, Stone Soup, the Boiling Frog, reinventing the wheel, yak shaving, and so on.&lt;/p&gt;

&lt;p&gt;You can absolutely live without memorizing any of these, but I want to keep them within reach, both as a piece of engineering literacy and as a personal commitment to not repeat past mistakes. Some of them genuinely earn their keep during code review. So in this article, I am organizing the famous ones, each with a short definition and a note on when it actually matters in practice. Treat it as a personal cheatsheet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A note on scope&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This article prioritizes "do engineers actually use this in conversation?" and "does it show up in classic software engineering literature?" over strict academic accuracy. More obscure terms are intentionally omitted.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Laws&lt;/li&gt;
&lt;li&gt;Other principles, strategies, and metaphors&lt;/li&gt;
&lt;li&gt;How to use these terms&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  1. Laws
&lt;/h2&gt;

&lt;p&gt;The star rating is my own rough sense of "how often this term actually comes up in engineering conversations and code reviews". It is not a strict ranking, just a feel for how often it shows up in technical writing, design discussions, and pull request reviews.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Stars&lt;/th&gt;
&lt;th&gt;Meaning&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;★★★★★&lt;/td&gt;
&lt;td&gt;5 stars. Heard often in conversation and code review&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;★★★★☆&lt;/td&gt;
&lt;td&gt;4 stars. Common knowledge; comes up in design discussions and small talk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;★★★☆☆&lt;/td&gt;
&lt;td&gt;3 stars. Known by some, but less frequent in day-to-day talk&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;★★☆☆☆&lt;/td&gt;
&lt;td&gt;2 stars. Appears in books and classics, less so in conversation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;★☆☆☆☆&lt;/td&gt;
&lt;td&gt;1 star. Fairly obscure; barely used in this article&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;First, the ones that are most commonly framed as "laws" in everyday software development.&lt;/p&gt;

&lt;h3&gt;
  
  
  1-1. Project and organization laws
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Conway's Law ★★★★☆
&lt;/h4&gt;

&lt;p&gt;The structure of a system tends to mirror the communication structure of the organization that built it.&lt;/p&gt;

&lt;p&gt;If your auth team, payments team, and inventory team never talk to each other, you should not be surprised when that disconnect shows up in your API boundaries and your screen transitions. It looks like an architecture conversation, but a lot of the time it is really an org design conversation. The term shows up constantly in discussions of microservice boundaries, team splits, and responsibility lines.&lt;/p&gt;

&lt;h4&gt;
  
  
  Brooks's Law ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Adding people to a late software project can make it even later.&lt;/p&gt;

&lt;p&gt;This is not the simple "do not add people, ever" rule it is sometimes flattened into. The point is that onboarding, alignment, reviews, merges, and decision coordination all grow with team size, so dropping new people into a burning project does not produce instant relief. It is the standard warning you hear before someone proposes "let's just throw more headcount at it."&lt;/p&gt;

&lt;h4&gt;
  
  
  Parkinson's Law ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Work expands so as to fill the time available for its completion.&lt;/p&gt;

&lt;p&gt;If the deadline is a week, the work takes a week. If it is a month, it takes a month. Meetings behave the same way: a 30-minute agenda will happily absorb a 60-minute slot. This is the reason short deadlines, short review windows, and short meetings tend to be a good default. It is the same reason summer break homework somehow always gets finished only in the last few days, no matter how much time you started with.&lt;/p&gt;

&lt;h4&gt;
  
  
  Ninety-Ninety Rule ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;The first 90% of the code accounts for the first 90% of the development time. The remaining 10% of the code accounts for the other 90% of the development time.&lt;/p&gt;

&lt;p&gt;This one is attributed to Tom Cargill at Bell Labs and is also quoted in Jon Bentley's &lt;em&gt;Programming Pearls&lt;/em&gt;. The punchline is that the numbers sum to 180%. It is a tidy explanation of why "we're basically done, just a few tweaks left" is rarely trustworthy. The final edge cases, error handling, documentation, tests, and operational work tend to be heavier than anyone estimated.&lt;/p&gt;

&lt;h4&gt;
  
  
  Parkinson's Law of Triviality (Bikeshedding) ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;People tend to spend disproportionate time on small, easy-to-grasp problems rather than on the important and difficult ones.&lt;/p&gt;

&lt;p&gt;The classic example is a committee that breezes past the design of a nuclear reactor but argues for hours about the color of the bike shed. In engineering, this shows up as architecture decisions getting waved through while a code review stalls on a variable name, a button color, or microscopic copy choices.&lt;/p&gt;

&lt;h4&gt;
  
  
  Peter Principle ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;People tend to be promoted until they reach a position where they are no longer effective, and then stay there.&lt;/p&gt;

&lt;p&gt;Promoting your strongest developer to manager does not automatically produce your strongest manager. Being great at writing code and being great at hiring, evaluating, shaping teams, and negotiating budgets are different skills. Worth keeping in mind whenever you are thinking about engineering manager or tech lead role design.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hofstadter's Law ★★☆☆☆
&lt;/h4&gt;

&lt;p&gt;It always takes longer than you expect, even when you take into account Hofstadter's Law.&lt;/p&gt;

&lt;p&gt;This one self-references on purpose. It lands during estimation, release planning, migrations, and legacy rewrites: "I padded the estimate this time, and even with that, we still ran out of time." A short, accurate description of how schedules actually behave.&lt;/p&gt;

&lt;h3&gt;
  
  
  1-2. Design and code laws
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Postel's Law ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Be conservative in what you send, be liberal in what you accept. Also known as the Robustness Principle, from early TCP/IP RFCs.&lt;/p&gt;

&lt;p&gt;In the early internet, this kind of tolerance helped systems interoperate. In modern web and security contexts, being too liberal in what you accept can mean fuzzy specs and exploitable corners, so "do not be too lenient on input" is also part of the conversation now. Input validation usually wants the opposite of pure tolerance.&lt;/p&gt;

&lt;h4&gt;
  
  
  Law of Demeter ★★★★☆
&lt;/h4&gt;

&lt;p&gt;An object should only talk to its immediate neighbors. Also known as the Principle of Least Knowledge.&lt;/p&gt;

&lt;p&gt;Long chains like &lt;code&gt;user.getCompany().getAddress().getZip()&lt;/code&gt; quietly couple the caller to the internal structure of every object in the chain. The moment any of those internals change, the call site breaks. This law shows up in class design, domain modeling, and API design.&lt;/p&gt;

&lt;h4&gt;
  
  
  Law of Leaky Abstractions ★★★★☆
&lt;/h4&gt;

&lt;p&gt;All non-trivial abstractions, to some degree, leak.&lt;/p&gt;

&lt;p&gt;Using an ORM does not let you forget about SQL. Using the cloud does not let you forget about networking and IAM. Using React or Next.js does not free you from how the browser actually works. Abstractions are convenient, but the layer underneath never fully disappears.&lt;/p&gt;

&lt;h4&gt;
  
  
  Kernighan's Law ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it.&lt;/p&gt;

&lt;p&gt;A direct shot at one-liners, nested ternaries, gratuitous metaprogramming, and clever abstractions that read like riddles. Code is judged not by "can I write this?" but by "can I still read this in three months?" and "can I still fix this when it breaks at 2am?"&lt;/p&gt;

&lt;h4&gt;
  
  
  Atwood's Law ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Any application that can be written in JavaScript will eventually be written in JavaScript.&lt;/p&gt;

&lt;p&gt;A neat summary of how web technologies have escaped the browser into the server, the desktop, mobile, the CLI, and IoT. If you have spent any time in the Electron / Node.js / React Native part of the world, this one writes itself.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hyrum's Law ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;With a sufficient number of users of an API, all observable behaviors of your system will be depended on by somebody.&lt;/p&gt;

&lt;p&gt;Anyone who has ever shipped a public API has lived through this. The accidental key order in a response, an error message that happens to be stable, a request that happens to complete in a predictable amount of time: even when none of that is part of the documented contract, somebody will end up depending on it. Anything visible can become a contract.&lt;/p&gt;

&lt;h4&gt;
  
  
  Linus's Law ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;Given enough eyeballs, all bugs are shallow. The phrase was coined by Eric S. Raymond in &lt;em&gt;The Cathedral and the Bazaar&lt;/em&gt; and named in tribute to Linus Torvalds's development model, not by Linus himself.&lt;/p&gt;

&lt;p&gt;Roughly: with enough people looking at the code, bugs get found and root-caused faster. Useful when explaining the value of code review, open source, audits, and bug bounties. The catch is that headcount alone does not buy safety; reviewers need relevant expertise, code needs to be reviewable, and you need tests and reproducible builds to back any of it up.&lt;/p&gt;

&lt;h4&gt;
  
  
  Zawinski's Law ★★☆☆☆
&lt;/h4&gt;

&lt;p&gt;Every program attempts to expand until it can read mail.&lt;/p&gt;

&lt;p&gt;The serious version: useful tools accumulate features until they have quietly become full platforms. The tiny task tracker grows a chat tab, then a calendar, then mail, then AI, then workflows.&lt;/p&gt;

&lt;h4&gt;
  
  
  Sturgeon's Law ★★☆☆☆
&lt;/h4&gt;

&lt;p&gt;Ninety percent of everything is crap.&lt;/p&gt;

&lt;p&gt;Bluntly useful when evaluating libraries, sample code, blog posts, OSS projects, or AI-generated code. The job is not to admire everything that exists, but to develop an eye for the worthwhile 10%.&lt;/p&gt;

&lt;h3&gt;
  
  
  1-3. Performance and scale laws
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Moore's Law ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Transistor density on integrated circuits has doubled at a roughly constant cadence.&lt;/p&gt;

&lt;p&gt;Originally a prediction about component count on a chip, later stretched into a broader story about ever-increasing compute. Physical limits and manufacturing costs have made the simple version harder to maintain, so the current reality is more nuanced than the classic framing.&lt;/p&gt;

&lt;h4&gt;
  
  
  Amdahl's Law ★★★★☆
&lt;/h4&gt;

&lt;p&gt;The speedup you get from parallelizing a program is limited by the part that cannot be parallelized.&lt;/p&gt;

&lt;p&gt;A cold shower for "just add more servers and it will be faster." If the bottleneck is a DB lock, a single queue, an external API, or some synchronous step in the middle, more workers will not save you past a certain point. It is the standard mental model when discussing multithreading, distributed processing, and host-side overhead in GPU workloads.&lt;/p&gt;

&lt;h4&gt;
  
  
  Wirth's Law ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;Software gets slower faster than hardware gets faster.&lt;/p&gt;

&lt;p&gt;Hardware keeps improving, and yet perceived speed often does not, thanks to ballooning dependencies, more abstraction layers, Electron-everything, and an endless stream of new features. Comes up whenever someone is talking about performance work or trimming bloat.&lt;/p&gt;

&lt;h4&gt;
  
  
  Metcalfe's Law ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;The value of a network grows roughly with the square of the number of its users.&lt;/p&gt;

&lt;p&gt;With &lt;code&gt;n&lt;/code&gt; participants, the number of possible pairs is &lt;code&gt;n(n-1)/2&lt;/code&gt;, which scales close to &lt;code&gt;n²&lt;/code&gt; for large &lt;code&gt;n&lt;/code&gt;. That is the basis for the "value proportional to the square of users" framing. Common in explanations of social networks, marketplaces, telecom networks, and developer communities.&lt;/p&gt;

&lt;h4&gt;
  
  
  Gustafson's Law ★★☆☆☆
&lt;/h4&gt;

&lt;p&gt;If you can grow the problem with the machine, parallelization pays off more than Amdahl suggests.&lt;/p&gt;

&lt;p&gt;Amdahl's Law asks "how fast can I make a fixed workload?". Gustafson's Law asks "now that I have more compute, how much bigger a problem can I tackle?". You see it most often in HPC, batch processing, and large-scale data work.&lt;/p&gt;

&lt;h3&gt;
  
  
  1-4. Metrics and decision laws
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Pareto Principle (80/20 Rule) ★★★★★
&lt;/h4&gt;

&lt;p&gt;A small share of causes is responsible for a large share of the outcomes. Famous well outside engineering.&lt;/p&gt;

&lt;p&gt;Most incidents tend to cluster in a few features. Most support tickets tend to cluster on a few screens. Most revenue tends to come from a few customers. Handy when prioritizing critical bugs, key users, and recurring support themes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Murphy's Law ★★★★★
&lt;/h4&gt;

&lt;p&gt;The compact version: anything that can go wrong, will go wrong.&lt;/p&gt;

&lt;p&gt;In practice, this is not "expect doom" but "stop assuming nothing will fail, and start designing for what happens when it does". It is the friendly companion of failure design, retries, monitoring, backups, idempotency, and fail-safe defaults. The classic illustration is the slice of buttered toast that, when knocked off the table, lands butter-side down.&lt;/p&gt;

&lt;h4&gt;
  
  
  Goodhart's Law ★★★★☆
&lt;/h4&gt;

&lt;p&gt;When a measure becomes a target, it ceases to be a good measure. The pithy form is usually credited to Marilyn Strathern's restatement.&lt;/p&gt;

&lt;p&gt;Make test coverage a target and you get tests that exist mostly to lift the number. Make velocity a performance metric and ticket splitting becomes a game. Make incident count a goal and small incidents stop getting reported. Metrics are useful as signals, but they get corrupted the moment they become objectives in themselves.&lt;/p&gt;

&lt;h4&gt;
  
  
  Gall's Law ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;A complex system that works is invariably found to have evolved from a simple system that worked.&lt;/p&gt;

&lt;p&gt;Starting from a giant ideal architecture rarely beats starting from something small that works and then growing it. The principle bites hard on new products, big replatform projects, and platform overhauls.&lt;/p&gt;

&lt;h4&gt;
  
  
  Campbell's Law ★★☆☆☆
&lt;/h4&gt;

&lt;p&gt;The more any quantitative indicator is used for decision-making, the more it tends to distort and corrupt the processes it is intended to monitor.&lt;/p&gt;

&lt;p&gt;A close cousin of Goodhart's Law, more often cited in evaluation, education, and policy contexts. In engineering organizations, tying compensation directly to PR count, commit count, story points, or review count tends to produce predictable distortion.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Other principles, strategies, and metaphors
&lt;/h2&gt;

&lt;p&gt;This second group is not strictly "laws", but it includes principles, strategies, indicators, metaphors, and phrases from classic books that show up constantly in engineering conversations.&lt;/p&gt;

&lt;h3&gt;
  
  
  2-1. Design principles
&lt;/h3&gt;

&lt;h4&gt;
  
  
  DRY ★★★★★
&lt;/h4&gt;

&lt;p&gt;I have been called out on this in real code review. Short for &lt;em&gt;Don't Repeat Yourself&lt;/em&gt;: do not duplicate the same piece of knowledge in multiple places.&lt;/p&gt;

&lt;p&gt;It is often misread as "do not write the same line twice." The thing you really must not duplicate is &lt;em&gt;knowledge&lt;/em&gt;: business rules, constants, schemas, specifications. Forcing two coincidentally similar chunks of code into a single shared abstraction tends to backfire when the two reasons for change start diverging. &lt;em&gt;The Pragmatic Programmer&lt;/em&gt; is the canonical reference.&lt;/p&gt;

&lt;h4&gt;
  
  
  KISS ★★★★★
&lt;/h4&gt;

&lt;p&gt;Short for &lt;em&gt;Keep It Simple, Stupid&lt;/em&gt;: prefer the simplest design that solves the problem.&lt;/p&gt;

&lt;p&gt;This shows up in design, API shape, runbooks, and team rules. Choose a structure you can read, explain, and recover from when it breaks, over one that merely looks clever. Simple really is best, more often than not.&lt;/p&gt;

&lt;h4&gt;
  
  
  YAGNI ★★★★★
&lt;/h4&gt;

&lt;p&gt;Short for &lt;em&gt;You Aren't Gonna Need It&lt;/em&gt;: do not build features you do not need yet. An Extreme Programming staple.&lt;/p&gt;

&lt;p&gt;This is not "ignore the future." It is "do not pay today's cost for tomorrow's hypothetical." A surprising amount of code written "just in case" never gets used in the form you imagined.&lt;/p&gt;

&lt;h4&gt;
  
  
  SOLID ★★★★★
&lt;/h4&gt;

&lt;p&gt;A mnemonic for five object-oriented design principles.&lt;/p&gt;

&lt;p&gt;Single Responsibility, Open-Closed, Liskov Substitution, Interface Segregation, and Dependency Inversion. SOLID gets some legitimate criticism in modern contexts, but as a shared vocabulary for talking about dependencies, reasons for change, and responsibility boundaries, it is still very much in use.&lt;/p&gt;

&lt;h4&gt;
  
  
  Single Responsibility Principle ★★★★★
&lt;/h4&gt;

&lt;p&gt;I hear this one a lot. A module or a class should have only one reason to change.&lt;/p&gt;

&lt;p&gt;It does &lt;em&gt;not&lt;/em&gt; mean "one method per class." If changes to your user view, your billing rules, and your DB storage format all flow through the same class, that class is probably doing too much.&lt;/p&gt;

&lt;h4&gt;
  
  
  Separation of Concerns ★★★★★
&lt;/h4&gt;

&lt;p&gt;Do not blend unrelated concerns into the same place.&lt;/p&gt;

&lt;p&gt;When UI, domain logic, DB access, auth, logging, notifications, and external API calls all live tangled together, every change becomes scary. This is the idea sitting under layered architecture, clean architecture, and MVC.&lt;/p&gt;

&lt;h4&gt;
  
  
  Principle of Least Privilege ★★★★★
&lt;/h4&gt;

&lt;p&gt;Genuinely essential. Grant only the minimum privileges required.&lt;/p&gt;

&lt;p&gt;Applies broadly: IAM, DB permissions, CI/CD, GitHub Actions, AI agents, MCP tools, admin dashboards, the lot. The default is not "open it up until people stop complaining", but "figure out the smallest scope that works and hand out exactly that."&lt;/p&gt;

&lt;h4&gt;
  
  
  Open-Closed Principle ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Software entities should be open for extension, but closed for modification.&lt;/p&gt;

&lt;p&gt;The goal is to add a new payment method or a new notification target without rewriting half the existing code. Pushed too far it produces an abstraction graveyard, so it needs to live in tension with YAGNI.&lt;/p&gt;

&lt;h4&gt;
  
  
  Principle of Least Astonishment ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Behave in a way that does not surprise the user.&lt;/p&gt;

&lt;p&gt;Applies to function names, API responses, UI, default values, and CLI flags. A function called &lt;code&gt;deleteUser()&lt;/code&gt; that actually performs a hard delete when the rest of the system uses soft deletes, or a &lt;code&gt;get&lt;/code&gt; endpoint that mutates the database, will surprise people. Surprise is a bug.&lt;/p&gt;

&lt;h4&gt;
  
  
  Unix Philosophy ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Build small tools, make them compose well.&lt;/p&gt;

&lt;p&gt;The familiar slogans, "do one thing and do it well", "communicate via text streams", "compose small tools", come from Unix culture. The influence is clearly visible in CLIs, pipes, microservices, and modern developer tooling.&lt;/p&gt;

&lt;h4&gt;
  
  
  WET ★★☆☆☆
&lt;/h4&gt;

&lt;p&gt;The anti-DRY: variously expanded as &lt;em&gt;Write Everything Twice&lt;/em&gt;, &lt;em&gt;Write Every Time&lt;/em&gt;, or &lt;em&gt;We Enjoy Typing&lt;/em&gt;. It describes a bad state.&lt;/p&gt;

&lt;p&gt;You end up with the same logic, the same rule, or the same configuration scattered across the codebase. When the spec changes, you fix one copy and forget the other; docs drift away from the code; tests still assert the old behavior. The DRY / WET pairing is one of the more fun bits of vocabulary in the field.&lt;/p&gt;

&lt;h4&gt;
  
  
  ETC (Easier to Change) ★★☆☆☆
&lt;/h4&gt;

&lt;p&gt;A guiding value from &lt;em&gt;The Pragmatic Programmer&lt;/em&gt; (20th anniversary edition): make code easier to change.&lt;/p&gt;

&lt;p&gt;The book explicitly frames ETC as a &lt;em&gt;value&lt;/em&gt;, not a rule. DRY, KISS, YAGNI, and Separation of Concerns can all be read as instances of "will this make the next change easier or harder?". When you are stuck between two designs, asking that question often unblocks the decision.&lt;/p&gt;

&lt;h3&gt;
  
  
  2-2. Methods and metaphors from classic books
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Prototype ★★★★★
&lt;/h4&gt;

&lt;p&gt;Code you write specifically to learn, with the expectation of throwing it away.&lt;/p&gt;

&lt;p&gt;Useful for de-risking an unfamiliar technology, a UI direction, a library, or a performance profile. The danger is conflating "things I am going to grow into production code" with "things I am going to throw away." Code written to be thrown away has a nasty habit of being shipped instead.&lt;/p&gt;

&lt;h4&gt;
  
  
  Reinventing the Wheel ★★★★★
&lt;/h4&gt;

&lt;p&gt;You hear this constantly. Rebuilding something that already exists, for no good reason.&lt;/p&gt;

&lt;p&gt;Standard examples include writing your own framework or, worse, your own crypto without checking the existing ecosystem first. A clear caveat: rebuilding something for learning purposes, or to satisfy a constraint that no off-the-shelf option supports, can be valuable. The problem is ignoring existing knowledge and repeating other people's mistakes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Boiling Frog ★★★★☆
&lt;/h4&gt;

&lt;p&gt;When conditions worsen slowly, people tend to miss the danger. &lt;em&gt;The Pragmatic Programmer&lt;/em&gt; introduces it alongside Stone Soup.&lt;/p&gt;

&lt;p&gt;The story (a frog in slowly heating water failing to notice the danger) is used as a metaphor for slow decay. Builds get one minute slower. Tests get slightly flakier. A few more type errors get ignored. Each step is small enough to overlook, but the cumulative effect is a much slower team. This is the shape of technical debt. The biological version is not actually accurate; treat it strictly as a software-engineering metaphor.&lt;/p&gt;

&lt;h4&gt;
  
  
  Broken Windows Theory ★★★★☆
&lt;/h4&gt;

&lt;p&gt;If you tolerate small messes, larger messes follow. Famous outside engineering as well.&lt;/p&gt;

&lt;p&gt;In code: failing tests, sloppy naming, abandoned TODOs, unformatted files, perpetually red CI. Letting these sit broadcasts the message "this repo is fine to treat carelessly," which then attracts more carelessness.&lt;/p&gt;

&lt;h4&gt;
  
  
  Rubber Duck Debugging ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Explain the problem out loud and you often spot the bug yourself.&lt;/p&gt;

&lt;p&gt;The audience does not have to be human. A rubber duck on your desk works fine. Walking through the code line by line forces you to confront the gaps in your own understanding, which makes it useful as a pre-review self-check too.&lt;/p&gt;

&lt;h4&gt;
  
  
  No Silver Bullet ★★★★☆
&lt;/h4&gt;

&lt;p&gt;There is no single technology that can deliver a tenfold productivity improvement to software development on its own. Frederick Brooks's famous argument.&lt;/p&gt;

&lt;p&gt;New languages, frameworks, clouds, and AI tools do not erase the essential difficulties of understanding requirements, managing complexity, accommodating change, and communicating with people. A handy phrase for tempering hype around new technology. ("Silver bullet" here is the folkloric weapon that kills monsters in one shot.)&lt;/p&gt;

&lt;h4&gt;
  
  
  Yak Shaving ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Doing a chain of prerequisite tasks before you can get to the thing you actually wanted to do.&lt;/p&gt;

&lt;p&gt;"I just wanted to fix this small bug, but to run the tests I had to upgrade Node, and to upgrade Node I had to fix CI, and to fix CI I had to revisit permissions, and now I have no idea what I was originally doing." Very common during environment setup and dependency upgrades.&lt;/p&gt;

&lt;h4&gt;
  
  
  Stone Soup ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;A metaphor for kickstarting a small change that ends up pulling other people in.&lt;/p&gt;

&lt;p&gt;The folk tale: a traveler offers to make a soup from a stone, sets up a pot, and asks each villager to contribute one small ingredient. By the end, there is a real soup.&lt;/p&gt;

&lt;p&gt;In a codebase, the equivalent is something like: "Let's refactor the whole module" goes nowhere, but a small, concrete improvement PR ships. Someone else sees it and adds tests. Someone else adds docs. Before long, an improvement effort exists.&lt;/p&gt;

&lt;h4&gt;
  
  
  Tracer Bullets ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;Cut a thin slice all the way through the system, end to end, as your first real implementation.&lt;/p&gt;

&lt;p&gt;The metaphor is borrowed from tracer rounds in ballistics: rounds that glow in flight so you can correct your aim in real time.&lt;/p&gt;

&lt;p&gt;This is not the same as a throwaway prototype. The tracer-bullet slice is meant to be real, just narrow: UI, API, DB, deploy, and monitoring, all wired up at the smallest viable scope, then widened over time. It overlaps with the idea of a "walking skeleton."&lt;/p&gt;

&lt;p&gt;The difference from a prototype is intent. A prototype is meant to be thrown away. A tracer-bullet slice is meant to be kept and grown. Both are tools for fast feedback, but they live different lives.&lt;/p&gt;

&lt;h3&gt;
  
  
  2-3. Cognition and learning metaphors
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Joshua Tree Principle ★★★★★
&lt;/h4&gt;

&lt;p&gt;This one resonates with me. Once you learn the name of a thing, you start noticing it everywhere.&lt;/p&gt;

&lt;p&gt;Not so much an academic law as a metaphor that gets phrased as the &lt;em&gt;Joshua Tree principle&lt;/em&gt; or &lt;em&gt;Joshua Tree epiphany&lt;/em&gt;. Learn the name "Hyrum's Law", and you start spotting "uh-oh, somebody is going to depend on this exact behavior" during API review. Design patterns, anti-patterns, incident patterns, and cognitive biases all become much easier to spot once you have a label for them.&lt;/p&gt;

&lt;h4&gt;
  
  
  Dunning-Kruger Effect ★★★★☆
&lt;/h4&gt;

&lt;p&gt;People with low ability in a domain tend to overestimate their ability.&lt;/p&gt;

&lt;p&gt;The pop version is "beginners are overconfident", but the real claim is subtler: the metacognitive skill needed to notice your own mistakes is one of the things you are missing in the first place. There is a clear parallel with over-trusting AI-generated code. In any unfamiliar area, hold back on certainty and insist on verification and review.&lt;/p&gt;

&lt;h4&gt;
  
  
  Confirmation Bias ★★★★☆
&lt;/h4&gt;

&lt;p&gt;The tendency to seek and weigh information that fits the hypothesis you already hold.&lt;/p&gt;

&lt;p&gt;In incident response, deciding "this is a DB problem" makes you read every log through DB-colored glasses. The same thing happens during performance tuning and code review. Forming a hypothesis is fine; the discipline is to also look for the evidence that would refute it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Occam's Razor ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Among competing explanations of equal predictive power, prefer the one with fewer assumptions.&lt;/p&gt;

&lt;p&gt;Named after the 14th-century philosopher and theologian William of Ockham. The original "do not multiply entities beyond necessity" is often described as shaving away unnecessary assumptions with a razor.&lt;/p&gt;

&lt;p&gt;In incident response, before reaching for an exotic distributed-systems bug, check the boring options first: a misconfiguration, a missing env var, a forgotten deploy, an unusual input, a time-zone bug. The simple explanation is not always right, but it is a strong opening hypothesis.&lt;/p&gt;

&lt;h4&gt;
  
  
  Chesterton's Fence ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Do not remove a fence you do not understand the purpose of, until you understand its purpose.&lt;/p&gt;

&lt;p&gt;The image, from G.K. Chesterton, is of someone walking down a road and finding a fence that seems pointless. The first move is not "tear it down because it serves no use", but "find out why it was built in the first place."&lt;/p&gt;

&lt;p&gt;In legacy code, when you find a strange &lt;code&gt;if&lt;/code&gt; branch or a baffling config switch, it is tempting to delete it on sight. But it may be the residue of a real production incident, a customer-specific requirement, or a regression workaround. Check logs, issues, commit history, and other engineers' memory before removing it.&lt;/p&gt;

&lt;h4&gt;
  
  
  Survivorship Bias ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;Drawing conclusions only from the cases that survived to be visible.&lt;/p&gt;

&lt;p&gt;Studying only successful startups, popular OSS, and viral blog posts will quietly convince you that "doing X is the path to success." What is missing from view is the much larger pile of efforts that did the same thing and failed. Worth holding in mind during tech selection and career conversations.&lt;/p&gt;

&lt;h4&gt;
  
  
  Baader-Meinhof Phenomenon (Frequency Illusion) ★★☆☆☆
&lt;/h4&gt;

&lt;p&gt;The feeling that a word you just learned is suddenly appearing everywhere.&lt;/p&gt;

&lt;p&gt;Right after picking up a new technical term, you start spotting it in your feed, in articles, in meetings. The world did not change, your attention did.&lt;/p&gt;

&lt;h3&gt;
  
  
  2-4. Architecture and distributed systems staples
&lt;/h3&gt;

&lt;h4&gt;
  
  
  CAP Theorem ★★★★★
&lt;/h4&gt;

&lt;p&gt;In a distributed system, you cannot simultaneously and perfectly satisfy consistency, availability, and partition tolerance.&lt;/p&gt;

&lt;p&gt;The "pick two out of three" phrasing is the famous one, but in practice it is more useful to think of CAP as describing a design choice that becomes visible when a network partition actually happens: under partition, do you preserve consistency or availability?&lt;/p&gt;

&lt;h4&gt;
  
  
  Idempotence ★★★★★
&lt;/h4&gt;

&lt;p&gt;A property where performing the same operation multiple times has the same effect as performing it once.&lt;/p&gt;

&lt;p&gt;More precisely: applying the operation once or many times results in the same intended effect on the server's state, even if the response payload varies. Networks fail. Retries happen. So a payment request, a webhook handler, or any critical operation needs to be safe to receive more than once without double-charging or duplicating effects. Crucial in payments, job processing, and API design.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fail-safe ★★★★★
&lt;/h4&gt;

&lt;p&gt;When something fails, fall toward the safer outcome.&lt;/p&gt;

&lt;p&gt;Authorization errors fall toward "deny", not "allow". An ambiguous payment state falls toward "hold", not "double-charge". A control system falls toward "stop", not "uncontrolled motion". Foundational in security and safety design.&lt;/p&gt;

&lt;h4&gt;
  
  
  Foolproof ★★★★★
&lt;/h4&gt;

&lt;p&gt;Design so that human error is unlikely to cause damage. The Japanese-coined equivalent is &lt;em&gt;poka-yoke&lt;/em&gt; from manufacturing.&lt;/p&gt;

&lt;p&gt;Add a confirmation step to delete buttons. Require typing the environment name to run destructive commands in production. Disable dangerous CLI flags by default. Make inputs into select boxes instead of free text. Leverage the system's design, not the user's vigilance, to prevent mistakes.&lt;/p&gt;

&lt;h4&gt;
  
  
  Eventual Consistency ★★★★☆
&lt;/h4&gt;

&lt;p&gt;Replicas do not agree immediately, but they will agree given enough time.&lt;/p&gt;

&lt;p&gt;Common in NoSQL stores, caches, event-driven systems, and async pipelines. A read immediately after a write may see the old value; given some time, all replicas converge.&lt;/p&gt;

&lt;h4&gt;
  
  
  Fail-fast ★★★★☆
&lt;/h4&gt;

&lt;p&gt;If something is wrong, stop early rather than carrying the problem forward.&lt;/p&gt;

&lt;p&gt;Missing config, malformed input, a dependency that is unreachable: better to fail right at the boundary than to propagate the problem into later stages of the system. Shows up in input validation, config checks, CI, and startup self-checks.&lt;/p&gt;

&lt;h4&gt;
  
  
  Backpressure ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;When a consumer cannot keep up, slow the producer down.&lt;/p&gt;

&lt;p&gt;You see this with queues, streams, rate-limited APIs, and log pipelines. If the consumer is stuck and the producer keeps pushing, memory grows, latency grows, and eventually something crashes. Backpressure is the discipline of flow control.&lt;/p&gt;

&lt;h4&gt;
  
  
  Graceful Degradation ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;When part of the system breaks, keep as much of the rest working as possible.&lt;/p&gt;

&lt;p&gt;If an external API goes down, keep the core flows alive. If recommendations are unavailable, still render the product list. If image processing is slow, still show the text. This is the language of degraded modes and resilience.&lt;/p&gt;

&lt;h3&gt;
  
  
  2-5. Organization and development strategy
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Bus Factor ★★★★☆
&lt;/h4&gt;

&lt;p&gt;A peculiarly engineering metric: the number of people who would need to disappear for the project to be in trouble.&lt;/p&gt;

&lt;p&gt;A bus factor of 1 means a single resignation, transfer, or extended absence can break the project. The term is shorthand for risk from siloed knowledge, weak documentation, and weak review coverage. You raise the bus factor with code review, pair work, runbooks, and rotation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Inverse Conway Maneuver ★★★☆☆
&lt;/h4&gt;

&lt;p&gt;Use Conway's Law in reverse: shape the organization to fit the architecture you want.&lt;/p&gt;

&lt;p&gt;"We want these service boundaries, so let's organize teams along those same boundaries." Sits naturally next to ideas like Team Topologies, platform teams, stream-aligned teams, and bounded contexts.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. How to use these terms
&lt;/h2&gt;

&lt;p&gt;The vocabulary above is useful, but it is not magic.&lt;/p&gt;

&lt;h3&gt;
  
  
  3-1. Do not let the name end the discussion
&lt;/h3&gt;

&lt;p&gt;"That's just Brooks's Law." "That's YAGNI." "That's Conway." If the conversation ends there, you are casting spells instead of thinking.&lt;/p&gt;

&lt;p&gt;The trick is to &lt;em&gt;follow up&lt;/em&gt; with something concrete.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Bad]&lt;/strong&gt;&lt;br&gt;
"That's YAGNI."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Good]&lt;/strong&gt;&lt;br&gt;
"Do we have a concrete requirement for that extension point this quarter?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Bad]&lt;/strong&gt;&lt;br&gt;
"Brooks's Law, so no."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;[Good]&lt;/strong&gt;&lt;br&gt;
"If we add people now, the onboarding and review overhead will probably cost us at least two weeks before it pays back."&lt;/p&gt;

&lt;p&gt;Names are shortcuts. Use them to start a deeper conversation, not to skip one.&lt;/p&gt;
&lt;h3&gt;
  
  
  3-2. Translate the classics into your context
&lt;/h3&gt;

&lt;p&gt;Books like &lt;em&gt;The Pragmatic Programmer&lt;/em&gt;, &lt;em&gt;The Mythical Man-Month&lt;/em&gt;, &lt;em&gt;The Unix Philosophy&lt;/em&gt;, and the rest of the classic software engineering canon still hold up. Plenty of what they describe is directly useful today.&lt;/p&gt;

&lt;p&gt;But pulling those terms straight into modern web development, cloud, AI agents, or distributed systems sometimes needs translation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stone Soup, today: ship a small, concrete improvement PR and let it pull others in.&lt;/li&gt;
&lt;li&gt;Boiling frog, today: ignore the slow drift of CI getting slower and type safety getting looser.&lt;/li&gt;
&lt;li&gt;Reinventing the wheel, today: building it yourself without checking the existing libraries. Still valuable as a learning exercise; harmful as a default reflex.&lt;/li&gt;
&lt;li&gt;Leaky abstractions, today: even with cloud and AI tooling, you cannot fully forget the layer below.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The point of the classics is not to memorize them. It is to give the awkward feelings you already have in real projects a name you can point at.&lt;/p&gt;

&lt;p&gt;And please, do not become the person who weaponizes English jargon to win arguments.&lt;/p&gt;
&lt;h2&gt;
  
  
  Wrap-up
&lt;/h2&gt;

&lt;p&gt;Thanks for reading this far.&lt;/p&gt;

&lt;p&gt;The famous engineering laws and metaphors are not just trivia. They give short names to &lt;em&gt;why estimates miss&lt;/em&gt;, &lt;em&gt;why org structure shows up in the code&lt;/em&gt;, &lt;em&gt;why public APIs ossify in odd places&lt;/em&gt;, &lt;em&gt;why metrics go bad&lt;/em&gt;, and &lt;em&gt;why technical debt grows quietly&lt;/em&gt;. Once you have the name, you can recall the whole pattern in a second.&lt;/p&gt;

&lt;p&gt;If there is one thing I would like you to take away from this article, it is that &lt;strong&gt;once you know the name of a thing, you start spotting it in the wild&lt;/strong&gt;. That is the Joshua Tree Principle in action.&lt;/p&gt;

&lt;p&gt;See you in the next one.&lt;/p&gt;
&lt;h2&gt;
  
  
  About this article
&lt;/h2&gt;

&lt;p&gt;This article is the English adaptation of a Japanese post I originally wrote on Qiita, a developer community popular in Japan.&lt;/p&gt;


&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://qiita.com/miruky/items/cef8169b4a10cdd790b5" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fqiita-user-contents.imgix.net%2Fhttps%253A%252F%252Fqiita-user-contents.imgix.net%252Fhttps%25253A%25252F%25252Fcdn.qiita.com%25252Fassets%25252Fpublic%25252Farticle-ogp-background-afbab5eb44e0b055cce1258705637a91.png%253Fixlib%253Drb-4.1.1%2526w%253D1200%2526blend64%253DaHR0cHM6Ly9xaWl0YS11c2VyLXByb2ZpbGUtaW1hZ2VzLmltZ2l4Lm5ldC9odHRwcyUzQSUyRiUyRnFpaXRhLWltYWdlLXN0b3JlLnMzLmFwLW5vcnRoZWFzdC0xLmFtYXpvbmF3cy5jb20lMkYwJTJGMzYzNzIwNCUyRnByb2ZpbGUtaW1hZ2VzJTJGMTc3NDQ0NTA3MD9peGxpYj1yYi00LjEuMSZhcj0xJTNBMSZmaXQ9Y3JvcCZtYXNrPWVsbGlwc2UmYmc9RkZGRkZGJmZtPXBuZzMyJnM9NzhlNWJjOTliMzcxMjIzNTdjNWQ1N2EyMTc3MzQyMGQ%2526blend-x%253D120%2526blend-y%253D467%2526blend-w%253D82%2526blend-h%253D82%2526blend-mode%253Dnormal%2526s%253D4251943b4cba54fb403a98b0c03f0bf4%3Fixlib%3Drb-4.1.1%26w%3D1200%26fm%3Djpg%26mark64%3DaHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjEuMSZ3PTk2MCZoPTMyNCZ0eHQ9JUUzJTgwJTkwJUUzJTgyJUE4JUUzJTgzJUIzJUUzJTgyJUI4JUUzJTgzJThCJUUzJTgyJUEyJUUzJTgxJUFFJUU2JTk1JTk5JUU5JUE0JThBJUUzJTgwJTkxJUUzJTgxJUFBJUUzJTgxJTlDJUUzJTgxJThCJUUzJTgyJUE4JUUzJTgzJUIzJUUzJTgyJUI4JUUzJTgzJThCJUUzJTgyJUEyJUU3JTk1JThDJUU5JTlBJTg4JUUzJTgxJUE3JUU2JTlDJTg5JUU1JTkwJThEJUUzJTgxJUFBJUUyJTk3JUFGJUUyJTk3JUFGJUUzJTgxJUFFJUU2JUIzJTk1JUU1JTg5JTg3JUU3JTlBJTg0JUUzJTgxJUFBJUUzJTgyJTg0JUUzJTgxJUE0JUUzJTgyJTkyJUUzJTgxJUJFJUUzJTgxJUE4JUUzJTgyJTgxJUUzJTgxJUE2JUUzJTgxJUJGJUUzJTgxJTlGJnR4dC1hbGlnbj1sZWZ0JTJDdG9wJnR4dC1jb2xvcj0lMjMxRTIxMjEmdHh0LWZvbnQ9SGlyYWdpbm8lMjBTYW5zJTIwVzYmdHh0LXNpemU9NTYmdHh0LXBhZD0wJnM9N2FiNmVjM2MwNmY1MmRjNmZhNzhiOGJiOTJhYzE0YjE%26mark-x%3D120%26mark-y%3D112%26blend64%3DaHR0cHM6Ly9xaWl0YS11c2VyLWNvbnRlbnRzLmltZ2l4Lm5ldC9-dGV4dD9peGxpYj1yYi00LjEuMSZ3PTgzOCZoPTU4JnR4dD0lNDBtaXJ1a3kmdHh0LWNvbG9yPSUyMzFFMjEyMSZ0eHQtZm9udD1IaXJhZ2lubyUyMFNhbnMlMjBXNiZ0eHQtc2l6ZT0zNiZ0eHQtcGFkPTAmcz03OTk2NjQ5OGIxYWQ1NDQxNjI5ZjM2ZTYzYTY3MzliZg%26blend-x%3D242%26blend-y%3D480%26blend-w%3D838%26blend-h%3D46%26blend-fit%3Dcrop%26blend-crop%3Dleft%252Cbottom%26blend-mode%3Dnormal%26s%3D1ae5eaa951b8a0ba2e2d09a9f11e7973" height="630" class="m-0" width="1200"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://qiita.com/miruky/items/cef8169b4a10cdd790b5" rel="noopener noreferrer" class="c-link"&gt;
            【エンジニアの教養】なぜかエンジニア界隈で有名な◯◯の法則的なやつをまとめてみた #Security - Qiita
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            前置き こんばんは、mirukyです。 この間のGW中に、高校時代の先輩（テックリード）と飲みに行きました。 そのとき先輩が経験した炎上プロジェクトの話になり、先輩が「ブルックスの法則ってあるじゃん。まさしくあれになってさ」みたいなことを言っていたのですが、本で見たこと...
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fcdn.qiita.com%2Fassets%2Ffavicons%2Fpublic%2Fproduction-c620d3e403342b1022967ba5e3db1aaa.ico" width="120" height="120"&gt;
          qiita.com
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Laws
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://hyrumslaw.com/" rel="noopener noreferrer"&gt;Hyrum's Law&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.melconway.com/Home/Committees_Paper.html" rel="noopener noreferrer"&gt;How Do Committees Invent? - Melvin E. Conway&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.rfc-editor.org/rfc/rfc761" rel="noopener noreferrer"&gt;RFC 761 DoD standard Transmission Control Protocol - RFC Editor&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.joelonsoftware.com/2002/11/11/the-law-of-leaky-abstractions/" rel="noopener noreferrer"&gt;The Law of Leaky Abstractions - Joel on Software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://catb.org/~esr/jargon/html/Z/Zawinskis-Law.html" rel="noopener noreferrer"&gt;Zawinski's Law - The Jargon File&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://catb.org/jargon/html/N/Ninety-Ninety-Rule.html" rel="noopener noreferrer"&gt;Ninety-Ninety Rule - The Jargon File&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.computerhistory.org/siliconengine/moores-law-predicts-the-future-of-integrated-circuits/" rel="noopener noreferrer"&gt;Moore's Law Predicts the Future of Integrated Circuits - Computer History Museum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ma.tt/2006/08/metcalfe%E2%80%99s-law-and-social-networks/" rel="noopener noreferrer"&gt;Metcalfe's Law and Social Networks - Matt Mullenweg&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://mathworld.wolfram.com/LittlesLaw.html" rel="noopener noreferrer"&gt;Little's Law - Wolfram MathWorld&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cs.nyu.edu/~apanda/classes/sp25/papers/gilbert02brewers.pdf" rel="noopener noreferrer"&gt;Brewer's Conjecture and the Feasibility of Consistent, Available, Partition-Tolerant Web Services&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lawsofsoftwareengineering.com/" rel="noopener noreferrer"&gt;The Laws of Software Engineering&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://forrt.org/glossary/english/goodhart_s_law/" rel="noopener noreferrer"&gt;Goodhart's Law - FORRT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ojp.gov/ncjrs/virtual-library/abstracts/assessing-impact-planned-social-change" rel="noopener noreferrer"&gt;Assessing the Impact of Planned Social Change - Office of Justice Programs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Classic books and principles
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://pragprog.com/titles/tpp20/the-pragmatic-programmer-20th-anniversary-edition/" rel="noopener noreferrer"&gt;The Pragmatic Programmer, 20th Anniversary Edition - Pragmatic Bookshelf&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.artima.com/articles/tracer-bullets-and-prototypes" rel="noopener noreferrer"&gt;Tracer Bullets and Prototypes - Artima&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://c2.com/xp/YouArentGonnaNeedIt.html" rel="noopener noreferrer"&gt;You Aren't Gonna Need It - C2 Wiki&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www2.ccs.neu.edu/research/demeter/demeter-method/LawOfDemeter/general-formulation.html" rel="noopener noreferrer"&gt;The Law of Demeter - Northeastern University&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://catb.org/esr/writings/taoup/html/ch01s06.html" rel="noopener noreferrer"&gt;Basics of the Unix Philosophy - Eric S. Raymond&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.cin.ufpe.br/~phmb/ip/MaterialDeEnsino/BrooksNoSilverBullet.html" rel="noopener noreferrer"&gt;No Silver Bullet - Frederick P. Brooks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Metaphors, cognition, and the rest
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging" rel="noopener noreferrer"&gt;Rubber duck debugging - Wikipedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.techtarget.com/whatis/definition/yak-shaving" rel="noopener noreferrer"&gt;Yak shaving - TechTarget&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://en.wiktionary.org/wiki/bus_factor" rel="noopener noreferrer"&gt;Bus factor - Wiktionary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.britannica.com/topic/Occams-razor" rel="noopener noreferrer"&gt;Occam's razor - Britannica&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://cir.nii.ac.jp/crid/1362262945663265024?lang=en" rel="noopener noreferrer"&gt;Unskilled and unaware of it - CiNii Research&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.oreilly.com/library/view/the-non-designers-design/9780321563088/ch01.html" rel="noopener noreferrer"&gt;The Joshua Tree Epiphany - O'Reilly&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://languagelog.ldc.upenn.edu/~myl/languagelog/archives/002849.html" rel="noopener noreferrer"&gt;The infrequency illusion - Language Log&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>programming</category>
      <category>softwareengineering</category>
      <category>career</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
