{"id":1278,"date":"2026-11-10T15:28:57","date_gmt":"2026-11-10T15:28:57","guid":{"rendered":"https:\/\/www.devopsschool.com\/tutorials\/?p=1278"},"modified":"2026-11-10T15:28:58","modified_gmt":"2026-11-10T15:28:58","slug":"aws-developer-services-console-lab-guide","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/tutorials\/aws-developer-services-console-lab-guide\/","title":{"rendered":"AWS Developer Services: Console Lab Guide"},"content":{"rendered":"\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th class=\"has-text-align-left\" data-align=\"left\">title<\/th><td class=\"has-text-align-left\" data-align=\"left\">AWS Developer Services: Gold-Standard Console Lab Guide<\/td><\/tr><tr><th class=\"has-text-align-left\" data-align=\"left\">subtitle<\/th><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit \u2022 CodeArtifact \u2022 CodeBuild \u2022 CodeDeploy \u2022 CodePipeline<\/td><\/tr><tr><th class=\"has-text-align-left\" data-align=\"left\">author<\/th><td class=\"has-text-align-left\" data-align=\"left\">Instructor Edition | Browser-Only Labs<\/td><\/tr><tr><th class=\"has-text-align-left\" data-align=\"left\">date<\/th><td class=\"has-text-align-left\" data-align=\"left\">10 November 2026<\/td><\/tr><tr><th class=\"has-text-align-left\" data-align=\"left\">lang<\/th><td class=\"has-text-align-left\" data-align=\"left\">en-US<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Course navigation<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Lab<\/th><th class=\"has-text-align-left\" data-align=\"left\">AWS service<\/th><th class=\"has-text-align-left\" data-align=\"left\">Practical result<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">1<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodeCommit<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Create a browser-authored repo, branch, PR and merge<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">2<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodeArtifact<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Configure a private npm repository and public upstream<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">3<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodeBuild<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Resolve dependencies, test, create a deployable ZIP<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">4<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodeDeploy<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Deploy the tested ZIP to AL2023 EC2 without SSH<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">5<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodePipeline<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Automate commit-triggered build and deployment<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">Instructor&#8217;s quick start<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Course outcome.<\/strong>&nbsp;Complete five connected, independently verifiable labs that take one small web application from source control through dependency acquisition, automated build and tests, manual deployment, and change-triggered continuous delivery. All user interactions take place in web browsers and the AWS Management Console.&nbsp;<strong>Learners never use a terminal, AWS CLI, CloudShell, Session Manager shell, or local Git client.<\/strong>&nbsp;The supplied build and deployment scripts execute automatically&nbsp;<em>inside managed AWS services<\/em>; they are configuration files, not manual lab commands.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Source starting point.<\/strong>&nbsp;The lab adapts the idea of the official AWS GitHub repository&nbsp;<strong>aws-samples\/aws-codedeploy-samples<\/strong>, specifically&nbsp;<strong>applications\/SampleApp_Linux<\/strong>, into an Amazon Linux 2023-friendly static website with a meaningful Node.js build using an npm package from CodeArtifact. Original sample:&nbsp;<a href=\"https:\/\/github.com\/aws-samples\/aws-codedeploy-samples\/tree\/master\/applications\/SampleApp_Linux\">https:\/\/github.com\/aws-samples\/aws-codedeploy-samples\/tree\/master\/applications\/SampleApp_Linux<\/a>&nbsp;. This manual uses a separately provided&nbsp;<strong>AWS_Developer_Services_Console_Lab_Source.zip<\/strong>, whose text files are created in CodeCommit through the browser. The GitHub repository is the provenance\/reference; the ZIP is the modernized educational derivative.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Currency and verification disclosure.<\/strong>&nbsp;Research checked AWS&#8217;s publicly available CodeCommit, CodeArtifact, CodeBuild, CodeDeploy, Systems Manager and CodePipeline instructions on&nbsp;<strong>10 November 2026<\/strong>. The source tree, JSON, YAML and shell syntax were inspected offline.&nbsp;<strong>AWS account-specific execution, current live console screenshots and end-to-end runtime outcomes have not been verified<\/strong>: no access to a training AWS account was provided, and package installation from npm could not be exercised in the authoring environment. AWS can change field labels, Region availability, defaults and wizard ordering. Follow the named AWS documentation links in the final section whenever a screen differs. No simulated screenshots are presented as real console evidence.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Important service status.<\/strong>&nbsp;AWS announced on 24 November 2025 that&nbsp;<strong>CodeCommit returned to general availability for new customers<\/strong>. Do not follow older training materials claiming it is closed to new customers. Current CodePipeline documentation uses the&nbsp;<strong>Build custom pipeline<\/strong>&nbsp;creation choice and a&nbsp;<strong>V2<\/strong>&nbsp;pipeline experience. [AWS01][AWS02]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Architecture at a glance<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>GitHub sample (reference)\n         |\n         v  Copy modernized source files through CodeCommit browser editor\nAWS CodeCommit (main)\n         |\n         +--&gt; CodePipeline Source stage --&gt; CodeBuild Build stage --&gt; CodeDeploy Deploy stage\n                                             |                      |\n                    AWS CodeArtifact &lt;-------+                      v\n                     npm upstream                           Amazon EC2 (AL2023)\n                    &#91;lodash 4.17.21]                          Apache web server\n                                             |\n                               build release ZIP: appspec.yml,\n                               index.html, scripts\/*\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The same release ZIP is first deployed manually from Amazon S3 during&nbsp;<strong>Lab 4<\/strong>. Later, CodePipeline passes CodeBuild&#8217;s output artifact directly to CodeDeploy in&nbsp;<strong>Lab 5<\/strong>;&nbsp;<strong>do not deploy the unbuilt CodeCommit source artifact<\/strong>, because&nbsp;<code>index.html<\/code>&nbsp;contains build-time template placeholders.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Time, cost and prerequisites<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Item<\/th><th class=\"has-text-align-left\" data-align=\"left\">Requirement or recommendation<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">Course duration<\/td><td class=\"has-text-align-left\" data-align=\"left\">4\u20136 hours instructor-led; 6\u20138 hours for first-time learners, excluding provisioning delays<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS account<\/td><td class=\"has-text-align-left\" data-align=\"left\">Nonproduction, disposable training account preferred; access to IAM, EC2, CodeCommit, CodeArtifact, CodeBuild, CodeDeploy, CodePipeline, Systems Manager, S3 and CloudWatch<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">User permissions<\/td><td class=\"has-text-align-left\" data-align=\"left\">A training-admin or an approved permission set capable of creating IAM roles\/policies and passing them to AWS services; no root-user access<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Region<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>Asia Pacific (Tokyo), ap-northeast-1<\/strong>, throughout; use another common Region only after adapting all Region references<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Network<\/td><td class=\"has-text-align-left\" data-align=\"left\">Default VPC with at least one public subnet and outbound internet, EC2 auto-assigned public IPv4, Systems Manager connectivity and HTTP\/80 access from learner&#8217;s current public IP<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Browser<\/td><td class=\"has-text-align-left\" data-align=\"left\">Current Chrome, Edge, Firefox or Safari with downloads and clipboard enabled<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Downloads<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>AWS_Developer_Services_Console_Lab_Source.zip<\/strong>&nbsp;and this manual; extract ZIP locally using the operating system&#8217;s file manager (no terminal)<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Cost<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>Not free by default<\/strong>. EC2 compute, EBS, public IPv4, CodeBuild, CodeArtifact, CodePipeline, S3, CloudWatch and requests may incur charges; charges vary by account\/Region\/usage. Clean up same day.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Security<\/td><td class=\"has-text-align-left\" data-align=\"left\">Personal training account, least privileges where practical, S3 Block Public Access ON, EC2 TCP\/80 from&nbsp;<strong>My IP<\/strong>&nbsp;only, no SSH needed, never store credentials in Git<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Start-of-class gate.<\/strong>&nbsp;Open the AWS account menu, record the&nbsp;<strong>12-digit account ID<\/strong>, and verify the Region&nbsp;<strong>Asia Pacific (Tokyo)<\/strong>&nbsp;is displayed in each console. If a default VPC is absent, ask the instructor to supply a VPC with a public subnet and an internet route; do not create a public EC2 target in a private subnet by mistake. All example resource names are illustrative and should be kept consistent throughout.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fixed naming worksheet \u2014 complete before opening Lab 1<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Resource<\/th><th class=\"has-text-align-left\" data-align=\"left\">Name\/value used in this guide<\/th><th class=\"has-text-align-left\" data-align=\"left\">Record actual value<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">Region<\/td><td class=\"has-text-align-left\" data-align=\"left\">ap-northeast-1<\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS account ID<\/td><td class=\"has-text-align-left\" data-align=\"left\">12-digit AWS account ID<\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit repository<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-webapp<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit branch<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>main<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact domain<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact downstream repository<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>web-npm<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact public upstream<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>npm-store<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild project<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-build<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">S3 standalone artifact bucket<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-artifacts-ACCOUNTID-apne1<\/code>&nbsp;(replace ACCOUNTID)<\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">IAM EC2 instance role<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-ec2-role<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">IAM CodeDeploy service role<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-codedeploy-role<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">EC2 instance Name tag<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-ec2<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">EC2 security group<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-http-sg<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy application<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-app<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy deployment group<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-ec2<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline pipeline<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-pipeline<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline artifact bucket<\/td><td class=\"has-text-align-left\" data-align=\"left\">Created by pipeline wizard; record later<\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Naming note.<\/strong>&nbsp;S3 bucket names are globally unique. If the proposed bucket name is unavailable, append a short suffix and update every reference to that bucket. Avoid changing the fixed CodeArtifact names unless you also edit&nbsp;<code>buildspec.yml<\/code>&nbsp;through CodeCommit&#8217;s browser editor.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 1 \u2014 AWS CodeCommit: store and review the application<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Create a Git repository, populate it with the modernized GitHub-derived application, browse commit history, and complete one browser-only branch and pull request workflow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Before you begin.<\/strong>&nbsp;Sign in with the assigned training IAM Identity Center role or IAM identity; Region is&nbsp;<code>ap-northeast-1<\/code>. Download and extract the provided source ZIP using the graphical file manager. Have a name and contact email available for commit metadata (not credentials).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.1 Create the repository<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In the AWS Console search bar, search\u00a0<strong>CodeCommit<\/strong>\u00a0and open the service (direct link:\u00a0<a href=\"https:\/\/console.aws.amazon.com\/codecommit\/\">https:\/\/console.aws.amazon.com\/codecommit\/<\/a>\u00a0).<\/li>\n\n\n\n<li>Check the Region selector in the top bar: choose\u00a0<strong>Asia Pacific (Tokyo)<\/strong>.<\/li>\n\n\n\n<li>In the left navigation choose\u00a0<strong>Repositories<\/strong>; select\u00a0<strong>Create repository<\/strong>.<\/li>\n\n\n\n<li>In\u00a0<strong>Repository name<\/strong>, enter\u00a0<code>awsdevlab-webapp<\/code>.<\/li>\n\n\n\n<li>In\u00a0<strong>Description<\/strong>, enter\u00a0<code>Browser-only AWS developer tools training application<\/code>.<\/li>\n\n\n\n<li>Keep repository encryption at the AWS-managed\/default setting offered by your account. Do not configure CodeGuru or optional integrations for this lab unless your console mandates a setting.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Create<\/strong>. Wait for the new repository&#8217;s detail page to open.<\/li>\n\n\n\n<li>Select its\u00a0<strong>Code<\/strong>\u00a0view. An empty-repository prompt is expected: there is no default branch until your first browser-created commit.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CC-1:<\/strong>&nbsp;Repositories lists&nbsp;<code>awsdevlab-webapp<\/code>. Copy its HTTPS clone URL only as reference;&nbsp;<strong>do not open a terminal or clone it<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.2 Add the application using only the CodeCommit web editor<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>From the repository&#8217;s\u00a0<strong>Code<\/strong>\u00a0tab, choose\u00a0<strong>Add file \u2192 Create file<\/strong>. Open\u00a0<code>README.md<\/code>\u00a0from the extracted source folder in a graphical text editor; copy all its contents into the CodeCommit editor; enter\u00a0<strong>File name<\/strong>\u00a0<code>README.md<\/code>.<\/li>\n\n\n\n<li>Fill\u00a0<strong>Author name<\/strong>,\u00a0<strong>Email address<\/strong>, and\u00a0<strong>Commit message<\/strong>\u00a0(for example,\u00a0<code>Add lab README<\/code>). Select\u00a0<strong>Commit changes<\/strong>. The console creates the\u00a0<code>main<\/code>\u00a0branch for the first commit in a new repository.<\/li>\n\n\n\n<li>Return to the repository&#8217;s\u00a0<strong>Code<\/strong>\u00a0tab and confirm the branch drop-down shows\u00a0<strong>main<\/strong>. For each file below, repeat\u00a0<strong>Add file \u2192 Create file<\/strong>, paste the file&#8217;s text, enter its exact path in\u00a0<strong>File name<\/strong>, provide the same author\/email and a meaningful commit message, then choose\u00a0<strong>Commit changes<\/strong>:File name to create in CodeCommitPurpose<code>index.html<\/code>Site HTML template and first visible release label<code>package.json<\/code>Pinned npm dependency and build\/test scripts<code>buildspec.yml<\/code>CodeBuild phases, CodeArtifact login and release-artifact selection<code>appspec.yml<\/code>CodeDeploy file mapping and lifecycle events<code>scripts\/install_dependencies<\/code>Install Apache and curl on Amazon Linux 2023<code>scripts\/start_server<\/code>Start and enable Apache<code>scripts\/stop_server<\/code>Graceful stop before later deployments<code>scripts\/validate_server<\/code>Local service and HTTP content verification<code>tests\/verify-source.cjs<\/code>Automated source checks<code>tools\/build-release.cjs<\/code>Build release HTML and stage deployment package<\/li>\n\n\n\n<li>For nested names,\u00a0<strong>type the entire relative path<\/strong>\u00a0such as\u00a0<code>scripts\/start_server<\/code>\u00a0in the\u00a0<strong>Create file<\/strong>\u00a0dialog; AWS&#8217;s CodeCommit training tutorial documents this browser-only folder-creation method. Do not flatten paths to the root. [AWS03]<\/li>\n\n\n\n<li>Verify the repository tree shows\u00a0<code>README.md<\/code>,\u00a0<code>index.html<\/code>,\u00a0<code>package.json<\/code>,\u00a0<code>buildspec.yml<\/code>,\u00a0<code>appspec.yml<\/code>, and folders\u00a0<code>scripts\/<\/code>,\u00a0<code>tests\/<\/code>,\u00a0<code>tools\/<\/code>.<\/li>\n\n\n\n<li>Open\u00a0<code>buildspec.yml<\/code>\u00a0in CodeCommit and verify the\u00a0<strong>domain<\/strong>\u00a0is\u00a0<code>awsdevlab<\/code>, the\u00a0<strong>repository<\/strong>\u00a0is\u00a0<code>web-npm<\/code>, and\u00a0<code>artifacts.base-directory<\/code>\u00a0is\u00a0<code>release<\/code>.<\/li>\n\n\n\n<li>Open\u00a0<code>appspec.yml<\/code>\u00a0and verify it is located at the\u00a0<strong>repository root<\/strong>, includes\u00a0<code>ValidateService<\/code>, and installs\u00a0<code>\/index.html<\/code>\u00a0to\u00a0<code>\/var\/www\/html\/<\/code>.<\/li>\n\n\n\n<li>Select\u00a0<strong>Commits<\/strong>\u00a0or\u00a0<strong>History<\/strong>\u00a0in the repository navigation to confirm each browser-created file produced a commit on\u00a0<code>main<\/code>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Important:<\/strong>&nbsp;Uploading the&nbsp;<strong>entire ZIP<\/strong>&nbsp;as one CodeCommit repository file does&nbsp;<strong>not<\/strong>&nbsp;unpack it into Git. Use the&nbsp;<strong>Create file<\/strong>&nbsp;editor separately for the listed file paths. This is deliberately slower than Git push but honors the browser-only requirement. Never paste the ZIP&#8217;s binary data into the editor.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.3 Practice branching, review and merge entirely in CodeCommit<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Select\u00a0<strong>Branches<\/strong>\u00a0in the repository. Choose\u00a0<strong>Create branch<\/strong>\u00a0(the exact control may be under the\u00a0<strong>Branches<\/strong>\u00a0view).<\/li>\n\n\n\n<li>Set\u00a0<strong>Branch name<\/strong>\u00a0<code>feature\/lab-banner<\/code>\u00a0and\u00a0<strong>Branch from<\/strong>\u00a0<code>main<\/code>; select\u00a0<strong>Create branch<\/strong>.<\/li>\n\n\n\n<li>Return to\u00a0<strong>Code<\/strong>, select branch\u00a0<code>feature\/lab-banner<\/code>, and open\u00a0<code>index.html<\/code>.<\/li>\n\n\n\n<li>Select\u00a0<strong>Edit<\/strong>, locate the visible sentence\u00a0<code>Five services. One end-to-end delivery workflow.<\/code>, and replace it with\u00a0<code>Source control review completed. Ready for CI\/CD.<\/code>\u00a0Leave\u00a0<code>&lt;%- releaseLabel %><\/code>\u00a0and\u00a0<code>&lt;%- builtAt %><\/code>\u00a0placeholders untouched.<\/li>\n\n\n\n<li>Enter a meaningful commit message such as\u00a0<code>Update demo banner in feature branch<\/code>; choose\u00a0<strong>Commit changes<\/strong>. Confirm that\u00a0<code>main<\/code>\u00a0still has the original text and\u00a0<code>feature\/lab-banner<\/code>\u00a0has the update.<\/li>\n\n\n\n<li>Go to\u00a0<strong>Pull requests \u2192 Create pull request<\/strong>. Select\u00a0<strong>Source<\/strong>\u00a0<code>feature\/lab-banner<\/code>\u00a0and\u00a0<strong>Destination<\/strong>\u00a0<code>main<\/code>.<\/li>\n\n\n\n<li>Review the diff. Enter title\u00a0<code>Update training website banner<\/code>\u00a0and a description of the change; choose\u00a0<strong>Create pull request<\/strong>.<\/li>\n\n\n\n<li>In the pull request, review the\u00a0<strong>Changes<\/strong>\u00a0tab, add a review comment if available, then choose\u00a0<strong>Merge<\/strong>. Select a permitted merge strategy (for a simple, conflict-free example choose\u00a0<strong>Fast forward<\/strong>\u00a0if offered), confirm the destination is\u00a0<code>main<\/code>, and complete the merge.<\/li>\n\n\n\n<li>Return to branch\u00a0<code>main<\/code>\u00a0and open\u00a0<code>index.html<\/code>. Confirm the updated sentence is present and the pull request is merged\/closed.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CC-2:<\/strong>&nbsp;A named feature branch, a reviewed and merged pull request, and the modified file on&nbsp;<code>main<\/code>&nbsp;are visible in the CodeCommit console. If required by an organizational approval rule, ask another authorized learner to approve instead of bypassing governance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 1 evidence to capture<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Screenshot: repository name with\u00a0<code>main<\/code>\u00a0branch and complete folder tree.<\/li>\n\n\n\n<li>Screenshot: pull request diff and merged status.<\/li>\n\n\n\n<li>Record: repository ARN, default branch, most recent commit ID.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 1 troubleshooting<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>AccessDenied on creation or commit:<\/strong>\u00a0check the trainee permission set and account\/Region; a repository policy or organization SCP may restrict\u00a0<code>codecommit:CreateRepository<\/code>,\u00a0<code>PutFile<\/code>\u00a0or merge permissions.<\/li>\n\n\n\n<li><strong>No main branch:<\/strong>\u00a0complete the first browser-created file and refresh the page.<\/li>\n\n\n\n<li><strong>Missing\u00a0<code>scripts\/<\/code>\u00a0folder:<\/strong>\u00a0nested file paths must be entered in the filename field on\u00a0<strong>Create file<\/strong>, not in a flat\u00a0<strong>Upload file<\/strong>\u00a0chooser.<\/li>\n\n\n\n<li><strong>Pull request cannot merge:<\/strong>\u00a0verify destination\/main, source\/feature, merge conflicts, branch policies and required approvals.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 2 \u2014 AWS CodeArtifact: manage build dependencies<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Create an AWS CodeArtifact domain and npm repository connected to the public npm registry, grant the CodeBuild role secure read access, and later verify that CodeBuild actually fetched the pinned&nbsp;<code>lodash<\/code>&nbsp;dependency through CodeArtifact.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Note on order.<\/strong>&nbsp;This lab creates the repository. The first package version will appear under Packages&nbsp;<strong>after the initial CodeBuild execution in Lab 3<\/strong>. A console-only learner does not need to authenticate npm on a local machine.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2.1 Create domain, downstream repository and npm upstream<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Use AWS Console search to open\u00a0<strong>CodeArtifact<\/strong>\u00a0(direct link:\u00a0<a href=\"https:\/\/console.aws.amazon.com\/codesuite\/codeartifact\/start\">https:\/\/console.aws.amazon.com\/codesuite\/codeartifact\/start<\/a>\u00a0). Check Region\u00a0<code>ap-northeast-1<\/code>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Create repository<\/strong>\u00a0from the Repositories view.<\/li>\n\n\n\n<li>Set\u00a0<strong>Repository name<\/strong>\u00a0to\u00a0<code>web-npm<\/code>\u00a0and optional description\u00a0<code>Dependencies consumed by the web application CodeBuild project<\/code>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Public upstream repositories<\/strong>, select the\u00a0<strong>npm-store<\/strong>\u00a0option that connects to the public npmjs registry. The wizard will create\/link an upstream repository named\u00a0<code>npm-store<\/code>.\u00a0<strong>Do not leave the public upstream selection empty<\/strong>; this is how the first\u00a0<code>lodash<\/code>\u00a0package is ingested.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Next<\/strong>. For\u00a0<strong>AWS account<\/strong>, choose\u00a0<strong>This AWS account<\/strong>.<\/li>\n\n\n\n<li>For\u00a0<strong>Domain name<\/strong>, enter\u00a0<code>awsdevlab<\/code>\u00a0(new domain). If a domain already exists, only reuse it if your instructor confirms the domain ownership and permissions.<\/li>\n\n\n\n<li>Under\u00a0<strong>Additional configuration<\/strong>, choose the\u00a0<strong>AWS managed key<\/strong>\u00a0for domain encryption for this disposable lab; customer-managed KMS keys require additional permissions.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Next<\/strong>, review the package flow\u00a0<code>web-npm \u2192 npm-store \u2192 npmjs<\/code>, then\u00a0<strong>Create repository<\/strong>.<\/li>\n\n\n\n<li>From\u00a0<strong>Repositories<\/strong>, verify both\u00a0<code>web-npm<\/code>\u00a0and\u00a0<code>npm-store<\/code>\u00a0exist and are associated with domain\u00a0<code>awsdevlab<\/code>; from\u00a0<strong>Domains<\/strong>, verify\u00a0<code>awsdevlab<\/code>\u00a0exists.<\/li>\n\n\n\n<li>Open repository\u00a0<strong>web-npm<\/strong>\u00a0and select\u00a0<strong>View connection instructions<\/strong>\u00a0\u2192\u00a0<strong>npm<\/strong>. Inspect the displayed domain\/repository\/Region endpoint. This screen is for understanding the connection;\u00a0<strong>do not execute the suggested terminal login command<\/strong>. Authentication will occur inside CodeBuild using\u00a0<code>buildspec.yml<\/code>\u00a0in Lab 3. [AWS04]<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CA-1:<\/strong>&nbsp;CodeArtifact&#8217;s repository view shows&nbsp;<code>web-npm<\/code>, its upstream&nbsp;<code>npm-store<\/code>&nbsp;and the new domain&nbsp;<code>awsdevlab<\/code>. The package list might correctly be empty until Lab 3.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2.2 Prepare the future CodeBuild access policy in IAM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The policy below is intended for the&nbsp;<strong>CodeBuild service role<\/strong>, not the trainee identity or EC2 instance. Create it after CodeBuild creates its role in Lab 3 (the next section gives the exact console steps). Do not place CodeArtifact tokens in CodeCommit,&nbsp;<code>package.json<\/code>, or CodeBuild plaintext environment variables. Each build automatically acquires a short-lived token. [AWS05]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>IAM policy template \u2014 replace&nbsp;<code>ACCOUNT_ID<\/code>&nbsp;with your 12-digit account ID before saving. This is policy JSON, not a terminal command.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": &#91;\n    {\n      \"Sid\": \"CodeArtifactDomainToken\",\n      \"Effect\": \"Allow\",\n      \"Action\": \"codeartifact:GetAuthorizationToken\",\n      \"Resource\": \"arn:aws:codeartifact:ap-northeast-1:ACCOUNT_ID:domain\/awsdevlab\"\n    },\n    {\n      \"Sid\": \"CodeArtifactReadRepository\",\n      \"Effect\": \"Allow\",\n      \"Action\": &#91;\n        \"codeartifact:GetRepositoryEndpoint\",\n        \"codeartifact:ReadFromRepository\"\n      ],\n      \"Resource\": \"arn:aws:codeartifact:ap-northeast-1:ACCOUNT_ID:repository\/awsdevlab\/web-npm\"\n    },\n    {\n      \"Sid\": \"AllowServiceBearerToken\",\n      \"Effect\": \"Allow\",\n      \"Action\": \"sts:GetServiceBearerToken\",\n      \"Resource\": \"*\",\n      \"Condition\": {\n        \"StringEquals\": {\n          \"sts:AWSServiceName\": \"codeartifact.amazonaws.com\"\n        }\n      }\n    }\n  ]\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Instructor checkpoint:<\/strong>&nbsp;Explain the two trust boundaries: the trainee can configure IAM, while CodeBuild assumes its own execution role.&nbsp;<code>sts:GetServiceBearerToken<\/code>&nbsp;is separate from CodeArtifact&#8217;s repository authorization. The example grants&nbsp;<strong>read<\/strong>, not publish, permissions. [AWS06]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2.3 Return after Lab 3 to prove package use<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>After the\u00a0<strong>first successful CodeBuild run<\/strong>, open\u00a0<strong>CodeArtifact \u2192 Repositories \u2192 web-npm \u2192 Packages<\/strong>.<\/li>\n\n\n\n<li>Refresh. Search for\u00a0<strong>lodash<\/strong>. Open the package and confirm a package version such as\u00a0<code>4.17.21<\/code>\u00a0is present.<\/li>\n\n\n\n<li>Inspect its assets\/metadata. Navigate to\u00a0<strong>npm-store<\/strong>\u00a0and examine the upstream relationship, if shown in your console.<\/li>\n\n\n\n<li>Return to CodeBuild&#8217;s build logs. Confirm the CodeArtifact login phase and package-install phase succeeded; treat CodeArtifact package presence\u00a0<strong>and<\/strong>\u00a0build success together as evidence that the dependency path worked.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CA-2:<\/strong>&nbsp;<code>lodash<\/code>&nbsp;<code>4.17.21<\/code>&nbsp;appears in the downstream repository following a successful build. Package visibility may lag; refresh before troubleshooting.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 2 troubleshooting<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Public package missing after build:<\/strong>\u00a0check upstream\u00a0<code>npm-store<\/code>, public internet egress from CodeBuild, build logs, and whether the build actually installed npm dependencies. Do not assume an empty package list before first build is a fault.<\/li>\n\n\n\n<li><strong>Token authorization error:<\/strong>\u00a0CodeBuild role requires CodeArtifact token + repository read actions\u00a0<strong>and<\/strong>\u00a0<code>sts:GetServiceBearerToken<\/code>; root credentials cannot request a CodeArtifact auth token.<\/li>\n\n\n\n<li><strong>Repository not listed in CodeBuild account:<\/strong>\u00a0verify Region, account, domain and repository spelling. Cross-account CodeArtifact access needs additional resource policies not covered here.<\/li>\n\n\n\n<li><strong>Private VPC build cannot access CodeArtifact\/npmjs:<\/strong>\u00a0use the default service-managed CodeBuild networking for this course; custom VPC builds need additional routes\/endpoints.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 3 \u2014 AWS CodeBuild: test, build and store a release ZIP<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Create a standalone CodeBuild project whose source is CodeCommit, automatically fetch npm&nbsp;<code>lodash<\/code>&nbsp;from CodeArtifact, run tests, generate an&nbsp;<code>index.html<\/code>&nbsp;with a release label, and publish a fully formed CodeDeploy revision as a ZIP in private S3.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What success looks like:<\/strong>&nbsp;CodeBuild status&nbsp;<strong>Succeeded<\/strong>, test result&nbsp;<strong>PASS<\/strong>, S3 ZIP contains&nbsp;<code>appspec.yml<\/code>,&nbsp;<code>index.html<\/code>, and&nbsp;<code>scripts\/*<\/code>&nbsp;at the archive root, and the CodeArtifact package can be inspected in its console.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.1 Create the private S3 release-artifact bucket<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>Amazon S3 \u2192 Buckets \u2192 Create bucket<\/strong>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>General purpose<\/strong>\u00a0bucket. Set\u00a0<strong>Bucket name<\/strong>\u00a0to\u00a0<code>awsdevlab-artifacts-ACCOUNTID-apne1<\/code>\u00a0(substitute your account ID; append a suffix if already in use).<\/li>\n\n\n\n<li>Set the\u00a0<strong>AWS Region<\/strong>\u00a0to\u00a0<strong>Asia Pacific (Tokyo)<\/strong>.<\/li>\n\n\n\n<li>Leave\u00a0<strong>Block all public access<\/strong>\u00a0enabled. Do not make the bucket or its objects public.<\/li>\n\n\n\n<li>For\u00a0<strong>Bucket Versioning<\/strong>, choose\u00a0<strong>Disable<\/strong>\u00a0for this disposable lab, unless your institution requires versioning (if enabled, cleanup requires deleting versions and delete markers).<\/li>\n\n\n\n<li>For\u00a0<strong>Default encryption<\/strong>, leave\u00a0<strong>SSE-S3<\/strong>\u00a0or another account-approved default. For the simplest lab, use SSE-S3 rather than customer-managed KMS.<\/li>\n\n\n\n<li>Leave other settings at their defaults; choose\u00a0<strong>Create bucket<\/strong>\u00a0and record its exact name.<\/li>\n\n\n\n<li>Open the bucket and confirm the\u00a0<strong>Permissions<\/strong>\u00a0panel shows Block Public Access enabled.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CB-1:<\/strong>&nbsp;Private, same-Region S3 bucket is available and empty.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.2 Create the CodeBuild project<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeBuild \u2192 Build \u2192 Build projects \u2192 Create build project<\/strong>\u00a0(or\u00a0<strong>Create build project<\/strong>\u00a0from the welcome screen).<\/li>\n\n\n\n<li><strong>Project configuration \u2192 Project name:<\/strong>\u00a0<code>awsdevlab-web-build<\/code>. Enter a short description such as\u00a0<code>CodeCommit \u2192 CodeArtifact npm \u2192 test \u2192 S3 deployable ZIP<\/code>.<\/li>\n\n\n\n<li><strong>Source \u2192 Source provider:<\/strong>\u00a0choose\u00a0<strong>AWS CodeCommit<\/strong>.\u00a0<strong>Repository:<\/strong>\u00a0<code>awsdevlab-webapp<\/code>.\u00a0<strong>Reference type:<\/strong>\u00a0Branch.\u00a0<strong>Branch:<\/strong>\u00a0<code>main<\/code>\u00a0(if requested). Leave Git depth and submodules at defaults unless your console requires an option.<\/li>\n\n\n\n<li><strong>Environment \u2192 Provisioning model:<\/strong>\u00a0On-demand (managed).\u00a0<strong>Environment image:<\/strong>\u00a0Managed image.\u00a0<strong>Operating system:<\/strong>\u00a0Amazon Linux.\u00a0<strong>Runtime:<\/strong>\u00a0Standard.\u00a0<strong>Image:<\/strong>\u00a0select\u00a0<strong>Amazon Linux 2023 x86_64 standard:6.0<\/strong>\u00a0(the exact catalog label may include\u00a0<code>aws\/codebuild\/amazonlinux-x86_64-standard:6.0<\/code>). Choose a Linux container and the smallest general-purpose compute option appropriate for a lightweight Node build.<\/li>\n\n\n\n<li><strong>Environment \u2192 Service role:<\/strong>\u00a0choose\u00a0<strong>New service role<\/strong>; note the automatically proposed role name, such as\u00a0<code>codebuild-awsdevlab-web-build-service-role<\/code>. Avoid privileged mode (not required), a custom VPC, secrets or additional environment variables for this lab.<\/li>\n\n\n\n<li><strong>Buildspec \u2192 Build specifications:<\/strong>\u00a0choose\u00a0<strong>Use a buildspec file<\/strong>\u00a0in the source root. Confirm the name is\u00a0<code>buildspec.yml<\/code>\u00a0(do not paste terminal commands into the browser).<\/li>\n\n\n\n<li><strong>Artifacts \u2192 Type:<\/strong>\u00a0<strong>Amazon S3<\/strong>. Select the private bucket created in 3.1.<\/li>\n\n\n\n<li><strong>Artifact name:<\/strong>\u00a0<code>web-demo-release.zip<\/code>. Select\u00a0<strong>ZIP<\/strong>\u00a0packaging. Keep a blank\u00a0<strong>Path<\/strong>, choose\u00a0<strong>No namespace \/ None<\/strong>\u00a0if that field appears, and leave any\u00a0<strong>artifact name override\/semantic versioning<\/strong>\u00a0option\u00a0<strong>off<\/strong>. If the option\u00a0<strong>Remove artifacts encryption<\/strong>\u00a0appears, use it\u00a0<strong>only if<\/strong>\u00a0the bucket enforces SSE-S3 and the course is not using client-side AWS KMS artifact encryption; otherwise use the default encryption and grant the deployment role appropriate KMS decrypt permissions.<\/li>\n\n\n\n<li><strong>Cache:<\/strong>\u00a0No cache for the first run.\u00a0<strong>Logs:<\/strong>\u00a0enable\u00a0<strong>CloudWatch Logs<\/strong>\u00a0to capture the build phases. Accept a generated or explicitly named log group; record it for cleanup.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Create build project<\/strong>. Note the project&#8217;s\u00a0<strong>Service role ARN<\/strong>\u00a0on the details page. [AWS07][AWS08]<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Image selection note.<\/strong>&nbsp;AWS currently documents Node.js&nbsp;<strong>22<\/strong>&nbsp;on the Amazon Linux 2023 standard 6.0 CodeBuild image. Our&nbsp;<code>buildspec.yml<\/code>&nbsp;explicitly selects Node.js 22 to avoid silent runtime changes. [AWS09]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.3 Grant CodeBuild role access through the IAM console<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>IAM \u2192 Roles<\/strong>\u00a0in another tab.<\/li>\n\n\n\n<li>Search for the\u00a0<strong>CodeBuild service role<\/strong>\u00a0recorded in 3.2. Select it; verify its trusted entity\/service is\u00a0<code>codebuild.amazonaws.com<\/code>.<\/li>\n\n\n\n<li>On\u00a0<strong>Permissions<\/strong>, select\u00a0<strong>Add permissions \u2192 Create inline policy<\/strong>\u00a0(or create a customer-managed policy in\u00a0<strong>IAM \u2192 Policies<\/strong>\u00a0and attach it to this role). Open the\u00a0<strong>JSON<\/strong>\u00a0editor.<\/li>\n\n\n\n<li>Replace\u00a0<code>ACCOUNT_ID<\/code>\u00a0in the\u00a0<strong>Lab 2 CodeArtifact policy<\/strong>\u00a0with your actual account ID and paste the full JSON. Choose\u00a0<strong>Next<\/strong>; enter policy name\u00a0<code>AWSDevLabCodeArtifactRead<\/code>; review and\u00a0<strong>Create policy<\/strong>. Wait until the policy appears on the CodeBuild role.<\/li>\n\n\n\n<li>Inspect the existing CodeBuild role permissions for\u00a0<strong>CodeCommit<\/strong>\u00a0source access,\u00a0<strong>CloudWatch Logs<\/strong>, and the chosen\u00a0<strong>S3 output bucket<\/strong>. The console may create some scoped policies automatically; do not assume permissions are present solely because the role exists.<\/li>\n\n\n\n<li>If the role lacks S3 write or CodeCommit pull access, create and attach this\u00a0<strong>supplementary inline policy<\/strong>, replacing\u00a0<code>ACCOUNT_ID<\/code>\u00a0in the resource ARNs and the\u00a0<code>ARTIFACT_BUCKET<\/code>\u00a0value with the actual bucket name:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": &#91;\n    {\n      \"Sid\": \"ReadTrainingCodeCommit\",\n      \"Effect\": \"Allow\",\n      \"Action\": &#91;\"codecommit:GitPull\", \"codecommit:GetRepository\"],\n      \"Resource\": \"arn:aws:codecommit:ap-northeast-1:ACCOUNT_ID:awsdevlab-webapp\"\n    },\n    {\n      \"Sid\": \"InspectArtifactBucket\",\n      \"Effect\": \"Allow\",\n      \"Action\": &#91;\"s3:GetBucketLocation\", \"s3:ListBucket\"],\n      \"Resource\": \"arn:aws:s3:::ARTIFACT_BUCKET\"\n    },\n    {\n      \"Sid\": \"WriteArtifactObjects\",\n      \"Effect\": \"Allow\",\n      \"Action\": &#91;\"s3:PutObject\", \"s3:GetObject\"],\n      \"Resource\": \"arn:aws:s3:::ARTIFACT_BUCKET\/*\"\n    }\n  ]\n}\n<\/code><\/pre>\n\n\n\n<ol start=\"7\" class=\"wp-block-list\">\n<li>Review the IAM policy summary before saving; confirm the target is the\u00a0<strong>CodeBuild role<\/strong>\u00a0and there are no unresolved placeholder values. If an organization SCP or bucket policy applies an explicit deny, fixing the IAM role alone may not be sufficient.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CB-2:<\/strong>&nbsp;CodeBuild&#8217;s execution role has CodeArtifact read\/token, service bearer token, CodeCommit pull, CloudWatch log permissions, and S3 artifact write permissions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.4 Inspect the build contract before running<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeCommit \u2192 awsdevlab-webapp \u2192 Code \u2192 main \u2192 buildspec.yml<\/strong>.<\/li>\n\n\n\n<li>Confirm\u00a0<strong>install<\/strong>\u00a0selects Node.js 22;\u00a0<strong>pre_build<\/strong>\u00a0authenticates npm to CodeArtifact and installs dependencies; the test checks source structure;\u00a0<strong>build<\/strong>\u00a0generates the release;\u00a0<strong>artifacts<\/strong>\u00a0packages\u00a0<code>release\/**<\/code>\u00a0with\u00a0<strong>release<\/strong>\u00a0as the base directory.<\/li>\n\n\n\n<li>Open\u00a0<code>package.json<\/code>. Confirm dependency\u00a0<code>lodash<\/code>\u00a0is pinned to version\u00a0<code>4.17.21<\/code>\u00a0and has\u00a0<code>test<\/code>\u00a0and\u00a0<code>build<\/code>\u00a0scripts.<\/li>\n\n\n\n<li>Open\u00a0<code>tools\/build-release.cjs<\/code>. Confirm it renders the template with\u00a0<code>lodash<\/code>, copies\u00a0<code>appspec.yml<\/code>, and includes all four CodeDeploy hooks in the\u00a0<code>release\/scripts\/<\/code>\u00a0directory.<\/li>\n\n\n\n<li>Explain to learners that\u00a0<strong>the YAML\/JavaScript\/shell files are source configuration<\/strong>. The user never manually runs their operations. CodeBuild executes the buildspec internally using the service role; CodeDeploy executes lifecycle hooks later on the deployment host.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Production distinction:<\/strong>&nbsp;For teaching a first-time upstream cache ingest, this lab pins a single dependency and performs a fresh package resolution without a lockfile. For production, create a reviewed registry-consistent lockfile, use a reproducible installation mode, add vulnerability scanning, and remove unnecessary public dependency access.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.5 Start and inspect the standalone build<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Return to\u00a0<strong>CodeBuild \u2192 Build projects \u2192 awsdevlab-web-build<\/strong>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Start build<\/strong>. For source version, choose the default\/latest\u00a0<code>main<\/code>\u00a0revision; leave optional build overrides unchanged and choose\u00a0<strong>Start build<\/strong>.<\/li>\n\n\n\n<li>Open the new build ID in\u00a0<strong>Build history<\/strong>. Watch each phase:\u00a0<strong>DOWNLOAD_SOURCE<\/strong>,\u00a0<strong>INSTALL<\/strong>,\u00a0<strong>PRE_BUILD<\/strong>,\u00a0<strong>BUILD<\/strong>,\u00a0<strong>UPLOAD_ARTIFACTS<\/strong>,\u00a0<strong>FINALIZING<\/strong>.<\/li>\n\n\n\n<li>On the\u00a0<strong>Build logs<\/strong>\u00a0tab, confirm the CodeArtifact npm login step completed successfully, dependency installation completed, the automated test printed a\u00a0<strong>PASS<\/strong>\u00a0message, and build output states the release directory was created.<\/li>\n\n\n\n<li>Confirm the build&#8217;s top-level\u00a0<strong>Status<\/strong>\u00a0is\u00a0<strong>Succeeded<\/strong>. Record the build ID and source commit ID.<\/li>\n\n\n\n<li>In the build detail\u00a0<strong>Artifacts<\/strong>\u00a0section, follow the\u00a0<strong>Artifacts upload location<\/strong>\u00a0link to S3, or open S3 \u2192 your artifact bucket manually.<\/li>\n\n\n\n<li>Locate\u00a0<code>web-demo-release.zip<\/code>\u00a0(or the S3 object whose exact key appears in the build details). Confirm it is an S3\u00a0<strong>object<\/strong>, not a folder of loose individual files.<\/li>\n\n\n\n<li>From the S3\u00a0<strong>object<\/strong>\u00a0page, choose\u00a0<strong>Download<\/strong>\u00a0in the browser; use your operating system&#8217;s graphical archive viewer to inspect its entries. The expected ZIP hierarchy is:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>appspec.yml\nindex.html\nscripts\/install_dependencies\nscripts\/start_server\nscripts\/stop_server\nscripts\/validate_server\n<\/code><\/pre>\n\n\n\n<ol start=\"9\" class=\"wp-block-list\">\n<li>Verify that\u00a0<code>appspec.yml<\/code>\u00a0is at the ZIP\u00a0<strong>root<\/strong>, not inside\u00a0<code>release\/<\/code>,\u00a0<code>source\/<\/code>, a GitHub folder or another nested directory. Open the packaged\u00a0<code>index.html<\/code>\u00a0in a local text editor and confirm the visible\u00a0<strong>Release: LAB-V1<\/strong>\u00a0placeholder has been rendered and the build time is a real UTC timestamp.<\/li>\n\n\n\n<li>Return to\u00a0<strong>CodeArtifact \u2192 web-npm \u2192 Packages<\/strong>; verify\u00a0<code>lodash<\/code>\u00a0version\u00a0<code>4.17.21<\/code>\u00a0appears (allow some time and refresh if initially absent).<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CB-3:<\/strong>&nbsp;Build&nbsp;<strong>Succeeded<\/strong>, release ZIP has correct file paths,&nbsp;<code>lodash<\/code>&nbsp;is present in CodeArtifact, and build log contains the source-test PASS. Save the&nbsp;<strong>S3 URI<\/strong>&nbsp;of the ZIP for manual CodeDeploy deployment.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 3 troubleshooting matrix<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Symptom in CodeBuild<\/th><th class=\"has-text-align-left\" data-align=\"left\">Verify in console<\/th><th class=\"has-text-align-left\" data-align=\"left\">Recovery without terminal<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">Source download fails<\/td><td class=\"has-text-align-left\" data-align=\"left\">Build log; CodeCommit repository and branch; role policy<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check same Region, correct branch,&nbsp;<code>codecommit:GitPull<\/code>, repo ARN<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact access denied<\/td><td class=\"has-text-align-left\" data-align=\"left\">PRE_BUILD log and CodeBuild role<\/td><td class=\"has-text-align-left\" data-align=\"left\">Apply all 3 permissions areas from Lab 2, including&nbsp;<code>sts:GetServiceBearerToken<\/code><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">npm package not found \/ 404<\/td><td class=\"has-text-align-left\" data-align=\"left\">Domain, downstream upstream flow<\/td><td class=\"has-text-align-left\" data-align=\"left\">Connect&nbsp;<code>web-npm<\/code>&nbsp;to&nbsp;<code>npm-store<\/code>&nbsp;and npmjs; retry build<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>buildspec.yml<\/code>&nbsp;not found<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit tree<\/td><td class=\"has-text-align-left\" data-align=\"left\">Create at repository root, correct spelling (not&nbsp;<code>buildspec.yaml<\/code>)<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Node runtime unsupported<\/td><td class=\"has-text-align-left\" data-align=\"left\">Build environment image<\/td><td class=\"has-text-align-left\" data-align=\"left\">Use AL2023 x86_64 standard 6.0 and Node.js 22<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Test failed<\/td><td class=\"has-text-align-left\" data-align=\"left\">Detailed log; tests\/ path<\/td><td class=\"has-text-align-left\" data-align=\"left\">Restore exact sample file paths and template markers<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Artifact upload failed<\/td><td class=\"has-text-align-left\" data-align=\"left\">UPLOAD_ARTIFACTS and IAM\/S3<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check S3 PutObject, actual bucket ARN, ZIP packaging and encryption<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">ZIP contains nested&nbsp;<code>release\/<\/code>&nbsp;directory<\/td><td class=\"has-text-align-left\" data-align=\"left\">Buildspec&nbsp;<code>base-directory<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Set&nbsp;<code>base-directory: release<\/code>, re-run, inspect ZIP again<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 4 \u2014 AWS CodeDeploy: deploy the build artifact to Amazon EC2<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Launch a single Amazon Linux 2023 target, install the CodeDeploy agent entirely through the CodeDeploy\/Systems Manager consoles, manually deploy the&nbsp;<em>tested ZIP<\/em>&nbsp;from Lab 3, inspect lifecycle events, and validate the live HTTP website.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture note.<\/strong>&nbsp;This is intentionally a&nbsp;<strong>single-instance, in-place deployment<\/strong>&nbsp;with no load balancer. It teaches CodeDeploy lifecycle events. It is&nbsp;<strong>not<\/strong>&nbsp;a highly available production deployment. The web server is installed by lifecycle hooks included in the build artifact; the learner does not manually run installation commands.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.1 Create the EC2 instance profile (IAM role)<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>IAM \u2192 Roles \u2192 Create role<\/strong>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Trusted entity type<\/strong>, choose\u00a0<strong>AWS service<\/strong>;\u00a0<strong>Use case<\/strong>\u00a0\u2192\u00a0<strong>EC2<\/strong>; choose\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li>In\u00a0<strong>Permissions<\/strong>, attach\u00a0<strong>AmazonSSMManagedInstanceCore<\/strong>\u00a0and\u00a0<strong>AmazonEC2RoleforAWSCodeDeploy<\/strong>. The latter grants broad S3 read permissions and is convenient for this isolated course;\u00a0<strong>do not use its broad S3 resource scope unreviewed in production<\/strong>. For production, scope S3 reads to approved artifact paths and any required AWS-owned service buckets. [AWS10]<\/li>\n\n\n\n<li>Choose\u00a0<strong>Next<\/strong>; enter\u00a0<strong>Role name<\/strong>\u00a0<code>awsdevlab-ec2-role<\/code>; optionally add tag\u00a0<code>Course=AWSDevLab<\/code>; choose\u00a0<strong>Create role<\/strong>.<\/li>\n\n\n\n<li>Open the role and verify its\u00a0<strong>Trust relationships<\/strong>\u00a0shows the EC2 service principal, and its\u00a0<strong>Permissions<\/strong>\u00a0tab contains both managed policies.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-1:<\/strong>&nbsp;An EC2-trusted instance role exists, with SSM access and the CodeDeploy agent&#8217;s artifact access.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.2 Launch the EC2 target using the EC2 console<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>EC2 \u2192 Instances \u2192 Launch instances<\/strong>.<\/li>\n\n\n\n<li>Set\u00a0<strong>Name<\/strong>\u00a0to\u00a0<code>awsdevlab-web-ec2<\/code>. This creates\u00a0<strong>Name=awsdevlab-web-ec2<\/strong>, which the deployment group will use to select the target.<\/li>\n\n\n\n<li>Under\u00a0<strong>Application and OS Images (AMI)<\/strong>\u00a0choose\u00a0<strong>Amazon Linux<\/strong>\u00a0and explicitly select\u00a0<strong>Amazon Linux 2023 (AL2023)<\/strong>, x86_64. Do not choose an old Amazon Linux 2 image only because an older walkthrough shows it.<\/li>\n\n\n\n<li>Under\u00a0<strong>Instance type<\/strong>, choose a small, supported general-purpose type suitable for the course, such as\u00a0<code>t3.micro<\/code>\u00a0if available and permitted. Verify pricing in your account; do\u00a0<strong>not<\/strong>\u00a0assume free-tier eligibility.<\/li>\n\n\n\n<li>Under\u00a0<strong>Key pair (login)<\/strong>\u00a0choose\u00a0<strong>Proceed without a key pair<\/strong>\u00a0if allowed. This lab uses no SSH. If your organization requires an approved key pair, choose it, but do not open TCP\/22 merely for this tutorial.<\/li>\n\n\n\n<li>Expand\u00a0<strong>Network settings \u2192 Edit<\/strong>. Select the instructor-approved\u00a0<strong>VPC<\/strong>\u00a0and\u00a0<strong>public subnet<\/strong>. Choose\u00a0<strong>Auto-assign public IP: Enable<\/strong>. Ensure the subnet&#8217;s route table provides an Internet Gateway path for internet-facing test traffic.<\/li>\n\n\n\n<li>Create a new security group\u00a0<code>awsdevlab-http-sg<\/code>\u00a0with\u00a0<strong>Inbound HTTP TCP\/80 \u2192 Source type: My IP<\/strong>.\u00a0<strong>Remove SSH TCP\/22<\/strong>\u00a0if the wizard adds it automatically. Leave the normal outbound rule allowing required service access. Record the IPv4 CIDR displayed for My IP; this may need to be updated if your public IP changes.<\/li>\n\n\n\n<li>Under\u00a0<strong>Configure storage<\/strong>, keep the default encrypted\/root EBS volume size offered by the selected AMI (small is sufficient). Check\u00a0<strong>Delete on termination<\/strong>\u00a0is enabled for the root volume.<\/li>\n\n\n\n<li>Expand\u00a0<strong>Advanced details<\/strong>. Under\u00a0<strong>IAM instance profile<\/strong>, select\u00a0<code>awsdevlab-ec2-role<\/code>.\u00a0<strong>No user data is required<\/strong>; do not paste bootstrapping commands.<\/li>\n\n\n\n<li>Under\u00a0<strong>Summary<\/strong>, verify\u00a0<strong>Number of instances = 1<\/strong>. Choose\u00a0<strong>Launch instance<\/strong>.<\/li>\n\n\n\n<li>In\u00a0<strong>EC2 \u2192 Instances<\/strong>, select the new instance and wait for\u00a0<strong>Instance state: Running<\/strong>\u00a0and\u00a0<strong>Status checks: 2\/2 checks passed<\/strong>. Record instance ID, public IPv4, public DNS and the security group.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-2:<\/strong>&nbsp;One AL2023 EC2 instance is running in a public subnet with Name tag&nbsp;<code>awsdevlab-web-ec2<\/code>, assigned instance role and HTTP ingress only from your IP.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.3 Confirm SSM sees the instance; do not install agents from a shell<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>AWS Systems Manager<\/strong>\u00a0in\u00a0<code>ap-northeast-1<\/code>. Under\u00a0<strong>Node Management \/ Fleet Manager \u2192 Managed nodes<\/strong>, look for the EC2 instance ID. Console navigation grouping may vary; search\u00a0<strong>Managed nodes<\/strong>\u00a0inside Systems Manager if necessary.<\/li>\n\n\n\n<li>Confirm the node shows a healthy\/online SSM agent connection. AL2023 Amazon-provided AMIs typically include SSM Agent; registration requires the EC2 IAM role and outbound connectivity.<\/li>\n\n\n\n<li>If not online, revisit the EC2 instance profile, VPC internet route, network ACL, outbound security group and SSM prerequisites. Do not continue until the instance is manageable. [AWS11]<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">4.4 Create the CodeDeploy service role<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>IAM \u2192 Roles \u2192 Create role<\/strong>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>AWS service \u2192 CodeDeploy \u2192 CodeDeploy<\/strong>\u00a0as the use case and\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li>Confirm the console proposes or attaches\u00a0<strong>AWSCodeDeployRole<\/strong>\u00a0managed policy for EC2\/On-Premises deployments.<\/li>\n\n\n\n<li>Set role name\u00a0<code>awsdevlab-codedeploy-role<\/code>; choose\u00a0<strong>Create role<\/strong>.<\/li>\n\n\n\n<li>Open the role and verify its trust principal is\u00a0<code>codedeploy.amazonaws.com<\/code>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-3:<\/strong>&nbsp;The CodeDeploy service role exists and is distinct from the EC2 instance role and the CodeBuild role.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.5 Create the CodeDeploy application and deployment group<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeDeploy \u2192 Deploy \u2192 Applications \u2192 Create application<\/strong>.<\/li>\n\n\n\n<li><strong>Application name:<\/strong>\u00a0<code>awsdevlab-web-app<\/code>.\u00a0<strong>Compute platform:<\/strong>\u00a0<strong>EC2\/On-premises<\/strong>. Choose\u00a0<strong>Create application<\/strong>.<\/li>\n\n\n\n<li>On the application page select\u00a0<strong>Create deployment group<\/strong>.<\/li>\n\n\n\n<li><strong>Deployment group name:<\/strong>\u00a0<code>awsdevlab-web-ec2<\/code>.\u00a0<strong>Service role:<\/strong>\u00a0choose the ARN of\u00a0<code>awsdevlab-codedeploy-role<\/code>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Deployment type<\/strong>, choose\u00a0<strong>In-place<\/strong>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Environment configuration<\/strong>, choose\u00a0<strong>Amazon EC2 instances<\/strong>. Set tag selector\u00a0<strong>Key = Name<\/strong>,\u00a0<strong>Value = awsdevlab-web-ec2<\/strong>. If the console shows a matched-instance count, confirm one target is selected.<\/li>\n\n\n\n<li>Under\u00a0<strong>Agent configuration with AWS Systems Manager<\/strong>, choose\u00a0<strong>Now and schedule updates<\/strong>. This uses Systems Manager to install\/configure the CodeDeploy agent on selected instances;\u00a0<strong>this field is the key to our no-terminal requirement<\/strong>. If this option is absent, see the alternative in Step 4.6. [AWS12]<\/li>\n\n\n\n<li><strong>Deployment configuration:<\/strong>\u00a0<code>CodeDeployDefault.OneAtATime<\/code>.\u00a0<strong>Load balancer:<\/strong>\u00a0disable\u00a0<strong>Enable load balancing<\/strong>\u00a0for this one-instance course.<\/li>\n\n\n\n<li>Review fields; choose\u00a0<strong>Create deployment group<\/strong>.<\/li>\n\n\n\n<li>In the deployment group&#8217;s details, verify\u00a0<strong>in-place<\/strong>, EC2 target tag, CodeDeploy service role and agent management settings. Allow agent installation to finish before deploying.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-4:<\/strong>&nbsp;Application and deployment group exist; the correct EC2 target is registered; CodeDeploy agent installation is being managed by SSM.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.6 Fallback: install CodeDeploy agent with Systems Manager&#8217;s visual package workflow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use this&nbsp;<strong>only if<\/strong>&nbsp;the deployment group&#8217;s agent-management UI is absent or reports an install failure. It is still browser-only.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>Systems Manager \u2192 Node Management \u2192 Distributor<\/strong>\u00a0(or the Systems Manager package-management feature; console groupings change). Choose\u00a0<strong>Third party \/ Amazon-owned packages<\/strong>\u00a0or the repository of available packages.<\/li>\n\n\n\n<li>Search for the AWS package\u00a0<strong><code>AWSCodeDeployAgentV2<\/code><\/strong>, the AWS-documented package for CodeDeploy agent version 2.0 and later. Select the package and\u00a0<strong>Install<\/strong>\u00a0\/\u00a0<strong>Install package<\/strong>.<\/li>\n\n\n\n<li>In the setup choose\u00a0<strong>Installation type: Install<\/strong>\u00a0and target the\u00a0<strong>managed EC2 instance ID<\/strong>\u00a0from 4.2. For recurring updates, choose the update schedule your instructor approves; a one-off install is enough for a disposable lab.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Run \/ Create association<\/strong>\u00a0as the UI offers. View the\u00a0<strong>Command\/Association execution status<\/strong>\u00a0until\u00a0<strong>Success<\/strong>. Do not enter custom shell scripts or use the terminal. [AWS13]<\/li>\n\n\n\n<li>Return to the CodeDeploy deployment group and verify agent readiness. If the package screen differs materially, follow the AWS CodeDeploy agent installation via Systems Manager documentation cited in the References section.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">4.7 Deploy the S3 build output manually<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>S3 \u2192 the standalone artifacts bucket \u2192\u00a0<code>web-demo-release.zip<\/code><\/strong>. From the object detail page, choose\u00a0<strong>Copy S3 URI<\/strong>\u00a0(or copy the actual S3 object path). The value must point to the exact ZIP object, not the bucket, prefix or console webpage URL.<\/li>\n\n\n\n<li>Return to\u00a0<strong>CodeDeploy \u2192 Applications \u2192 awsdevlab-web-app \u2192 Deployments \u2192 Create deployment<\/strong>.<\/li>\n\n\n\n<li><strong>Deployment group:<\/strong>\u00a0<code>awsdevlab-web-ec2<\/code>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Repository \/ Revision type<\/strong>, select\u00a0<strong>My application is stored in Amazon S3<\/strong>.<\/li>\n\n\n\n<li><strong>Revision location:<\/strong>\u00a0paste the full S3 object URI, such as\u00a0<code>s3:\/\/awsdevlab-artifacts-ACCOUNTID-apne1\/web-demo-release.zip<\/code>\u00a0(replace with real bucket\/key).<\/li>\n\n\n\n<li><strong>Revision file type:<\/strong>\u00a0<strong>.zip<\/strong>. Enter description\u00a0<code>Manual deployment of tested CodeBuild release<\/code>.<\/li>\n\n\n\n<li>Leave the configured deployment group strategy, deployment configuration and any optional rollback settings at their course defaults. If auto rollback on failure is available, enable it for safety, but understand a first-time deployment has no last-good revision to roll back to.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Create deployment<\/strong>. Record its deployment ID. [AWS14]<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">4.8 Validate lifecycle execution and the public website<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>On the\u00a0<strong>CodeDeploy deployment detail<\/strong>\u00a0page, inspect\u00a0<strong>Deployment status<\/strong>\u00a0until\u00a0<strong>Succeeded<\/strong>.<\/li>\n\n\n\n<li>Expand\u00a0<strong>Deployment lifecycle events \/ Instance details<\/strong>. Confirm the expected events were completed:\u00a0<strong>BeforeInstall \u2192 Install \u2192 ApplicationStart \u2192 ValidateService<\/strong>.\u00a0<strong>ApplicationStop<\/strong>\u00a0is normally skipped on the\u00a0<strong>first<\/strong>\u00a0deployment because there is no previous successfully deployed revision from which to load a stop hook.<\/li>\n\n\n\n<li>If an event is red\/failed, select its error\/details link or related\u00a0<strong>View logs<\/strong>\u00a0link in the deployment pane. The instance&#8217;s agent logs are not required for the normal success path; the UI&#8217;s failure details should be your first stop.<\/li>\n\n\n\n<li>From\u00a0<strong>EC2 \u2192 Instances \u2192 awsdevlab-web-ec2<\/strong>, copy its\u00a0<strong>Public IPv4 address<\/strong>\u00a0or\u00a0<strong>Public IPv4 DNS<\/strong>. In a new browser tab, open the\u00a0<code>http:\/\/<\/code>\u00a0URL (not\u00a0<code>https:\/\/<\/code>, because the course does not configure TLS).<\/li>\n\n\n\n<li>Confirm the page displays\u00a0<strong>AWS Developer Services Lab<\/strong>, the merged banner from Lab 1,\u00a0<strong>Release: LAB-V1<\/strong>, and a UTC build time. Take a screenshot showing the browser URL and page content.<\/li>\n\n\n\n<li>If the browser times out but CodeDeploy succeeded, check the instance&#8217;s public IP, inbound\u00a0<strong>HTTP\/80<\/strong>\u00a0rule with your current\u00a0<strong>My IP<\/strong>, public route table, and local network restrictions. If the browser returns HTTP error 403\/404, inspect Apache lifecycle hooks or the ZIP&#8217;s path structure.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-5:<\/strong>&nbsp;CodeDeploy deployment status&nbsp;<strong>Succeeded<\/strong>, ValidateService succeeded and a real browser request to the instance&#8217;s public IP returns the released page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 4 troubleshooting matrix<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Symptom<\/th><th class=\"has-text-align-left\" data-align=\"left\">Likely issue<\/th><th class=\"has-text-align-left\" data-align=\"left\">Browser-based recovery<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">No EC2 targets matched<\/td><td class=\"has-text-align-left\" data-align=\"left\">Tag mismatch or wrong Region<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check EC2 Name tag, CodeDeploy group tag Key\/Value and account\/Region<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Deployment never begins \/ skipped target<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy agent not installed \/ not healthy<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check SSM Managed nodes and agent association; use Distributor V2 workflow<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Failed BeforeInstall<\/td><td class=\"has-text-align-left\" data-align=\"left\">Apache package install error \/ outbound internet<\/td><td class=\"has-text-align-left\" data-align=\"left\">Open lifecycle failure, verify public subnet internet and EC2 outbound access; retry after network fix<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Failed Install (missing AppSpec)<\/td><td class=\"has-text-align-left\" data-align=\"left\">ZIP root structure wrong<\/td><td class=\"has-text-align-left\" data-align=\"left\">Open standalone ZIP locally; AppSpec must be at root, rebuild from CodeBuild<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AccessDenied fetching revision<\/td><td class=\"has-text-align-left\" data-align=\"left\">IAM role \/ S3 object \/ KMS<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check EC2 instance profile&nbsp;<code>s3:GetObject<\/code>, exact S3 key and any KMS decrypt grant<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Failed ApplicationStart<\/td><td class=\"has-text-align-left\" data-align=\"left\">Web server not running<\/td><td class=\"has-text-align-left\" data-align=\"left\">Open lifecycle error, confirm AL2023, install hook and scripts in revision<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Failed ValidateService<\/td><td class=\"has-text-align-left\" data-align=\"left\">HTTP endpoint\/content verification failed<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check the rendered&nbsp;<code>index.html<\/code>, Apache service startup and root path<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy Succeeded but public page inaccessible<\/td><td class=\"has-text-align-left\" data-align=\"left\">HTTP\/80 inbound \/ public IP \/ VPC route<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check My IP CIDR, subnet\/IGW, instance public IPv4; use HTTP URL<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 5 \u2014 AWS CodePipeline: automate source \u2192 build \u2192 deploy<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Transform the standalone CodeBuild project into a pipeline-compatible action, create a V2 CodePipeline containing CodeCommit source, CodeBuild build and CodeDeploy deployment, then demonstrate an automatic rebuild and redeployment from an in-browser CodeCommit edit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Two essential integration rules:<\/strong>&nbsp;(1) The existing CodeBuild project must have&nbsp;<strong>Source provider = AWS CodePipeline<\/strong>&nbsp;and&nbsp;<strong>Artifacts type = AWS CodePipeline<\/strong>&nbsp;before the pipeline executes it. (2) The&nbsp;<strong>CodeDeploy action input artifact must be the CodeBuild output<\/strong>&nbsp;(often&nbsp;<code>BuildArtifact<\/code>), not the CodeCommit raw source output (<code>SourceArtifact<\/code>). Missing either rule is a common source of misleading pipelines that cannot deploy the rendered HTML. [AWS15][AWS16]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.1 Reconfigure the existing build project for CodePipeline<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeBuild \u2192 Build projects \u2192 awsdevlab-web-build<\/strong>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Edit \u2192 Source<\/strong>. Change\u00a0<strong>Source provider<\/strong>\u00a0from\u00a0<strong>AWS CodeCommit<\/strong>\u00a0to\u00a0<strong>AWS CodePipeline<\/strong>. The pipeline will now supply source ZIPs to this project. Save\u00a0<strong>Update source<\/strong>\u00a0\/\u00a0<strong>Update configuration<\/strong>, depending on the screen.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Edit \u2192 Artifacts<\/strong>. Change\u00a0<strong>Type<\/strong>\u00a0from\u00a0<strong>Amazon S3<\/strong>\u00a0to\u00a0<strong>AWS CodePipeline<\/strong>; save. This does\u00a0<strong>not<\/strong>\u00a0delete the standalone ZIP created earlier in S3.<\/li>\n\n\n\n<li>Verify\u00a0<strong>Environment<\/strong>\u00a0still uses AL2023 x86_64 standard 6.0,\u00a0<strong>Service role<\/strong>\u00a0is the same CodeBuild role (with CodeArtifact read access), and\u00a0<strong>Buildspec<\/strong>\u00a0still uses root\u00a0<code>buildspec.yml<\/code>.<\/li>\n\n\n\n<li>On project details verify\u00a0<strong>Source: AWS CodePipeline<\/strong>\u00a0and\u00a0<strong>Artifacts: AWS CodePipeline<\/strong>. Do\u00a0<strong>not<\/strong>\u00a0use\u00a0<strong>Start build<\/strong>\u00a0directly for another standalone test; pipeline now supplies the input source and manages artifacts.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CP-1:<\/strong>&nbsp;The existing, already-tested CodeBuild project is configured for CodePipeline source and artifact exchange.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.2 Create the V2 custom pipeline in the AWS console<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodePipeline \u2192 Pipelines \u2192 Create pipeline<\/strong>.<\/li>\n\n\n\n<li>On\u00a0<strong>Choose creation option<\/strong>, select\u00a0<strong>Build custom pipeline<\/strong>, then\u00a0<strong>Next<\/strong>. Avoid a prebuilt template that changes the pipeline&#8217;s service architecture.<\/li>\n\n\n\n<li>On\u00a0<strong>Pipeline settings<\/strong>, set\u00a0<strong>Pipeline name<\/strong>\u00a0<code>awsdevlab-web-pipeline<\/code>.<\/li>\n\n\n\n<li>For\u00a0<strong>Pipeline type<\/strong>, use\u00a0<strong>V2<\/strong>\u00a0(the current console experience). Select\u00a0<strong>New service role<\/strong>\u00a0and allow AWS to create the CodePipeline service role. Record its role ARN. Keep the default same-Region S3 pipeline artifact store unless organizational policy requires a preexisting protected artifact bucket. Choose\u00a0<strong>Next<\/strong>. [AWS02]<\/li>\n\n\n\n<li><strong>Add source stage<\/strong>:\u00a0<strong>Source provider = AWS CodeCommit<\/strong>.\u00a0<strong>Repository name = awsdevlab-webapp<\/strong>.\u00a0<strong>Branch name = main<\/strong>. For\u00a0<strong>Output artifact format<\/strong>, choose\u00a0<strong>CodePipeline default<\/strong>,\u00a0<strong>not Full clone<\/strong>, because the deployment later needs buildable ZIP contents. Enable\u00a0<strong>Start the pipeline on source code change \/ EventBridge change detection<\/strong>. Confirm the source output artifact name, normally\u00a0<strong>SourceArtifact<\/strong>. Choose\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li><strong>Add build stage<\/strong>:\u00a0<strong>Build provider = AWS CodeBuild<\/strong>. Select\u00a0<strong>Existing project<\/strong>, then choose\u00a0<code>awsdevlab-web-build<\/code>. Keep build mode\u00a0<strong>Single build<\/strong>\u00a0if offered, not batch build. Confirm the build receives\u00a0<strong>SourceArtifact<\/strong>\u00a0and will produce a new output artifact, normally\u00a0<strong>BuildArtifact<\/strong>. Choose\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li><strong>Add test stage<\/strong>, if offered: choose\u00a0<strong>Skip test stage<\/strong>, since CodeBuild already runs the automated test in its PRE_BUILD phase. For production, consider a distinct dedicated test stage.<\/li>\n\n\n\n<li><strong>Add deploy stage<\/strong>:\u00a0<strong>Deploy provider = AWS CodeDeploy<\/strong>.\u00a0<strong>Application name = awsdevlab-web-app<\/strong>.\u00a0<strong>Deployment group = awsdevlab-web-ec2<\/strong>. If there is an\u00a0<strong>Input artifacts<\/strong>\u00a0selector, explicitly choose the\u00a0<strong>CodeBuild output<\/strong>\u00a0(normally\u00a0<strong>BuildArtifact<\/strong>). Choose\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li>On the\u00a0<strong>Review<\/strong>\u00a0page check source repository and branch, build project name, deployment group, artifact wiring and V2 type. Choose\u00a0<strong>Create pipeline<\/strong>.<\/li>\n\n\n\n<li>The pipeline may start an initial execution immediately. In\u00a0<strong>Pipeline details \/ Edit<\/strong>, inspect the\u00a0<strong>Deploy<\/strong>\u00a0action. If it selected\u00a0<strong>SourceArtifact<\/strong>\u00a0or a different input, choose\u00a0<strong>Edit action<\/strong>, set\u00a0<strong>Input artifact<\/strong>\u00a0to the CodeBuild\u00a0<strong>BuildArtifact<\/strong>, and\u00a0<strong>Save<\/strong>\u00a0the pipeline change. Trigger a fresh execution using\u00a0<strong>Release change<\/strong>\u00a0after correcting the input; the first run may have failed if it used an incorrect artifact.<\/li>\n\n\n\n<li>Inspect the pipeline&#8217;s automatically created artifact bucket from\u00a0<strong>Pipeline settings \/ Artifact store<\/strong>\u00a0and record its name. These artifacts are managed separately from the standalone Lab 3 S3 bucket.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CP-2:<\/strong>&nbsp;The pipeline visually shows&nbsp;<strong>Source (CodeCommit) \u2192 Build (CodeBuild) \u2192 Deploy (CodeDeploy)<\/strong>. Source output flows to Build; Build output flows to Deploy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.3 Observe first complete pipeline execution<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>On the pipeline\u00a0<strong>Executions<\/strong>\u00a0or visualization page, choose\u00a0<strong>Release change<\/strong>\u00a0if no execution is in progress; confirm the action when prompted.<\/li>\n\n\n\n<li>Watch\u00a0<strong>Source<\/strong>\u00a0become\u00a0<strong>Succeeded<\/strong>. Select its execution details and verify the\u00a0<strong>main<\/strong>\u00a0branch and latest CodeCommit commit ID.<\/li>\n\n\n\n<li>Watch\u00a0<strong>Build<\/strong>. Follow\u00a0<strong>View details<\/strong>\u00a0to CodeBuild and confirm tests, CodeArtifact npm authentication and\u00a0<code>release\/<\/code>\u00a0packaging all succeed.<\/li>\n\n\n\n<li>Watch\u00a0<strong>Deploy<\/strong>. Follow\u00a0<strong>View details<\/strong>\u00a0to CodeDeploy and confirm the correct application\/deployment group and all lifecycle events succeed.<\/li>\n\n\n\n<li>Once the full pipeline is\u00a0<strong>Succeeded<\/strong>, refresh the browser tab pointing at the EC2 public IP. Confirm the page remains accessible and the\u00a0<strong>Build time (UTC)<\/strong>\u00a0reflects the new pipeline build.<\/li>\n\n\n\n<li>Capture the pipeline execution ID, CodeCommit commit ID, CodeBuild build ID and CodeDeploy deployment ID. These four linked IDs form the traceable evidence chain for the release.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CP-3:<\/strong>&nbsp;A green three-stage pipeline deploys a built ZIP produced by CodeBuild and the HTTP page is healthy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.4 Demonstrate a true automatically triggered change<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeCommit \u2192 awsdevlab-webapp \u2192 Code \u2192 main \u2192 index.html<\/strong>.<\/li>\n\n\n\n<li>Select\u00a0<strong>Edit<\/strong>. Change the visible headline\u00a0<code>AWS Developer Services Lab<\/code>\u00a0(inside the\u00a0<code>&lt;h1><\/code>\u00a0element only) to\u00a0<strong>AWS Developer Services Lab \u2014 Version 2<\/strong>. Keep the separate\u00a0<code>&lt;title><\/code>\u00a0text, the verification marker strings, the\u00a0<code>releaseLabel<\/code>\u00a0template placeholder and the\u00a0<code>lab-check<\/code>\u00a0element untouched.<\/li>\n\n\n\n<li>The\u00a0<strong>source-test checker<\/strong>\u00a0intentionally verifies the phrase\u00a0<strong>AWS Developer Services Lab<\/strong>, which remains a substring of the updated heading, so the test will continue to pass.<\/li>\n\n\n\n<li>Enter commit message\u00a0<code>Release version 2 from CodeCommit console<\/code>\u00a0and choose\u00a0<strong>Commit changes<\/strong>\u00a0directly on\u00a0<code>main<\/code>\u00a0for the automatic-trigger demonstration. (In a governed production workflow, use a pull request with approvals.)<\/li>\n\n\n\n<li>Immediately return to\u00a0<strong>CodePipeline \u2192 awsdevlab-web-pipeline<\/strong>. Observe a\u00a0<strong>new execution<\/strong>\u00a0created by the CodeCommit change. It can take a short time for the event to arrive.<\/li>\n\n\n\n<li>Verify Source, Build, Deploy each become\u00a0<strong>Succeeded<\/strong>. In\u00a0<strong>Build logs<\/strong>, look for PASS and the generated release. In\u00a0<strong>CodeDeploy<\/strong>, confirm ValidateService succeeded.<\/li>\n\n\n\n<li>Refresh the public page. Confirm the new heading\u00a0<strong>AWS Developer Services Lab \u2014 Version 2<\/strong>\u00a0and a changed UTC build time.<\/li>\n\n\n\n<li>Optionally open\u00a0<strong>CodeCommit \u2192 Commits<\/strong>,\u00a0<strong>CodePipeline \u2192 Executions<\/strong>,\u00a0<strong>CodeBuild \u2192 Build history<\/strong>, and\u00a0<strong>CodeDeploy \u2192 Deployments<\/strong>\u00a0side by side and connect the commit, pipeline, build and deployment IDs.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CP-4:<\/strong>&nbsp;A single CodeCommit browser edit automatically results in a tested, packaged and successfully deployed Version 2 website\u2014without manually starting a build or deployment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.5 Optional: introduce a controlled failure and practice recovery<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<code>index.html<\/code>\u00a0through CodeCommit\u00a0<strong>Edit<\/strong>\u00a0and temporarily remove the HTML element with\u00a0<code>id=\"lab-check\"<\/code>. Commit this change on a\u00a0<strong>separate temporary branch<\/strong>\u00a0or on\u00a0<code>main<\/code>\u00a0only if the class permits deliberately failing the training pipeline.<\/li>\n\n\n\n<li>Observe the subsequent Build stage fail its source test in CodeBuild. Confirm CodePipeline\u00a0<strong>does not run a new successful Deploy action<\/strong>\u00a0for that failed source revision; the old website should remain reachable.<\/li>\n\n\n\n<li>Restore the\u00a0<code>id=\"lab-check\"<\/code>\u00a0element using the CodeCommit browser editor and commit the corrected file. Re-run (or allow the trigger to start) the pipeline.<\/li>\n\n\n\n<li>Verify the next pipeline execution becomes\u00a0<strong>Succeeded<\/strong>\u00a0and the website is healthy. Explain why build-time tests prevent a defective revision from reaching the deployment stage.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Safety note:<\/strong>&nbsp;A pipeline source-stage rule, branch permission or manual approval may prevent an automatic trigger. If so, capture that governance behavior as part of the exercise rather than disabling organizational controls without permission.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 5 troubleshooting matrix<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Symptom<\/th><th class=\"has-text-align-left\" data-align=\"left\">Inspect<\/th><th class=\"has-text-align-left\" data-align=\"left\">Corrective action in console<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline build says wrong source type<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild Source settings<\/td><td class=\"has-text-align-left\" data-align=\"left\">Change CodeBuild Source to AWS CodePipeline<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild artifact type mismatch<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild Artifacts settings<\/td><td class=\"has-text-align-left\" data-align=\"left\">Change Type to AWS CodePipeline<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Deploy step says missing AppSpec or raw template shown<\/td><td class=\"has-text-align-left\" data-align=\"left\">Deploy action Input artifacts<\/td><td class=\"has-text-align-left\" data-align=\"left\">Select&nbsp;<strong>BuildArtifact<\/strong>, not SourceArtifact<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">No auto-trigger after CodeCommit commit<\/td><td class=\"has-text-align-left\" data-align=\"left\">Source stage change detection<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check&nbsp;<code>main<\/code>&nbsp;branch, EventBridge rule and pipeline trigger settings; release manually to isolate fault<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline cannot use CodeBuild<\/td><td class=\"has-text-align-left\" data-align=\"left\">Pipeline service role permissions<\/td><td class=\"has-text-align-left\" data-align=\"left\">Confirm&nbsp;<code>codebuild:StartBuild<\/code>,&nbsp;<code>codebuild:BatchGetBuilds<\/code>, build project ARN<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy cannot read pipeline artifact<\/td><td class=\"has-text-align-left\" data-align=\"left\">EC2 instance role \/ artifact bucket and KMS policy<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check managed S3 GetObject and any extra KMS decrypt rights<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Only first pipeline works<\/td><td class=\"has-text-align-left\" data-align=\"left\">Region\/branch, token refresh, artifact names<\/td><td class=\"has-text-align-left\" data-align=\"left\">Trace each stage&#8217;s current input\/output and cloud log references<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Old website after green run<\/td><td class=\"has-text-align-left\" data-align=\"left\">Browser cache, wrong public IP, artifact input<\/td><td class=\"has-text-align-left\" data-align=\"left\">Hard-refresh browser, inspect build timestamp, deploy action artifact and EC2 target tag<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Instructor verification and assessment<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Deliverable checklist<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Gate<\/th><th class=\"has-text-align-left\" data-align=\"left\">Must-have evidence<\/th><th class=\"has-text-align-left\" data-align=\"left\">Pass condition<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">CC-1\/2<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit repo tree; PR diff; merged status<\/td><td class=\"has-text-align-left\" data-align=\"left\">Correct root\/nested paths, main branch, completed review<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CA-1\/2<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact domain, npm upstream, cached lodash<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>web-npm<\/code>&nbsp;and&nbsp;<code>npm-store<\/code>;&nbsp;<code>lodash<\/code>&nbsp;4.17.21 after successful build<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CB-1\/3<\/td><td class=\"has-text-align-left\" data-align=\"left\">Private artifact bucket; CodeBuild status\/log; release ZIP<\/td><td class=\"has-text-align-left\" data-align=\"left\">Succeeded, tests PASS, AppSpec at ZIP root, readable release content<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CD-1\/5<\/td><td class=\"has-text-align-left\" data-align=\"left\">EC2 role\/instance\/SSM; deployment detail; web page<\/td><td class=\"has-text-align-left\" data-align=\"left\">Managed EC2 target, CodeDeploy Succeeded, ValidateService passed, HTTP page loads<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CP-1\/4<\/td><td class=\"has-text-align-left\" data-align=\"left\">Pipeline wiring; second execution; Version 2 page<\/td><td class=\"has-text-align-left\" data-align=\"left\">V2 pipeline, BuildArtifact to Deploy, automatic trigger, page changes<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Clean-up<\/td><td class=\"has-text-align-left\" data-align=\"left\">Empty artifact buckets; deleted EC2 and lab resources<\/td><td class=\"has-text-align-left\" data-align=\"left\">No running instances\/pipelines or remaining paid lab artifacts<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Suggested assessment (100 points):<\/strong>&nbsp;CodeCommit 15; CodeArtifact 15; CodeBuild 20; CodeDeploy 25; CodePipeline 20; safe clean-up 5. Award points only for screenshots\/IDs or in-console evidence; do not award on the basis of claimed success alone.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Security and production-hardening discussion<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>IAM:<\/strong>\u00a0The provided CodeBuild CodeArtifact policy is scoped to one repository\/domain. The beginner-friendly EC2\u00a0<code>AmazonEC2RoleforAWSCodeDeploy<\/code>\u00a0managed policy is broad (<code>s3:*<\/code>\u00a0read-related actions on all resources); consider a custom scope for production, including service-specific buckets, and any required customer-managed KMS permissions.<\/li>\n\n\n\n<li><strong>Package supply chain:<\/strong>\u00a0CodeArtifact is an upstream\/cache boundary, not malware scanning by itself. Pin versions, adopt lockfiles, scan dependency vulnerabilities, govern upstream repositories and consider repository package-origin controls.<\/li>\n\n\n\n<li><strong>Deployment:<\/strong>\u00a0A single EC2 instance and HTTP from My IP are instructional. For production use private instances, an ALB, TLS, launch templates or images with the CodeDeploy agent, Auto Scaling or blue\/green, alarms and rollback.<\/li>\n\n\n\n<li><strong>Build security:<\/strong>\u00a0Keep CodeBuild privileged mode OFF when not needed; avoid plaintext secrets and broad service roles; log and monitor builds, consider VPC endpoints and private package access.<\/li>\n\n\n\n<li><strong>Release governance:<\/strong>\u00a0Prefer PR reviews, protected main branch, manual approval for production stages, deployment windows, change records and automated failure alarms.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">No-terminal cleanup runbook \u2014 perform in this order<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Why the order matters:<\/strong>&nbsp;Pipelines may retrigger from new source commits, deployments may create Systems Manager associations, and S3 buckets may contain automatically generated artifacts. Removing high-level orchestration first reduces orphaned resources.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>CodePipeline:<\/strong>\u00a0Open Pipelines \u2192\u00a0<code>awsdevlab-web-pipeline<\/code>. Stop\/disable active executions or transitions if possible; then select\u00a0<strong>Delete pipeline<\/strong>\u00a0and confirm. Record the CodePipeline-managed S3 artifact bucket from pipeline settings\u00a0<strong>before<\/strong>\u00a0deleting if you have not already recorded it.<\/li>\n\n\n\n<li><strong>CodeDeploy:<\/strong>\u00a0Open Applications \u2192\u00a0<code>awsdevlab-web-app<\/code>; inspect deployment group and any active deployments. Delete the deployment group and application through their\u00a0<strong>Delete<\/strong>\u00a0controls. Review\u00a0<strong>Systems Manager \u2192 State Manager\/Associations<\/strong>\u00a0for any CodeDeploy agent installation\/update associations created for the target and remove lab-only associations if they remain.<\/li>\n\n\n\n<li><strong>EC2:<\/strong>\u00a0Open EC2 \u2192 Instances; select\u00a0<code>awsdevlab-web-ec2<\/code>\u00a0and choose\u00a0<strong>Instance state \u2192 Terminate instance<\/strong>. Confirm termination. Inspect Volumes, Snapshots and Elastic IPs for any lab-only resources left behind; delete only those created by this lab. Delete\u00a0<code>awsdevlab-http-sg<\/code>\u00a0after the instance releases the security group.<\/li>\n\n\n\n<li><strong>CodeBuild:<\/strong>\u00a0Open Build projects \u2192\u00a0<code>awsdevlab-web-build<\/code>\u00a0\u2192\u00a0<strong>Delete<\/strong>. Check its optional CloudWatch Logs group; delete the lab-specific log group after saving any instructional evidence.<\/li>\n\n\n\n<li><strong>CodeCommit:<\/strong>\u00a0Open Repositories \u2192\u00a0<code>awsdevlab-webapp<\/code>\u00a0\u2192\u00a0<strong>Delete repository<\/strong>. Confirm that there is no source data you still need.<\/li>\n\n\n\n<li><strong>CodeArtifact:<\/strong>\u00a0Under Repositories delete\u00a0<code>web-npm<\/code>\u00a0and\u00a0<code>npm-store<\/code>\u00a0(including package contents per prompts), then go to Domains and delete\u00a0<code>awsdevlab<\/code>. You\u00a0<strong>cannot delete a domain until its repositories have been removed<\/strong>.<\/li>\n\n\n\n<li><strong>Amazon S3:<\/strong>\u00a0Empty the standalone\u00a0<code>awsdevlab-artifacts-ACCOUNTID-apne1<\/code>\u00a0bucket, then\u00a0<strong>Delete bucket<\/strong>. Identify the separate CodePipeline-generated artifact bucket\/folder; remove the pipeline&#8217;s lab objects, and delete the bucket\u00a0<strong>only if you confirm no other pipeline shares it<\/strong>. Versioned buckets require removal of\u00a0<strong>all object versions and delete markers<\/strong>.<\/li>\n\n\n\n<li><strong>IAM:<\/strong>\u00a0Delete the lab-specific IAM roles\u00a0<code>awsdevlab-ec2-role<\/code>,\u00a0<code>awsdevlab-codedeploy-role<\/code>, the generated CodeBuild service role, and the generated CodePipeline role\u00a0<strong>only after confirming nothing else uses them<\/strong>. Delete any custom\u00a0<code>AWSDevLabCodeArtifactRead<\/code>\u00a0policy if not reused. Detach policies before deleting roles when the console requests it.<\/li>\n\n\n\n<li><strong>CloudWatch\/EventBridge:<\/strong>\u00a0Inspect for lab-only log groups, alarms and EventBridge rules still present; delete orphaned lab-only resources. Some change detection rules are removed automatically when the pipeline is deleted.<\/li>\n\n\n\n<li><strong>Cost review:<\/strong>\u00a0Open\u00a0<strong>Billing and Cost Management \u2192 Cost Explorer<\/strong>\u00a0after billing data posts. Look for EC2, CodeBuild, CodeArtifact, CodePipeline, S3, public IPv4 and CloudWatch charges. Cost data is not necessarily real time.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Final cleanup gate:<\/strong>&nbsp;EC2 Instances shows no running training EC2, CodePipeline and CodeBuild no longer list training resources, CodeArtifact domain is deleted, the standalone S3 bucket is gone, and training IAM roles are removed or explicitly retained by policy.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Reference guide: verified documentation and sample provenance<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Key<\/th><th class=\"has-text-align-left\" data-align=\"left\">Current authoritative\/reference material<\/th><th class=\"has-text-align-left\" data-align=\"left\">URL<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS01<\/td><td class=\"has-text-align-left\" data-align=\"left\">AWS announcement: CodeCommit returned to general availability (24 November 2025)<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/aws.amazon.com\/blogs\/devops\/aws-codecommit-returns-to-general-availability\/\">https:\/\/aws.amazon.com\/blogs\/devops\/aws-codecommit-returns-to-general-availability\/<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS02<\/td><td class=\"has-text-align-left\" data-align=\"left\">AWS CodePipeline: create a custom pipeline (console), V1\/V2, stages and change detection<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/pipelines-create.html\">https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/pipelines-create.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS03<\/td><td class=\"has-text-align-left\" data-align=\"left\">AWS CodePipeline tutorial: CodeCommit browser files and nested paths<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/tutorials-simple-codecommit.html\">https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/tutorials-simple-codecommit.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS04<\/td><td class=\"has-text-align-left\" data-align=\"left\">AWS CodeArtifact: getting started using the console<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/getting-started-console.html\">https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/getting-started-console.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS05<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact authentication\/token behavior<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/tokens-authentication.html\">https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/tokens-authentication.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS06<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact: using npm packages in CodeBuild and IAM permissions<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/using-npm-packages-in-codebuild.html\">https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/using-npm-packages-in-codebuild.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS07<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild: create build project through console<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/create-project.html\">https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/create-project.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS08<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild: buildspec syntax and artifact base-directory<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/build-spec-ref.html\">https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/build-spec-ref.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS09<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild: currently available runtimes and images<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/available-runtimes.html\">https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/available-runtimes.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS10<\/td><td class=\"has-text-align-left\" data-align=\"left\">Managed EC2 CodeDeploy role scope (AWS managed policy)<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/aws-managed-policy\/latest\/reference\/AmazonEC2RoleforAWSCodeDeploy.html\">https:\/\/docs.aws.amazon.com\/aws-managed-policy\/latest\/reference\/AmazonEC2RoleforAWSCodeDeploy.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS11<\/td><td class=\"has-text-align-left\" data-align=\"left\">Systems Manager: managing EC2 as managed nodes<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/systems-manager\/latest\/userguide\/systems-manager-setting-up-nodes.html\">https:\/\/docs.aws.amazon.com\/systems-manager\/latest\/userguide\/systems-manager-setting-up-nodes.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS12<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy\/CodePipeline tutorial: configure agent using SSM in deployment group<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/tutorials-simple-codecommit.html\">https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/tutorials-simple-codecommit.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS13<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy: install CodeDeploy agent through Systems Manager Distributor<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codedeploy\/latest\/userguide\/codedeploy-agent-operations-install-ssm.html\">https:\/\/docs.aws.amazon.com\/codedeploy\/latest\/userguide\/codedeploy-agent-operations-install-ssm.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS14<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy: create EC2\/on-prem deployment with S3 revision<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codedeploy\/latest\/userguide\/deployments-create-console.html\">https:\/\/docs.aws.amazon.com\/codedeploy\/latest\/userguide\/deployments-create-console.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS15<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild: change project source and artifacts in the console<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/change-project.html\">https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/change-project.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS16<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline: CodeDeploy deploy action and artifact requirements<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/action-reference-CodeDeploy.html\">https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/action-reference-CodeDeploy.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS17<\/td><td class=\"has-text-align-left\" data-align=\"left\">GitHub sample: AWS CodeDeploy&nbsp;<code>SampleApp_Linux<\/code>&nbsp;(architecture and origin)<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/github.com\/aws-samples\/aws-codedeploy-samples\/tree\/master\/applications\/SampleApp_Linux\">https:\/\/github.com\/aws-samples\/aws-codedeploy-samples\/tree\/master\/applications\/SampleApp_Linux<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS18<\/td><td class=\"has-text-align-left\" data-align=\"left\">lodash package source and current npm package information<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/lodash\">https:\/\/www.npmjs.com\/package\/lodash<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Source integrity reminder:<\/strong>&nbsp;This guide is an original training adaptation, not a claim that the GitHub sample was written for CodeArtifact or AL2023. For exact upstream source and license, review the AWS GitHub repository. The downloadable training ZIP contains the files participants should transfer through the CodeCommit browser editor. No AWS or GitHub credentials are bundled.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th class=\"has-text-align-left\" data-align=\"left\">title<\/th><td class=\"has-text-align-left\" data-align=\"left\">AWS Developer Services: Gold-Standard Console Lab Guide<\/td><\/tr><tr><th class=\"has-text-align-left\" data-align=\"left\">subtitle<\/th><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit \u2022 CodeArtifact \u2022 CodeBuild \u2022 CodeDeploy \u2022 CodePipeline<\/td><\/tr><tr><th class=\"has-text-align-left\" data-align=\"left\">author<\/th><td class=\"has-text-align-left\" data-align=\"left\">Instructor Edition | Browser-Only Labs<\/td><\/tr><tr><th class=\"has-text-align-left\" data-align=\"left\">date<\/th><td class=\"has-text-align-left\" data-align=\"left\">10 November 2026<\/td><\/tr><tr><th class=\"has-text-align-left\" data-align=\"left\">lang<\/th><td class=\"has-text-align-left\" data-align=\"left\">en-US<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Course navigation<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Lab<\/th><th class=\"has-text-align-left\" data-align=\"left\">AWS service<\/th><th class=\"has-text-align-left\" data-align=\"left\">Practical result<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">1<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodeCommit<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Create a browser-authored repo, branch, PR and merge<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">2<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodeArtifact<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Configure a private npm repository and public upstream<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">3<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodeBuild<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Resolve dependencies, test, create a deployable ZIP<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">4<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodeDeploy<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Deploy the tested ZIP to AL2023 EC2 without SSH<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">5<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>CodePipeline<\/strong><\/td><td class=\"has-text-align-left\" data-align=\"left\">Automate commit-triggered build and deployment<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\">Instructor&#8217;s quick start<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Course outcome.<\/strong>&nbsp;Complete five connected, independently verifiable labs that take one small web application from source control through dependency acquisition, automated build and tests, manual deployment, and change-triggered continuous delivery. All user interactions take place in web browsers and the AWS Management Console.&nbsp;<strong>Learners never use a terminal, AWS CLI, CloudShell, Session Manager shell, or local Git client.<\/strong>&nbsp;The supplied build and deployment scripts execute automatically&nbsp;<em>inside managed AWS services<\/em>; they are configuration files, not manual lab commands.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Source starting point.<\/strong>&nbsp;The lab adapts the idea of the official AWS GitHub repository&nbsp;<strong>aws-samples\/aws-codedeploy-samples<\/strong>, specifically&nbsp;<strong>applications\/SampleApp_Linux<\/strong>, into an Amazon Linux 2023-friendly static website with a meaningful Node.js build using an npm package from CodeArtifact. Original sample:&nbsp;<a href=\"https:\/\/github.com\/aws-samples\/aws-codedeploy-samples\/tree\/master\/applications\/SampleApp_Linux\">https:\/\/github.com\/aws-samples\/aws-codedeploy-samples\/tree\/master\/applications\/SampleApp_Linux<\/a>&nbsp;. This manual uses a separately provided&nbsp;<strong>AWS_Developer_Services_Console_Lab_Source.zip<\/strong>, whose text files are created in CodeCommit through the browser. The GitHub repository is the provenance\/reference; the ZIP is the modernized educational derivative.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Currency and verification disclosure.<\/strong>&nbsp;Research checked AWS&#8217;s publicly available CodeCommit, CodeArtifact, CodeBuild, CodeDeploy, Systems Manager and CodePipeline instructions on&nbsp;<strong>10 November 2026<\/strong>. The source tree, JSON, YAML and shell syntax were inspected offline.&nbsp;<strong>AWS account-specific execution, current live console screenshots and end-to-end runtime outcomes have not been verified<\/strong>: no access to a training AWS account was provided, and package installation from npm could not be exercised in the authoring environment. AWS can change field labels, Region availability, defaults and wizard ordering. Follow the named AWS documentation links in the final section whenever a screen differs. No simulated screenshots are presented as real console evidence.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Important service status.<\/strong>&nbsp;AWS announced on 24 November 2025 that&nbsp;<strong>CodeCommit returned to general availability for new customers<\/strong>. Do not follow older training materials claiming it is closed to new customers. Current CodePipeline documentation uses the&nbsp;<strong>Build custom pipeline<\/strong>&nbsp;creation choice and a&nbsp;<strong>V2<\/strong>&nbsp;pipeline experience. [AWS01][AWS02]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Architecture at a glance<\/h2>\n\n\n\n<pre class=\"wp-block-code\"><code>GitHub sample (reference)\n         |\n         v  Copy modernized source files through CodeCommit browser editor\nAWS CodeCommit (main)\n         |\n         +--&gt; CodePipeline Source stage --&gt; CodeBuild Build stage --&gt; CodeDeploy Deploy stage\n                                             |                      |\n                    AWS CodeArtifact &lt;-------+                      v\n                     npm upstream                           Amazon EC2 (AL2023)\n                    &#91;lodash 4.17.21]                          Apache web server\n                                             |\n                               build release ZIP: appspec.yml,\n                               index.html, scripts\/*\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The same release ZIP is first deployed manually from Amazon S3 during&nbsp;<strong>Lab 4<\/strong>. Later, CodePipeline passes CodeBuild&#8217;s output artifact directly to CodeDeploy in&nbsp;<strong>Lab 5<\/strong>;&nbsp;<strong>do not deploy the unbuilt CodeCommit source artifact<\/strong>, because&nbsp;<code>index.html<\/code>&nbsp;contains build-time template placeholders.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Time, cost and prerequisites<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Item<\/th><th class=\"has-text-align-left\" data-align=\"left\">Requirement or recommendation<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">Course duration<\/td><td class=\"has-text-align-left\" data-align=\"left\">4\u20136 hours instructor-led; 6\u20138 hours for first-time learners, excluding provisioning delays<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS account<\/td><td class=\"has-text-align-left\" data-align=\"left\">Nonproduction, disposable training account preferred; access to IAM, EC2, CodeCommit, CodeArtifact, CodeBuild, CodeDeploy, CodePipeline, Systems Manager, S3 and CloudWatch<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">User permissions<\/td><td class=\"has-text-align-left\" data-align=\"left\">A training-admin or an approved permission set capable of creating IAM roles\/policies and passing them to AWS services; no root-user access<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Region<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>Asia Pacific (Tokyo), ap-northeast-1<\/strong>, throughout; use another common Region only after adapting all Region references<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Network<\/td><td class=\"has-text-align-left\" data-align=\"left\">Default VPC with at least one public subnet and outbound internet, EC2 auto-assigned public IPv4, Systems Manager connectivity and HTTP\/80 access from learner&#8217;s current public IP<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Browser<\/td><td class=\"has-text-align-left\" data-align=\"left\">Current Chrome, Edge, Firefox or Safari with downloads and clipboard enabled<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Downloads<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>AWS_Developer_Services_Console_Lab_Source.zip<\/strong>&nbsp;and this manual; extract ZIP locally using the operating system&#8217;s file manager (no terminal)<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Cost<\/td><td class=\"has-text-align-left\" data-align=\"left\"><strong>Not free by default<\/strong>. EC2 compute, EBS, public IPv4, CodeBuild, CodeArtifact, CodePipeline, S3, CloudWatch and requests may incur charges; charges vary by account\/Region\/usage. Clean up same day.<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Security<\/td><td class=\"has-text-align-left\" data-align=\"left\">Personal training account, least privileges where practical, S3 Block Public Access ON, EC2 TCP\/80 from&nbsp;<strong>My IP<\/strong>&nbsp;only, no SSH needed, never store credentials in Git<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Start-of-class gate.<\/strong>&nbsp;Open the AWS account menu, record the&nbsp;<strong>12-digit account ID<\/strong>, and verify the Region&nbsp;<strong>Asia Pacific (Tokyo)<\/strong>&nbsp;is displayed in each console. If a default VPC is absent, ask the instructor to supply a VPC with a public subnet and an internet route; do not create a public EC2 target in a private subnet by mistake. All example resource names are illustrative and should be kept consistent throughout.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Fixed naming worksheet \u2014 complete before opening Lab 1<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Resource<\/th><th class=\"has-text-align-left\" data-align=\"left\">Name\/value used in this guide<\/th><th class=\"has-text-align-left\" data-align=\"left\">Record actual value<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">Region<\/td><td class=\"has-text-align-left\" data-align=\"left\">ap-northeast-1<\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS account ID<\/td><td class=\"has-text-align-left\" data-align=\"left\">12-digit AWS account ID<\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit repository<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-webapp<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit branch<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>main<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact domain<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact downstream repository<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>web-npm<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact public upstream<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>npm-store<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild project<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-build<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">S3 standalone artifact bucket<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-artifacts-ACCOUNTID-apne1<\/code>&nbsp;(replace ACCOUNTID)<\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">IAM EC2 instance role<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-ec2-role<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">IAM CodeDeploy service role<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-codedeploy-role<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">EC2 instance Name tag<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-ec2<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">EC2 security group<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-http-sg<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy application<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-app<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy deployment group<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-ec2<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline pipeline<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>awsdevlab-web-pipeline<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline artifact bucket<\/td><td class=\"has-text-align-left\" data-align=\"left\">Created by pipeline wizard; record later<\/td><td class=\"has-text-align-left\" data-align=\"left\">__________________<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Naming note.<\/strong>&nbsp;S3 bucket names are globally unique. If the proposed bucket name is unavailable, append a short suffix and update every reference to that bucket. Avoid changing the fixed CodeArtifact names unless you also edit&nbsp;<code>buildspec.yml<\/code>&nbsp;through CodeCommit&#8217;s browser editor.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 1 \u2014 AWS CodeCommit: store and review the application<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Create a Git repository, populate it with the modernized GitHub-derived application, browse commit history, and complete one browser-only branch and pull request workflow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Before you begin.<\/strong>&nbsp;Sign in with the assigned training IAM Identity Center role or IAM identity; Region is&nbsp;<code>ap-northeast-1<\/code>. Download and extract the provided source ZIP using the graphical file manager. Have a name and contact email available for commit metadata (not credentials).<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.1 Create the repository<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>In the AWS Console search bar, search\u00a0<strong>CodeCommit<\/strong>\u00a0and open the service (direct link:\u00a0<a href=\"https:\/\/console.aws.amazon.com\/codecommit\/\">https:\/\/console.aws.amazon.com\/codecommit\/<\/a>\u00a0).<\/li>\n\n\n\n<li>Check the Region selector in the top bar: choose\u00a0<strong>Asia Pacific (Tokyo)<\/strong>.<\/li>\n\n\n\n<li>In the left navigation choose\u00a0<strong>Repositories<\/strong>; select\u00a0<strong>Create repository<\/strong>.<\/li>\n\n\n\n<li>In\u00a0<strong>Repository name<\/strong>, enter\u00a0<code>awsdevlab-webapp<\/code>.<\/li>\n\n\n\n<li>In\u00a0<strong>Description<\/strong>, enter\u00a0<code>Browser-only AWS developer tools training application<\/code>.<\/li>\n\n\n\n<li>Keep repository encryption at the AWS-managed\/default setting offered by your account. Do not configure CodeGuru or optional integrations for this lab unless your console mandates a setting.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Create<\/strong>. Wait for the new repository&#8217;s detail page to open.<\/li>\n\n\n\n<li>Select its\u00a0<strong>Code<\/strong>\u00a0view. An empty-repository prompt is expected: there is no default branch until your first browser-created commit.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CC-1:<\/strong>&nbsp;Repositories lists&nbsp;<code>awsdevlab-webapp<\/code>. Copy its HTTPS clone URL only as reference;&nbsp;<strong>do not open a terminal or clone it<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.2 Add the application using only the CodeCommit web editor<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>From the repository&#8217;s\u00a0<strong>Code<\/strong>\u00a0tab, choose\u00a0<strong>Add file \u2192 Create file<\/strong>. Open\u00a0<code>README.md<\/code>\u00a0from the extracted source folder in a graphical text editor; copy all its contents into the CodeCommit editor; enter\u00a0<strong>File name<\/strong>\u00a0<code>README.md<\/code>.<\/li>\n\n\n\n<li>Fill\u00a0<strong>Author name<\/strong>,\u00a0<strong>Email address<\/strong>, and\u00a0<strong>Commit message<\/strong>\u00a0(for example,\u00a0<code>Add lab README<\/code>). Select\u00a0<strong>Commit changes<\/strong>. The console creates the\u00a0<code>main<\/code>\u00a0branch for the first commit in a new repository.<\/li>\n\n\n\n<li>Return to the repository&#8217;s\u00a0<strong>Code<\/strong>\u00a0tab and confirm the branch drop-down shows\u00a0<strong>main<\/strong>. For each file below, repeat\u00a0<strong>Add file \u2192 Create file<\/strong>, paste the file&#8217;s text, enter its exact path in\u00a0<strong>File name<\/strong>, provide the same author\/email and a meaningful commit message, then choose\u00a0<strong>Commit changes<\/strong>:File name to create in CodeCommitPurpose<code>index.html<\/code>Site HTML template and first visible release label<code>package.json<\/code>Pinned npm dependency and build\/test scripts<code>buildspec.yml<\/code>CodeBuild phases, CodeArtifact login and release-artifact selection<code>appspec.yml<\/code>CodeDeploy file mapping and lifecycle events<code>scripts\/install_dependencies<\/code>Install Apache and curl on Amazon Linux 2023<code>scripts\/start_server<\/code>Start and enable Apache<code>scripts\/stop_server<\/code>Graceful stop before later deployments<code>scripts\/validate_server<\/code>Local service and HTTP content verification<code>tests\/verify-source.cjs<\/code>Automated source checks<code>tools\/build-release.cjs<\/code>Build release HTML and stage deployment package<\/li>\n\n\n\n<li>For nested names,\u00a0<strong>type the entire relative path<\/strong>\u00a0such as\u00a0<code>scripts\/start_server<\/code>\u00a0in the\u00a0<strong>Create file<\/strong>\u00a0dialog; AWS&#8217;s CodeCommit training tutorial documents this browser-only folder-creation method. Do not flatten paths to the root. [AWS03]<\/li>\n\n\n\n<li>Verify the repository tree shows\u00a0<code>README.md<\/code>,\u00a0<code>index.html<\/code>,\u00a0<code>package.json<\/code>,\u00a0<code>buildspec.yml<\/code>,\u00a0<code>appspec.yml<\/code>, and folders\u00a0<code>scripts\/<\/code>,\u00a0<code>tests\/<\/code>,\u00a0<code>tools\/<\/code>.<\/li>\n\n\n\n<li>Open\u00a0<code>buildspec.yml<\/code>\u00a0in CodeCommit and verify the\u00a0<strong>domain<\/strong>\u00a0is\u00a0<code>awsdevlab<\/code>, the\u00a0<strong>repository<\/strong>\u00a0is\u00a0<code>web-npm<\/code>, and\u00a0<code>artifacts.base-directory<\/code>\u00a0is\u00a0<code>release<\/code>.<\/li>\n\n\n\n<li>Open\u00a0<code>appspec.yml<\/code>\u00a0and verify it is located at the\u00a0<strong>repository root<\/strong>, includes\u00a0<code>ValidateService<\/code>, and installs\u00a0<code>\/index.html<\/code>\u00a0to\u00a0<code>\/var\/www\/html\/<\/code>.<\/li>\n\n\n\n<li>Select\u00a0<strong>Commits<\/strong>\u00a0or\u00a0<strong>History<\/strong>\u00a0in the repository navigation to confirm each browser-created file produced a commit on\u00a0<code>main<\/code>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Important:<\/strong>&nbsp;Uploading the&nbsp;<strong>entire ZIP<\/strong>&nbsp;as one CodeCommit repository file does&nbsp;<strong>not<\/strong>&nbsp;unpack it into Git. Use the&nbsp;<strong>Create file<\/strong>&nbsp;editor separately for the listed file paths. This is deliberately slower than Git push but honors the browser-only requirement. Never paste the ZIP&#8217;s binary data into the editor.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1.3 Practice branching, review and merge entirely in CodeCommit<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Select\u00a0<strong>Branches<\/strong>\u00a0in the repository. Choose\u00a0<strong>Create branch<\/strong>\u00a0(the exact control may be under the\u00a0<strong>Branches<\/strong>\u00a0view).<\/li>\n\n\n\n<li>Set\u00a0<strong>Branch name<\/strong>\u00a0<code>feature\/lab-banner<\/code>\u00a0and\u00a0<strong>Branch from<\/strong>\u00a0<code>main<\/code>; select\u00a0<strong>Create branch<\/strong>.<\/li>\n\n\n\n<li>Return to\u00a0<strong>Code<\/strong>, select branch\u00a0<code>feature\/lab-banner<\/code>, and open\u00a0<code>index.html<\/code>.<\/li>\n\n\n\n<li>Select\u00a0<strong>Edit<\/strong>, locate the visible sentence\u00a0<code>Five services. One end-to-end delivery workflow.<\/code>, and replace it with\u00a0<code>Source control review completed. Ready for CI\/CD.<\/code>\u00a0Leave\u00a0<code>&lt;%- releaseLabel %><\/code>\u00a0and\u00a0<code>&lt;%- builtAt %><\/code>\u00a0placeholders untouched.<\/li>\n\n\n\n<li>Enter a meaningful commit message such as\u00a0<code>Update demo banner in feature branch<\/code>; choose\u00a0<strong>Commit changes<\/strong>. Confirm that\u00a0<code>main<\/code>\u00a0still has the original text and\u00a0<code>feature\/lab-banner<\/code>\u00a0has the update.<\/li>\n\n\n\n<li>Go to\u00a0<strong>Pull requests \u2192 Create pull request<\/strong>. Select\u00a0<strong>Source<\/strong>\u00a0<code>feature\/lab-banner<\/code>\u00a0and\u00a0<strong>Destination<\/strong>\u00a0<code>main<\/code>.<\/li>\n\n\n\n<li>Review the diff. Enter title\u00a0<code>Update training website banner<\/code>\u00a0and a description of the change; choose\u00a0<strong>Create pull request<\/strong>.<\/li>\n\n\n\n<li>In the pull request, review the\u00a0<strong>Changes<\/strong>\u00a0tab, add a review comment if available, then choose\u00a0<strong>Merge<\/strong>. Select a permitted merge strategy (for a simple, conflict-free example choose\u00a0<strong>Fast forward<\/strong>\u00a0if offered), confirm the destination is\u00a0<code>main<\/code>, and complete the merge.<\/li>\n\n\n\n<li>Return to branch\u00a0<code>main<\/code>\u00a0and open\u00a0<code>index.html<\/code>. Confirm the updated sentence is present and the pull request is merged\/closed.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CC-2:<\/strong>&nbsp;A named feature branch, a reviewed and merged pull request, and the modified file on&nbsp;<code>main<\/code>&nbsp;are visible in the CodeCommit console. If required by an organizational approval rule, ask another authorized learner to approve instead of bypassing governance.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 1 evidence to capture<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Screenshot: repository name with\u00a0<code>main<\/code>\u00a0branch and complete folder tree.<\/li>\n\n\n\n<li>Screenshot: pull request diff and merged status.<\/li>\n\n\n\n<li>Record: repository ARN, default branch, most recent commit ID.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 1 troubleshooting<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>AccessDenied on creation or commit:<\/strong>\u00a0check the trainee permission set and account\/Region; a repository policy or organization SCP may restrict\u00a0<code>codecommit:CreateRepository<\/code>,\u00a0<code>PutFile<\/code>\u00a0or merge permissions.<\/li>\n\n\n\n<li><strong>No main branch:<\/strong>\u00a0complete the first browser-created file and refresh the page.<\/li>\n\n\n\n<li><strong>Missing\u00a0<code>scripts\/<\/code>\u00a0folder:<\/strong>\u00a0nested file paths must be entered in the filename field on\u00a0<strong>Create file<\/strong>, not in a flat\u00a0<strong>Upload file<\/strong>\u00a0chooser.<\/li>\n\n\n\n<li><strong>Pull request cannot merge:<\/strong>\u00a0verify destination\/main, source\/feature, merge conflicts, branch policies and required approvals.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 2 \u2014 AWS CodeArtifact: manage build dependencies<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Create an AWS CodeArtifact domain and npm repository connected to the public npm registry, grant the CodeBuild role secure read access, and later verify that CodeBuild actually fetched the pinned&nbsp;<code>lodash<\/code>&nbsp;dependency through CodeArtifact.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Note on order.<\/strong>&nbsp;This lab creates the repository. The first package version will appear under Packages&nbsp;<strong>after the initial CodeBuild execution in Lab 3<\/strong>. A console-only learner does not need to authenticate npm on a local machine.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2.1 Create domain, downstream repository and npm upstream<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Use AWS Console search to open\u00a0<strong>CodeArtifact<\/strong>\u00a0(direct link:\u00a0<a href=\"https:\/\/console.aws.amazon.com\/codesuite\/codeartifact\/start\">https:\/\/console.aws.amazon.com\/codesuite\/codeartifact\/start<\/a>\u00a0). Check Region\u00a0<code>ap-northeast-1<\/code>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Create repository<\/strong>\u00a0from the Repositories view.<\/li>\n\n\n\n<li>Set\u00a0<strong>Repository name<\/strong>\u00a0to\u00a0<code>web-npm<\/code>\u00a0and optional description\u00a0<code>Dependencies consumed by the web application CodeBuild project<\/code>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Public upstream repositories<\/strong>, select the\u00a0<strong>npm-store<\/strong>\u00a0option that connects to the public npmjs registry. The wizard will create\/link an upstream repository named\u00a0<code>npm-store<\/code>.\u00a0<strong>Do not leave the public upstream selection empty<\/strong>; this is how the first\u00a0<code>lodash<\/code>\u00a0package is ingested.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Next<\/strong>. For\u00a0<strong>AWS account<\/strong>, choose\u00a0<strong>This AWS account<\/strong>.<\/li>\n\n\n\n<li>For\u00a0<strong>Domain name<\/strong>, enter\u00a0<code>awsdevlab<\/code>\u00a0(new domain). If a domain already exists, only reuse it if your instructor confirms the domain ownership and permissions.<\/li>\n\n\n\n<li>Under\u00a0<strong>Additional configuration<\/strong>, choose the\u00a0<strong>AWS managed key<\/strong>\u00a0for domain encryption for this disposable lab; customer-managed KMS keys require additional permissions.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Next<\/strong>, review the package flow\u00a0<code>web-npm \u2192 npm-store \u2192 npmjs<\/code>, then\u00a0<strong>Create repository<\/strong>.<\/li>\n\n\n\n<li>From\u00a0<strong>Repositories<\/strong>, verify both\u00a0<code>web-npm<\/code>\u00a0and\u00a0<code>npm-store<\/code>\u00a0exist and are associated with domain\u00a0<code>awsdevlab<\/code>; from\u00a0<strong>Domains<\/strong>, verify\u00a0<code>awsdevlab<\/code>\u00a0exists.<\/li>\n\n\n\n<li>Open repository\u00a0<strong>web-npm<\/strong>\u00a0and select\u00a0<strong>View connection instructions<\/strong>\u00a0\u2192\u00a0<strong>npm<\/strong>. Inspect the displayed domain\/repository\/Region endpoint. This screen is for understanding the connection;\u00a0<strong>do not execute the suggested terminal login command<\/strong>. Authentication will occur inside CodeBuild using\u00a0<code>buildspec.yml<\/code>\u00a0in Lab 3. [AWS04]<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CA-1:<\/strong>&nbsp;CodeArtifact&#8217;s repository view shows&nbsp;<code>web-npm<\/code>, its upstream&nbsp;<code>npm-store<\/code>&nbsp;and the new domain&nbsp;<code>awsdevlab<\/code>. The package list might correctly be empty until Lab 3.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2.2 Prepare the future CodeBuild access policy in IAM<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The policy below is intended for the&nbsp;<strong>CodeBuild service role<\/strong>, not the trainee identity or EC2 instance. Create it after CodeBuild creates its role in Lab 3 (the next section gives the exact console steps). Do not place CodeArtifact tokens in CodeCommit,&nbsp;<code>package.json<\/code>, or CodeBuild plaintext environment variables. Each build automatically acquires a short-lived token. [AWS05]<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>IAM policy template \u2014 replace&nbsp;<code>ACCOUNT_ID<\/code>&nbsp;with your 12-digit account ID before saving. This is policy JSON, not a terminal command.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": &#91;\n    {\n      \"Sid\": \"CodeArtifactDomainToken\",\n      \"Effect\": \"Allow\",\n      \"Action\": \"codeartifact:GetAuthorizationToken\",\n      \"Resource\": \"arn:aws:codeartifact:ap-northeast-1:ACCOUNT_ID:domain\/awsdevlab\"\n    },\n    {\n      \"Sid\": \"CodeArtifactReadRepository\",\n      \"Effect\": \"Allow\",\n      \"Action\": &#91;\n        \"codeartifact:GetRepositoryEndpoint\",\n        \"codeartifact:ReadFromRepository\"\n      ],\n      \"Resource\": \"arn:aws:codeartifact:ap-northeast-1:ACCOUNT_ID:repository\/awsdevlab\/web-npm\"\n    },\n    {\n      \"Sid\": \"AllowServiceBearerToken\",\n      \"Effect\": \"Allow\",\n      \"Action\": \"sts:GetServiceBearerToken\",\n      \"Resource\": \"*\",\n      \"Condition\": {\n        \"StringEquals\": {\n          \"sts:AWSServiceName\": \"codeartifact.amazonaws.com\"\n        }\n      }\n    }\n  ]\n}\n<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Instructor checkpoint:<\/strong>&nbsp;Explain the two trust boundaries: the trainee can configure IAM, while CodeBuild assumes its own execution role.&nbsp;<code>sts:GetServiceBearerToken<\/code>&nbsp;is separate from CodeArtifact&#8217;s repository authorization. The example grants&nbsp;<strong>read<\/strong>, not publish, permissions. [AWS06]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2.3 Return after Lab 3 to prove package use<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>After the\u00a0<strong>first successful CodeBuild run<\/strong>, open\u00a0<strong>CodeArtifact \u2192 Repositories \u2192 web-npm \u2192 Packages<\/strong>.<\/li>\n\n\n\n<li>Refresh. Search for\u00a0<strong>lodash<\/strong>. Open the package and confirm a package version such as\u00a0<code>4.17.21<\/code>\u00a0is present.<\/li>\n\n\n\n<li>Inspect its assets\/metadata. Navigate to\u00a0<strong>npm-store<\/strong>\u00a0and examine the upstream relationship, if shown in your console.<\/li>\n\n\n\n<li>Return to CodeBuild&#8217;s build logs. Confirm the CodeArtifact login phase and package-install phase succeeded; treat CodeArtifact package presence\u00a0<strong>and<\/strong>\u00a0build success together as evidence that the dependency path worked.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CA-2:<\/strong>&nbsp;<code>lodash<\/code>&nbsp;<code>4.17.21<\/code>&nbsp;appears in the downstream repository following a successful build. Package visibility may lag; refresh before troubleshooting.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 2 troubleshooting<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Public package missing after build:<\/strong>\u00a0check upstream\u00a0<code>npm-store<\/code>, public internet egress from CodeBuild, build logs, and whether the build actually installed npm dependencies. Do not assume an empty package list before first build is a fault.<\/li>\n\n\n\n<li><strong>Token authorization error:<\/strong>\u00a0CodeBuild role requires CodeArtifact token + repository read actions\u00a0<strong>and<\/strong>\u00a0<code>sts:GetServiceBearerToken<\/code>; root credentials cannot request a CodeArtifact auth token.<\/li>\n\n\n\n<li><strong>Repository not listed in CodeBuild account:<\/strong>\u00a0verify Region, account, domain and repository spelling. Cross-account CodeArtifact access needs additional resource policies not covered here.<\/li>\n\n\n\n<li><strong>Private VPC build cannot access CodeArtifact\/npmjs:<\/strong>\u00a0use the default service-managed CodeBuild networking for this course; custom VPC builds need additional routes\/endpoints.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 3 \u2014 AWS CodeBuild: test, build and store a release ZIP<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Create a standalone CodeBuild project whose source is CodeCommit, automatically fetch npm&nbsp;<code>lodash<\/code>&nbsp;from CodeArtifact, run tests, generate an&nbsp;<code>index.html<\/code>&nbsp;with a release label, and publish a fully formed CodeDeploy revision as a ZIP in private S3.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>What success looks like:<\/strong>&nbsp;CodeBuild status&nbsp;<strong>Succeeded<\/strong>, test result&nbsp;<strong>PASS<\/strong>, S3 ZIP contains&nbsp;<code>appspec.yml<\/code>,&nbsp;<code>index.html<\/code>, and&nbsp;<code>scripts\/*<\/code>&nbsp;at the archive root, and the CodeArtifact package can be inspected in its console.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.1 Create the private S3 release-artifact bucket<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>Amazon S3 \u2192 Buckets \u2192 Create bucket<\/strong>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>General purpose<\/strong>\u00a0bucket. Set\u00a0<strong>Bucket name<\/strong>\u00a0to\u00a0<code>awsdevlab-artifacts-ACCOUNTID-apne1<\/code>\u00a0(substitute your account ID; append a suffix if already in use).<\/li>\n\n\n\n<li>Set the\u00a0<strong>AWS Region<\/strong>\u00a0to\u00a0<strong>Asia Pacific (Tokyo)<\/strong>.<\/li>\n\n\n\n<li>Leave\u00a0<strong>Block all public access<\/strong>\u00a0enabled. Do not make the bucket or its objects public.<\/li>\n\n\n\n<li>For\u00a0<strong>Bucket Versioning<\/strong>, choose\u00a0<strong>Disable<\/strong>\u00a0for this disposable lab, unless your institution requires versioning (if enabled, cleanup requires deleting versions and delete markers).<\/li>\n\n\n\n<li>For\u00a0<strong>Default encryption<\/strong>, leave\u00a0<strong>SSE-S3<\/strong>\u00a0or another account-approved default. For the simplest lab, use SSE-S3 rather than customer-managed KMS.<\/li>\n\n\n\n<li>Leave other settings at their defaults; choose\u00a0<strong>Create bucket<\/strong>\u00a0and record its exact name.<\/li>\n\n\n\n<li>Open the bucket and confirm the\u00a0<strong>Permissions<\/strong>\u00a0panel shows Block Public Access enabled.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CB-1:<\/strong>&nbsp;Private, same-Region S3 bucket is available and empty.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.2 Create the CodeBuild project<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeBuild \u2192 Build \u2192 Build projects \u2192 Create build project<\/strong>\u00a0(or\u00a0<strong>Create build project<\/strong>\u00a0from the welcome screen).<\/li>\n\n\n\n<li><strong>Project configuration \u2192 Project name:<\/strong>\u00a0<code>awsdevlab-web-build<\/code>. Enter a short description such as\u00a0<code>CodeCommit \u2192 CodeArtifact npm \u2192 test \u2192 S3 deployable ZIP<\/code>.<\/li>\n\n\n\n<li><strong>Source \u2192 Source provider:<\/strong>\u00a0choose\u00a0<strong>AWS CodeCommit<\/strong>.\u00a0<strong>Repository:<\/strong>\u00a0<code>awsdevlab-webapp<\/code>.\u00a0<strong>Reference type:<\/strong>\u00a0Branch.\u00a0<strong>Branch:<\/strong>\u00a0<code>main<\/code>\u00a0(if requested). Leave Git depth and submodules at defaults unless your console requires an option.<\/li>\n\n\n\n<li><strong>Environment \u2192 Provisioning model:<\/strong>\u00a0On-demand (managed).\u00a0<strong>Environment image:<\/strong>\u00a0Managed image.\u00a0<strong>Operating system:<\/strong>\u00a0Amazon Linux.\u00a0<strong>Runtime:<\/strong>\u00a0Standard.\u00a0<strong>Image:<\/strong>\u00a0select\u00a0<strong>Amazon Linux 2023 x86_64 standard:6.0<\/strong>\u00a0(the exact catalog label may include\u00a0<code>aws\/codebuild\/amazonlinux-x86_64-standard:6.0<\/code>). Choose a Linux container and the smallest general-purpose compute option appropriate for a lightweight Node build.<\/li>\n\n\n\n<li><strong>Environment \u2192 Service role:<\/strong>\u00a0choose\u00a0<strong>New service role<\/strong>; note the automatically proposed role name, such as\u00a0<code>codebuild-awsdevlab-web-build-service-role<\/code>. Avoid privileged mode (not required), a custom VPC, secrets or additional environment variables for this lab.<\/li>\n\n\n\n<li><strong>Buildspec \u2192 Build specifications:<\/strong>\u00a0choose\u00a0<strong>Use a buildspec file<\/strong>\u00a0in the source root. Confirm the name is\u00a0<code>buildspec.yml<\/code>\u00a0(do not paste terminal commands into the browser).<\/li>\n\n\n\n<li><strong>Artifacts \u2192 Type:<\/strong>\u00a0<strong>Amazon S3<\/strong>. Select the private bucket created in 3.1.<\/li>\n\n\n\n<li><strong>Artifact name:<\/strong>\u00a0<code>web-demo-release.zip<\/code>. Select\u00a0<strong>ZIP<\/strong>\u00a0packaging. Keep a blank\u00a0<strong>Path<\/strong>, choose\u00a0<strong>No namespace \/ None<\/strong>\u00a0if that field appears, and leave any\u00a0<strong>artifact name override\/semantic versioning<\/strong>\u00a0option\u00a0<strong>off<\/strong>. If the option\u00a0<strong>Remove artifacts encryption<\/strong>\u00a0appears, use it\u00a0<strong>only if<\/strong>\u00a0the bucket enforces SSE-S3 and the course is not using client-side AWS KMS artifact encryption; otherwise use the default encryption and grant the deployment role appropriate KMS decrypt permissions.<\/li>\n\n\n\n<li><strong>Cache:<\/strong>\u00a0No cache for the first run.\u00a0<strong>Logs:<\/strong>\u00a0enable\u00a0<strong>CloudWatch Logs<\/strong>\u00a0to capture the build phases. Accept a generated or explicitly named log group; record it for cleanup.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Create build project<\/strong>. Note the project&#8217;s\u00a0<strong>Service role ARN<\/strong>\u00a0on the details page. [AWS07][AWS08]<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Image selection note.<\/strong>&nbsp;AWS currently documents Node.js&nbsp;<strong>22<\/strong>&nbsp;on the Amazon Linux 2023 standard 6.0 CodeBuild image. Our&nbsp;<code>buildspec.yml<\/code>&nbsp;explicitly selects Node.js 22 to avoid silent runtime changes. [AWS09]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.3 Grant CodeBuild role access through the IAM console<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>IAM \u2192 Roles<\/strong>\u00a0in another tab.<\/li>\n\n\n\n<li>Search for the\u00a0<strong>CodeBuild service role<\/strong>\u00a0recorded in 3.2. Select it; verify its trusted entity\/service is\u00a0<code>codebuild.amazonaws.com<\/code>.<\/li>\n\n\n\n<li>On\u00a0<strong>Permissions<\/strong>, select\u00a0<strong>Add permissions \u2192 Create inline policy<\/strong>\u00a0(or create a customer-managed policy in\u00a0<strong>IAM \u2192 Policies<\/strong>\u00a0and attach it to this role). Open the\u00a0<strong>JSON<\/strong>\u00a0editor.<\/li>\n\n\n\n<li>Replace\u00a0<code>ACCOUNT_ID<\/code>\u00a0in the\u00a0<strong>Lab 2 CodeArtifact policy<\/strong>\u00a0with your actual account ID and paste the full JSON. Choose\u00a0<strong>Next<\/strong>; enter policy name\u00a0<code>AWSDevLabCodeArtifactRead<\/code>; review and\u00a0<strong>Create policy<\/strong>. Wait until the policy appears on the CodeBuild role.<\/li>\n\n\n\n<li>Inspect the existing CodeBuild role permissions for\u00a0<strong>CodeCommit<\/strong>\u00a0source access,\u00a0<strong>CloudWatch Logs<\/strong>, and the chosen\u00a0<strong>S3 output bucket<\/strong>. The console may create some scoped policies automatically; do not assume permissions are present solely because the role exists.<\/li>\n\n\n\n<li>If the role lacks S3 write or CodeCommit pull access, create and attach this\u00a0<strong>supplementary inline policy<\/strong>, replacing\u00a0<code>ACCOUNT_ID<\/code>\u00a0in the resource ARNs and the\u00a0<code>ARTIFACT_BUCKET<\/code>\u00a0value with the actual bucket name:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>{\n  \"Version\": \"2012-10-17\",\n  \"Statement\": &#91;\n    {\n      \"Sid\": \"ReadTrainingCodeCommit\",\n      \"Effect\": \"Allow\",\n      \"Action\": &#91;\"codecommit:GitPull\", \"codecommit:GetRepository\"],\n      \"Resource\": \"arn:aws:codecommit:ap-northeast-1:ACCOUNT_ID:awsdevlab-webapp\"\n    },\n    {\n      \"Sid\": \"InspectArtifactBucket\",\n      \"Effect\": \"Allow\",\n      \"Action\": &#91;\"s3:GetBucketLocation\", \"s3:ListBucket\"],\n      \"Resource\": \"arn:aws:s3:::ARTIFACT_BUCKET\"\n    },\n    {\n      \"Sid\": \"WriteArtifactObjects\",\n      \"Effect\": \"Allow\",\n      \"Action\": &#91;\"s3:PutObject\", \"s3:GetObject\"],\n      \"Resource\": \"arn:aws:s3:::ARTIFACT_BUCKET\/*\"\n    }\n  ]\n}\n<\/code><\/pre>\n\n\n\n<ol start=\"7\" class=\"wp-block-list\">\n<li>Review the IAM policy summary before saving; confirm the target is the\u00a0<strong>CodeBuild role<\/strong>\u00a0and there are no unresolved placeholder values. If an organization SCP or bucket policy applies an explicit deny, fixing the IAM role alone may not be sufficient.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CB-2:<\/strong>&nbsp;CodeBuild&#8217;s execution role has CodeArtifact read\/token, service bearer token, CodeCommit pull, CloudWatch log permissions, and S3 artifact write permissions.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.4 Inspect the build contract before running<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeCommit \u2192 awsdevlab-webapp \u2192 Code \u2192 main \u2192 buildspec.yml<\/strong>.<\/li>\n\n\n\n<li>Confirm\u00a0<strong>install<\/strong>\u00a0selects Node.js 22;\u00a0<strong>pre_build<\/strong>\u00a0authenticates npm to CodeArtifact and installs dependencies; the test checks source structure;\u00a0<strong>build<\/strong>\u00a0generates the release;\u00a0<strong>artifacts<\/strong>\u00a0packages\u00a0<code>release\/**<\/code>\u00a0with\u00a0<strong>release<\/strong>\u00a0as the base directory.<\/li>\n\n\n\n<li>Open\u00a0<code>package.json<\/code>. Confirm dependency\u00a0<code>lodash<\/code>\u00a0is pinned to version\u00a0<code>4.17.21<\/code>\u00a0and has\u00a0<code>test<\/code>\u00a0and\u00a0<code>build<\/code>\u00a0scripts.<\/li>\n\n\n\n<li>Open\u00a0<code>tools\/build-release.cjs<\/code>. Confirm it renders the template with\u00a0<code>lodash<\/code>, copies\u00a0<code>appspec.yml<\/code>, and includes all four CodeDeploy hooks in the\u00a0<code>release\/scripts\/<\/code>\u00a0directory.<\/li>\n\n\n\n<li>Explain to learners that\u00a0<strong>the YAML\/JavaScript\/shell files are source configuration<\/strong>. The user never manually runs their operations. CodeBuild executes the buildspec internally using the service role; CodeDeploy executes lifecycle hooks later on the deployment host.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Production distinction:<\/strong>&nbsp;For teaching a first-time upstream cache ingest, this lab pins a single dependency and performs a fresh package resolution without a lockfile. For production, create a reviewed registry-consistent lockfile, use a reproducible installation mode, add vulnerability scanning, and remove unnecessary public dependency access.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3.5 Start and inspect the standalone build<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Return to\u00a0<strong>CodeBuild \u2192 Build projects \u2192 awsdevlab-web-build<\/strong>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Start build<\/strong>. For source version, choose the default\/latest\u00a0<code>main<\/code>\u00a0revision; leave optional build overrides unchanged and choose\u00a0<strong>Start build<\/strong>.<\/li>\n\n\n\n<li>Open the new build ID in\u00a0<strong>Build history<\/strong>. Watch each phase:\u00a0<strong>DOWNLOAD_SOURCE<\/strong>,\u00a0<strong>INSTALL<\/strong>,\u00a0<strong>PRE_BUILD<\/strong>,\u00a0<strong>BUILD<\/strong>,\u00a0<strong>UPLOAD_ARTIFACTS<\/strong>,\u00a0<strong>FINALIZING<\/strong>.<\/li>\n\n\n\n<li>On the\u00a0<strong>Build logs<\/strong>\u00a0tab, confirm the CodeArtifact npm login step completed successfully, dependency installation completed, the automated test printed a\u00a0<strong>PASS<\/strong>\u00a0message, and build output states the release directory was created.<\/li>\n\n\n\n<li>Confirm the build&#8217;s top-level\u00a0<strong>Status<\/strong>\u00a0is\u00a0<strong>Succeeded<\/strong>. Record the build ID and source commit ID.<\/li>\n\n\n\n<li>In the build detail\u00a0<strong>Artifacts<\/strong>\u00a0section, follow the\u00a0<strong>Artifacts upload location<\/strong>\u00a0link to S3, or open S3 \u2192 your artifact bucket manually.<\/li>\n\n\n\n<li>Locate\u00a0<code>web-demo-release.zip<\/code>\u00a0(or the S3 object whose exact key appears in the build details). Confirm it is an S3\u00a0<strong>object<\/strong>, not a folder of loose individual files.<\/li>\n\n\n\n<li>From the S3\u00a0<strong>object<\/strong>\u00a0page, choose\u00a0<strong>Download<\/strong>\u00a0in the browser; use your operating system&#8217;s graphical archive viewer to inspect its entries. The expected ZIP hierarchy is:<\/li>\n<\/ol>\n\n\n\n<pre class=\"wp-block-code\"><code>appspec.yml\nindex.html\nscripts\/install_dependencies\nscripts\/start_server\nscripts\/stop_server\nscripts\/validate_server\n<\/code><\/pre>\n\n\n\n<ol start=\"9\" class=\"wp-block-list\">\n<li>Verify that\u00a0<code>appspec.yml<\/code>\u00a0is at the ZIP\u00a0<strong>root<\/strong>, not inside\u00a0<code>release\/<\/code>,\u00a0<code>source\/<\/code>, a GitHub folder or another nested directory. Open the packaged\u00a0<code>index.html<\/code>\u00a0in a local text editor and confirm the visible\u00a0<strong>Release: LAB-V1<\/strong>\u00a0placeholder has been rendered and the build time is a real UTC timestamp.<\/li>\n\n\n\n<li>Return to\u00a0<strong>CodeArtifact \u2192 web-npm \u2192 Packages<\/strong>; verify\u00a0<code>lodash<\/code>\u00a0version\u00a0<code>4.17.21<\/code>\u00a0appears (allow some time and refresh if initially absent).<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CB-3:<\/strong>&nbsp;Build&nbsp;<strong>Succeeded<\/strong>, release ZIP has correct file paths,&nbsp;<code>lodash<\/code>&nbsp;is present in CodeArtifact, and build log contains the source-test PASS. Save the&nbsp;<strong>S3 URI<\/strong>&nbsp;of the ZIP for manual CodeDeploy deployment.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 3 troubleshooting matrix<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Symptom in CodeBuild<\/th><th class=\"has-text-align-left\" data-align=\"left\">Verify in console<\/th><th class=\"has-text-align-left\" data-align=\"left\">Recovery without terminal<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">Source download fails<\/td><td class=\"has-text-align-left\" data-align=\"left\">Build log; CodeCommit repository and branch; role policy<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check same Region, correct branch,&nbsp;<code>codecommit:GitPull<\/code>, repo ARN<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact access denied<\/td><td class=\"has-text-align-left\" data-align=\"left\">PRE_BUILD log and CodeBuild role<\/td><td class=\"has-text-align-left\" data-align=\"left\">Apply all 3 permissions areas from Lab 2, including&nbsp;<code>sts:GetServiceBearerToken<\/code><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">npm package not found \/ 404<\/td><td class=\"has-text-align-left\" data-align=\"left\">Domain, downstream upstream flow<\/td><td class=\"has-text-align-left\" data-align=\"left\">Connect&nbsp;<code>web-npm<\/code>&nbsp;to&nbsp;<code>npm-store<\/code>&nbsp;and npmjs; retry build<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\"><code>buildspec.yml<\/code>&nbsp;not found<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit tree<\/td><td class=\"has-text-align-left\" data-align=\"left\">Create at repository root, correct spelling (not&nbsp;<code>buildspec.yaml<\/code>)<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Node runtime unsupported<\/td><td class=\"has-text-align-left\" data-align=\"left\">Build environment image<\/td><td class=\"has-text-align-left\" data-align=\"left\">Use AL2023 x86_64 standard 6.0 and Node.js 22<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Test failed<\/td><td class=\"has-text-align-left\" data-align=\"left\">Detailed log; tests\/ path<\/td><td class=\"has-text-align-left\" data-align=\"left\">Restore exact sample file paths and template markers<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Artifact upload failed<\/td><td class=\"has-text-align-left\" data-align=\"left\">UPLOAD_ARTIFACTS and IAM\/S3<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check S3 PutObject, actual bucket ARN, ZIP packaging and encryption<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">ZIP contains nested&nbsp;<code>release\/<\/code>&nbsp;directory<\/td><td class=\"has-text-align-left\" data-align=\"left\">Buildspec&nbsp;<code>base-directory<\/code><\/td><td class=\"has-text-align-left\" data-align=\"left\">Set&nbsp;<code>base-directory: release<\/code>, re-run, inspect ZIP again<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 4 \u2014 AWS CodeDeploy: deploy the build artifact to Amazon EC2<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Launch a single Amazon Linux 2023 target, install the CodeDeploy agent entirely through the CodeDeploy\/Systems Manager consoles, manually deploy the&nbsp;<em>tested ZIP<\/em>&nbsp;from Lab 3, inspect lifecycle events, and validate the live HTTP website.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Architecture note.<\/strong>&nbsp;This is intentionally a&nbsp;<strong>single-instance, in-place deployment<\/strong>&nbsp;with no load balancer. It teaches CodeDeploy lifecycle events. It is&nbsp;<strong>not<\/strong>&nbsp;a highly available production deployment. The web server is installed by lifecycle hooks included in the build artifact; the learner does not manually run installation commands.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.1 Create the EC2 instance profile (IAM role)<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>IAM \u2192 Roles \u2192 Create role<\/strong>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Trusted entity type<\/strong>, choose\u00a0<strong>AWS service<\/strong>;\u00a0<strong>Use case<\/strong>\u00a0\u2192\u00a0<strong>EC2<\/strong>; choose\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li>In\u00a0<strong>Permissions<\/strong>, attach\u00a0<strong>AmazonSSMManagedInstanceCore<\/strong>\u00a0and\u00a0<strong>AmazonEC2RoleforAWSCodeDeploy<\/strong>. The latter grants broad S3 read permissions and is convenient for this isolated course;\u00a0<strong>do not use its broad S3 resource scope unreviewed in production<\/strong>. For production, scope S3 reads to approved artifact paths and any required AWS-owned service buckets. [AWS10]<\/li>\n\n\n\n<li>Choose\u00a0<strong>Next<\/strong>; enter\u00a0<strong>Role name<\/strong>\u00a0<code>awsdevlab-ec2-role<\/code>; optionally add tag\u00a0<code>Course=AWSDevLab<\/code>; choose\u00a0<strong>Create role<\/strong>.<\/li>\n\n\n\n<li>Open the role and verify its\u00a0<strong>Trust relationships<\/strong>\u00a0shows the EC2 service principal, and its\u00a0<strong>Permissions<\/strong>\u00a0tab contains both managed policies.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-1:<\/strong>&nbsp;An EC2-trusted instance role exists, with SSM access and the CodeDeploy agent&#8217;s artifact access.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.2 Launch the EC2 target using the EC2 console<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>EC2 \u2192 Instances \u2192 Launch instances<\/strong>.<\/li>\n\n\n\n<li>Set\u00a0<strong>Name<\/strong>\u00a0to\u00a0<code>awsdevlab-web-ec2<\/code>. This creates\u00a0<strong>Name=awsdevlab-web-ec2<\/strong>, which the deployment group will use to select the target.<\/li>\n\n\n\n<li>Under\u00a0<strong>Application and OS Images (AMI)<\/strong>\u00a0choose\u00a0<strong>Amazon Linux<\/strong>\u00a0and explicitly select\u00a0<strong>Amazon Linux 2023 (AL2023)<\/strong>, x86_64. Do not choose an old Amazon Linux 2 image only because an older walkthrough shows it.<\/li>\n\n\n\n<li>Under\u00a0<strong>Instance type<\/strong>, choose a small, supported general-purpose type suitable for the course, such as\u00a0<code>t3.micro<\/code>\u00a0if available and permitted. Verify pricing in your account; do\u00a0<strong>not<\/strong>\u00a0assume free-tier eligibility.<\/li>\n\n\n\n<li>Under\u00a0<strong>Key pair (login)<\/strong>\u00a0choose\u00a0<strong>Proceed without a key pair<\/strong>\u00a0if allowed. This lab uses no SSH. If your organization requires an approved key pair, choose it, but do not open TCP\/22 merely for this tutorial.<\/li>\n\n\n\n<li>Expand\u00a0<strong>Network settings \u2192 Edit<\/strong>. Select the instructor-approved\u00a0<strong>VPC<\/strong>\u00a0and\u00a0<strong>public subnet<\/strong>. Choose\u00a0<strong>Auto-assign public IP: Enable<\/strong>. Ensure the subnet&#8217;s route table provides an Internet Gateway path for internet-facing test traffic.<\/li>\n\n\n\n<li>Create a new security group\u00a0<code>awsdevlab-http-sg<\/code>\u00a0with\u00a0<strong>Inbound HTTP TCP\/80 \u2192 Source type: My IP<\/strong>.\u00a0<strong>Remove SSH TCP\/22<\/strong>\u00a0if the wizard adds it automatically. Leave the normal outbound rule allowing required service access. Record the IPv4 CIDR displayed for My IP; this may need to be updated if your public IP changes.<\/li>\n\n\n\n<li>Under\u00a0<strong>Configure storage<\/strong>, keep the default encrypted\/root EBS volume size offered by the selected AMI (small is sufficient). Check\u00a0<strong>Delete on termination<\/strong>\u00a0is enabled for the root volume.<\/li>\n\n\n\n<li>Expand\u00a0<strong>Advanced details<\/strong>. Under\u00a0<strong>IAM instance profile<\/strong>, select\u00a0<code>awsdevlab-ec2-role<\/code>.\u00a0<strong>No user data is required<\/strong>; do not paste bootstrapping commands.<\/li>\n\n\n\n<li>Under\u00a0<strong>Summary<\/strong>, verify\u00a0<strong>Number of instances = 1<\/strong>. Choose\u00a0<strong>Launch instance<\/strong>.<\/li>\n\n\n\n<li>In\u00a0<strong>EC2 \u2192 Instances<\/strong>, select the new instance and wait for\u00a0<strong>Instance state: Running<\/strong>\u00a0and\u00a0<strong>Status checks: 2\/2 checks passed<\/strong>. Record instance ID, public IPv4, public DNS and the security group.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-2:<\/strong>&nbsp;One AL2023 EC2 instance is running in a public subnet with Name tag&nbsp;<code>awsdevlab-web-ec2<\/code>, assigned instance role and HTTP ingress only from your IP.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.3 Confirm SSM sees the instance; do not install agents from a shell<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>AWS Systems Manager<\/strong>\u00a0in\u00a0<code>ap-northeast-1<\/code>. Under\u00a0<strong>Node Management \/ Fleet Manager \u2192 Managed nodes<\/strong>, look for the EC2 instance ID. Console navigation grouping may vary; search\u00a0<strong>Managed nodes<\/strong>\u00a0inside Systems Manager if necessary.<\/li>\n\n\n\n<li>Confirm the node shows a healthy\/online SSM agent connection. AL2023 Amazon-provided AMIs typically include SSM Agent; registration requires the EC2 IAM role and outbound connectivity.<\/li>\n\n\n\n<li>If not online, revisit the EC2 instance profile, VPC internet route, network ACL, outbound security group and SSM prerequisites. Do not continue until the instance is manageable. [AWS11]<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">4.4 Create the CodeDeploy service role<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>IAM \u2192 Roles \u2192 Create role<\/strong>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>AWS service \u2192 CodeDeploy \u2192 CodeDeploy<\/strong>\u00a0as the use case and\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li>Confirm the console proposes or attaches\u00a0<strong>AWSCodeDeployRole<\/strong>\u00a0managed policy for EC2\/On-Premises deployments.<\/li>\n\n\n\n<li>Set role name\u00a0<code>awsdevlab-codedeploy-role<\/code>; choose\u00a0<strong>Create role<\/strong>.<\/li>\n\n\n\n<li>Open the role and verify its trust principal is\u00a0<code>codedeploy.amazonaws.com<\/code>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-3:<\/strong>&nbsp;The CodeDeploy service role exists and is distinct from the EC2 instance role and the CodeBuild role.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.5 Create the CodeDeploy application and deployment group<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeDeploy \u2192 Deploy \u2192 Applications \u2192 Create application<\/strong>.<\/li>\n\n\n\n<li><strong>Application name:<\/strong>\u00a0<code>awsdevlab-web-app<\/code>.\u00a0<strong>Compute platform:<\/strong>\u00a0<strong>EC2\/On-premises<\/strong>. Choose\u00a0<strong>Create application<\/strong>.<\/li>\n\n\n\n<li>On the application page select\u00a0<strong>Create deployment group<\/strong>.<\/li>\n\n\n\n<li><strong>Deployment group name:<\/strong>\u00a0<code>awsdevlab-web-ec2<\/code>.\u00a0<strong>Service role:<\/strong>\u00a0choose the ARN of\u00a0<code>awsdevlab-codedeploy-role<\/code>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Deployment type<\/strong>, choose\u00a0<strong>In-place<\/strong>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Environment configuration<\/strong>, choose\u00a0<strong>Amazon EC2 instances<\/strong>. Set tag selector\u00a0<strong>Key = Name<\/strong>,\u00a0<strong>Value = awsdevlab-web-ec2<\/strong>. If the console shows a matched-instance count, confirm one target is selected.<\/li>\n\n\n\n<li>Under\u00a0<strong>Agent configuration with AWS Systems Manager<\/strong>, choose\u00a0<strong>Now and schedule updates<\/strong>. This uses Systems Manager to install\/configure the CodeDeploy agent on selected instances;\u00a0<strong>this field is the key to our no-terminal requirement<\/strong>. If this option is absent, see the alternative in Step 4.6. [AWS12]<\/li>\n\n\n\n<li><strong>Deployment configuration:<\/strong>\u00a0<code>CodeDeployDefault.OneAtATime<\/code>.\u00a0<strong>Load balancer:<\/strong>\u00a0disable\u00a0<strong>Enable load balancing<\/strong>\u00a0for this one-instance course.<\/li>\n\n\n\n<li>Review fields; choose\u00a0<strong>Create deployment group<\/strong>.<\/li>\n\n\n\n<li>In the deployment group&#8217;s details, verify\u00a0<strong>in-place<\/strong>, EC2 target tag, CodeDeploy service role and agent management settings. Allow agent installation to finish before deploying.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-4:<\/strong>&nbsp;Application and deployment group exist; the correct EC2 target is registered; CodeDeploy agent installation is being managed by SSM.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4.6 Fallback: install CodeDeploy agent with Systems Manager&#8217;s visual package workflow<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use this&nbsp;<strong>only if<\/strong>&nbsp;the deployment group&#8217;s agent-management UI is absent or reports an install failure. It is still browser-only.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>Systems Manager \u2192 Node Management \u2192 Distributor<\/strong>\u00a0(or the Systems Manager package-management feature; console groupings change). Choose\u00a0<strong>Third party \/ Amazon-owned packages<\/strong>\u00a0or the repository of available packages.<\/li>\n\n\n\n<li>Search for the AWS package\u00a0<strong><code>AWSCodeDeployAgentV2<\/code><\/strong>, the AWS-documented package for CodeDeploy agent version 2.0 and later. Select the package and\u00a0<strong>Install<\/strong>\u00a0\/\u00a0<strong>Install package<\/strong>.<\/li>\n\n\n\n<li>In the setup choose\u00a0<strong>Installation type: Install<\/strong>\u00a0and target the\u00a0<strong>managed EC2 instance ID<\/strong>\u00a0from 4.2. For recurring updates, choose the update schedule your instructor approves; a one-off install is enough for a disposable lab.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Run \/ Create association<\/strong>\u00a0as the UI offers. View the\u00a0<strong>Command\/Association execution status<\/strong>\u00a0until\u00a0<strong>Success<\/strong>. Do not enter custom shell scripts or use the terminal. [AWS13]<\/li>\n\n\n\n<li>Return to the CodeDeploy deployment group and verify agent readiness. If the package screen differs materially, follow the AWS CodeDeploy agent installation via Systems Manager documentation cited in the References section.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">4.7 Deploy the S3 build output manually<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>S3 \u2192 the standalone artifacts bucket \u2192\u00a0<code>web-demo-release.zip<\/code><\/strong>. From the object detail page, choose\u00a0<strong>Copy S3 URI<\/strong>\u00a0(or copy the actual S3 object path). The value must point to the exact ZIP object, not the bucket, prefix or console webpage URL.<\/li>\n\n\n\n<li>Return to\u00a0<strong>CodeDeploy \u2192 Applications \u2192 awsdevlab-web-app \u2192 Deployments \u2192 Create deployment<\/strong>.<\/li>\n\n\n\n<li><strong>Deployment group:<\/strong>\u00a0<code>awsdevlab-web-ec2<\/code>.<\/li>\n\n\n\n<li>Under\u00a0<strong>Repository \/ Revision type<\/strong>, select\u00a0<strong>My application is stored in Amazon S3<\/strong>.<\/li>\n\n\n\n<li><strong>Revision location:<\/strong>\u00a0paste the full S3 object URI, such as\u00a0<code>s3:\/\/awsdevlab-artifacts-ACCOUNTID-apne1\/web-demo-release.zip<\/code>\u00a0(replace with real bucket\/key).<\/li>\n\n\n\n<li><strong>Revision file type:<\/strong>\u00a0<strong>.zip<\/strong>. Enter description\u00a0<code>Manual deployment of tested CodeBuild release<\/code>.<\/li>\n\n\n\n<li>Leave the configured deployment group strategy, deployment configuration and any optional rollback settings at their course defaults. If auto rollback on failure is available, enable it for safety, but understand a first-time deployment has no last-good revision to roll back to.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Create deployment<\/strong>. Record its deployment ID. [AWS14]<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">4.8 Validate lifecycle execution and the public website<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>On the\u00a0<strong>CodeDeploy deployment detail<\/strong>\u00a0page, inspect\u00a0<strong>Deployment status<\/strong>\u00a0until\u00a0<strong>Succeeded<\/strong>.<\/li>\n\n\n\n<li>Expand\u00a0<strong>Deployment lifecycle events \/ Instance details<\/strong>. Confirm the expected events were completed:\u00a0<strong>BeforeInstall \u2192 Install \u2192 ApplicationStart \u2192 ValidateService<\/strong>.\u00a0<strong>ApplicationStop<\/strong>\u00a0is normally skipped on the\u00a0<strong>first<\/strong>\u00a0deployment because there is no previous successfully deployed revision from which to load a stop hook.<\/li>\n\n\n\n<li>If an event is red\/failed, select its error\/details link or related\u00a0<strong>View logs<\/strong>\u00a0link in the deployment pane. The instance&#8217;s agent logs are not required for the normal success path; the UI&#8217;s failure details should be your first stop.<\/li>\n\n\n\n<li>From\u00a0<strong>EC2 \u2192 Instances \u2192 awsdevlab-web-ec2<\/strong>, copy its\u00a0<strong>Public IPv4 address<\/strong>\u00a0or\u00a0<strong>Public IPv4 DNS<\/strong>. In a new browser tab, open the\u00a0<code>http:\/\/<\/code>\u00a0URL (not\u00a0<code>https:\/\/<\/code>, because the course does not configure TLS).<\/li>\n\n\n\n<li>Confirm the page displays\u00a0<strong>AWS Developer Services Lab<\/strong>, the merged banner from Lab 1,\u00a0<strong>Release: LAB-V1<\/strong>, and a UTC build time. Take a screenshot showing the browser URL and page content.<\/li>\n\n\n\n<li>If the browser times out but CodeDeploy succeeded, check the instance&#8217;s public IP, inbound\u00a0<strong>HTTP\/80<\/strong>\u00a0rule with your current\u00a0<strong>My IP<\/strong>, public route table, and local network restrictions. If the browser returns HTTP error 403\/404, inspect Apache lifecycle hooks or the ZIP&#8217;s path structure.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CD-5:<\/strong>&nbsp;CodeDeploy deployment status&nbsp;<strong>Succeeded<\/strong>, ValidateService succeeded and a real browser request to the instance&#8217;s public IP returns the released page.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 4 troubleshooting matrix<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Symptom<\/th><th class=\"has-text-align-left\" data-align=\"left\">Likely issue<\/th><th class=\"has-text-align-left\" data-align=\"left\">Browser-based recovery<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">No EC2 targets matched<\/td><td class=\"has-text-align-left\" data-align=\"left\">Tag mismatch or wrong Region<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check EC2 Name tag, CodeDeploy group tag Key\/Value and account\/Region<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Deployment never begins \/ skipped target<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy agent not installed \/ not healthy<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check SSM Managed nodes and agent association; use Distributor V2 workflow<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Failed BeforeInstall<\/td><td class=\"has-text-align-left\" data-align=\"left\">Apache package install error \/ outbound internet<\/td><td class=\"has-text-align-left\" data-align=\"left\">Open lifecycle failure, verify public subnet internet and EC2 outbound access; retry after network fix<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Failed Install (missing AppSpec)<\/td><td class=\"has-text-align-left\" data-align=\"left\">ZIP root structure wrong<\/td><td class=\"has-text-align-left\" data-align=\"left\">Open standalone ZIP locally; AppSpec must be at root, rebuild from CodeBuild<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AccessDenied fetching revision<\/td><td class=\"has-text-align-left\" data-align=\"left\">IAM role \/ S3 object \/ KMS<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check EC2 instance profile&nbsp;<code>s3:GetObject<\/code>, exact S3 key and any KMS decrypt grant<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Failed ApplicationStart<\/td><td class=\"has-text-align-left\" data-align=\"left\">Web server not running<\/td><td class=\"has-text-align-left\" data-align=\"left\">Open lifecycle error, confirm AL2023, install hook and scripts in revision<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Failed ValidateService<\/td><td class=\"has-text-align-left\" data-align=\"left\">HTTP endpoint\/content verification failed<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check the rendered&nbsp;<code>index.html<\/code>, Apache service startup and root path<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy Succeeded but public page inaccessible<\/td><td class=\"has-text-align-left\" data-align=\"left\">HTTP\/80 inbound \/ public IP \/ VPC route<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check My IP CIDR, subnet\/IGW, instance public IPv4; use HTTP URL<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Lab 5 \u2014 AWS CodePipeline: automate source \u2192 build \u2192 deploy<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Objective.<\/strong>&nbsp;Transform the standalone CodeBuild project into a pipeline-compatible action, create a V2 CodePipeline containing CodeCommit source, CodeBuild build and CodeDeploy deployment, then demonstrate an automatic rebuild and redeployment from an in-browser CodeCommit edit.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Two essential integration rules:<\/strong>&nbsp;(1) The existing CodeBuild project must have&nbsp;<strong>Source provider = AWS CodePipeline<\/strong>&nbsp;and&nbsp;<strong>Artifacts type = AWS CodePipeline<\/strong>&nbsp;before the pipeline executes it. (2) The&nbsp;<strong>CodeDeploy action input artifact must be the CodeBuild output<\/strong>&nbsp;(often&nbsp;<code>BuildArtifact<\/code>), not the CodeCommit raw source output (<code>SourceArtifact<\/code>). Missing either rule is a common source of misleading pipelines that cannot deploy the rendered HTML. [AWS15][AWS16]<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.1 Reconfigure the existing build project for CodePipeline<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeBuild \u2192 Build projects \u2192 awsdevlab-web-build<\/strong>.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Edit \u2192 Source<\/strong>. Change\u00a0<strong>Source provider<\/strong>\u00a0from\u00a0<strong>AWS CodeCommit<\/strong>\u00a0to\u00a0<strong>AWS CodePipeline<\/strong>. The pipeline will now supply source ZIPs to this project. Save\u00a0<strong>Update source<\/strong>\u00a0\/\u00a0<strong>Update configuration<\/strong>, depending on the screen.<\/li>\n\n\n\n<li>Choose\u00a0<strong>Edit \u2192 Artifacts<\/strong>. Change\u00a0<strong>Type<\/strong>\u00a0from\u00a0<strong>Amazon S3<\/strong>\u00a0to\u00a0<strong>AWS CodePipeline<\/strong>; save. This does\u00a0<strong>not<\/strong>\u00a0delete the standalone ZIP created earlier in S3.<\/li>\n\n\n\n<li>Verify\u00a0<strong>Environment<\/strong>\u00a0still uses AL2023 x86_64 standard 6.0,\u00a0<strong>Service role<\/strong>\u00a0is the same CodeBuild role (with CodeArtifact read access), and\u00a0<strong>Buildspec<\/strong>\u00a0still uses root\u00a0<code>buildspec.yml<\/code>.<\/li>\n\n\n\n<li>On project details verify\u00a0<strong>Source: AWS CodePipeline<\/strong>\u00a0and\u00a0<strong>Artifacts: AWS CodePipeline<\/strong>. Do\u00a0<strong>not<\/strong>\u00a0use\u00a0<strong>Start build<\/strong>\u00a0directly for another standalone test; pipeline now supplies the input source and manages artifacts.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CP-1:<\/strong>&nbsp;The existing, already-tested CodeBuild project is configured for CodePipeline source and artifact exchange.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.2 Create the V2 custom pipeline in the AWS console<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodePipeline \u2192 Pipelines \u2192 Create pipeline<\/strong>.<\/li>\n\n\n\n<li>On\u00a0<strong>Choose creation option<\/strong>, select\u00a0<strong>Build custom pipeline<\/strong>, then\u00a0<strong>Next<\/strong>. Avoid a prebuilt template that changes the pipeline&#8217;s service architecture.<\/li>\n\n\n\n<li>On\u00a0<strong>Pipeline settings<\/strong>, set\u00a0<strong>Pipeline name<\/strong>\u00a0<code>awsdevlab-web-pipeline<\/code>.<\/li>\n\n\n\n<li>For\u00a0<strong>Pipeline type<\/strong>, use\u00a0<strong>V2<\/strong>\u00a0(the current console experience). Select\u00a0<strong>New service role<\/strong>\u00a0and allow AWS to create the CodePipeline service role. Record its role ARN. Keep the default same-Region S3 pipeline artifact store unless organizational policy requires a preexisting protected artifact bucket. Choose\u00a0<strong>Next<\/strong>. [AWS02]<\/li>\n\n\n\n<li><strong>Add source stage<\/strong>:\u00a0<strong>Source provider = AWS CodeCommit<\/strong>.\u00a0<strong>Repository name = awsdevlab-webapp<\/strong>.\u00a0<strong>Branch name = main<\/strong>. For\u00a0<strong>Output artifact format<\/strong>, choose\u00a0<strong>CodePipeline default<\/strong>,\u00a0<strong>not Full clone<\/strong>, because the deployment later needs buildable ZIP contents. Enable\u00a0<strong>Start the pipeline on source code change \/ EventBridge change detection<\/strong>. Confirm the source output artifact name, normally\u00a0<strong>SourceArtifact<\/strong>. Choose\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li><strong>Add build stage<\/strong>:\u00a0<strong>Build provider = AWS CodeBuild<\/strong>. Select\u00a0<strong>Existing project<\/strong>, then choose\u00a0<code>awsdevlab-web-build<\/code>. Keep build mode\u00a0<strong>Single build<\/strong>\u00a0if offered, not batch build. Confirm the build receives\u00a0<strong>SourceArtifact<\/strong>\u00a0and will produce a new output artifact, normally\u00a0<strong>BuildArtifact<\/strong>. Choose\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li><strong>Add test stage<\/strong>, if offered: choose\u00a0<strong>Skip test stage<\/strong>, since CodeBuild already runs the automated test in its PRE_BUILD phase. For production, consider a distinct dedicated test stage.<\/li>\n\n\n\n<li><strong>Add deploy stage<\/strong>:\u00a0<strong>Deploy provider = AWS CodeDeploy<\/strong>.\u00a0<strong>Application name = awsdevlab-web-app<\/strong>.\u00a0<strong>Deployment group = awsdevlab-web-ec2<\/strong>. If there is an\u00a0<strong>Input artifacts<\/strong>\u00a0selector, explicitly choose the\u00a0<strong>CodeBuild output<\/strong>\u00a0(normally\u00a0<strong>BuildArtifact<\/strong>). Choose\u00a0<strong>Next<\/strong>.<\/li>\n\n\n\n<li>On the\u00a0<strong>Review<\/strong>\u00a0page check source repository and branch, build project name, deployment group, artifact wiring and V2 type. Choose\u00a0<strong>Create pipeline<\/strong>.<\/li>\n\n\n\n<li>The pipeline may start an initial execution immediately. In\u00a0<strong>Pipeline details \/ Edit<\/strong>, inspect the\u00a0<strong>Deploy<\/strong>\u00a0action. If it selected\u00a0<strong>SourceArtifact<\/strong>\u00a0or a different input, choose\u00a0<strong>Edit action<\/strong>, set\u00a0<strong>Input artifact<\/strong>\u00a0to the CodeBuild\u00a0<strong>BuildArtifact<\/strong>, and\u00a0<strong>Save<\/strong>\u00a0the pipeline change. Trigger a fresh execution using\u00a0<strong>Release change<\/strong>\u00a0after correcting the input; the first run may have failed if it used an incorrect artifact.<\/li>\n\n\n\n<li>Inspect the pipeline&#8217;s automatically created artifact bucket from\u00a0<strong>Pipeline settings \/ Artifact store<\/strong>\u00a0and record its name. These artifacts are managed separately from the standalone Lab 3 S3 bucket.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CP-2:<\/strong>&nbsp;The pipeline visually shows&nbsp;<strong>Source (CodeCommit) \u2192 Build (CodeBuild) \u2192 Deploy (CodeDeploy)<\/strong>. Source output flows to Build; Build output flows to Deploy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.3 Observe first complete pipeline execution<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>On the pipeline\u00a0<strong>Executions<\/strong>\u00a0or visualization page, choose\u00a0<strong>Release change<\/strong>\u00a0if no execution is in progress; confirm the action when prompted.<\/li>\n\n\n\n<li>Watch\u00a0<strong>Source<\/strong>\u00a0become\u00a0<strong>Succeeded<\/strong>. Select its execution details and verify the\u00a0<strong>main<\/strong>\u00a0branch and latest CodeCommit commit ID.<\/li>\n\n\n\n<li>Watch\u00a0<strong>Build<\/strong>. Follow\u00a0<strong>View details<\/strong>\u00a0to CodeBuild and confirm tests, CodeArtifact npm authentication and\u00a0<code>release\/<\/code>\u00a0packaging all succeed.<\/li>\n\n\n\n<li>Watch\u00a0<strong>Deploy<\/strong>. Follow\u00a0<strong>View details<\/strong>\u00a0to CodeDeploy and confirm the correct application\/deployment group and all lifecycle events succeed.<\/li>\n\n\n\n<li>Once the full pipeline is\u00a0<strong>Succeeded<\/strong>, refresh the browser tab pointing at the EC2 public IP. Confirm the page remains accessible and the\u00a0<strong>Build time (UTC)<\/strong>\u00a0reflects the new pipeline build.<\/li>\n\n\n\n<li>Capture the pipeline execution ID, CodeCommit commit ID, CodeBuild build ID and CodeDeploy deployment ID. These four linked IDs form the traceable evidence chain for the release.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CP-3:<\/strong>&nbsp;A green three-stage pipeline deploys a built ZIP produced by CodeBuild and the HTTP page is healthy.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.4 Demonstrate a true automatically triggered change<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<strong>CodeCommit \u2192 awsdevlab-webapp \u2192 Code \u2192 main \u2192 index.html<\/strong>.<\/li>\n\n\n\n<li>Select\u00a0<strong>Edit<\/strong>. Change the visible headline\u00a0<code>AWS Developer Services Lab<\/code>\u00a0(inside the\u00a0<code>&lt;h1><\/code>\u00a0element only) to\u00a0<strong>AWS Developer Services Lab \u2014 Version 2<\/strong>. Keep the separate\u00a0<code>&lt;title><\/code>\u00a0text, the verification marker strings, the\u00a0<code>releaseLabel<\/code>\u00a0template placeholder and the\u00a0<code>lab-check<\/code>\u00a0element untouched.<\/li>\n\n\n\n<li>The\u00a0<strong>source-test checker<\/strong>\u00a0intentionally verifies the phrase\u00a0<strong>AWS Developer Services Lab<\/strong>, which remains a substring of the updated heading, so the test will continue to pass.<\/li>\n\n\n\n<li>Enter commit message\u00a0<code>Release version 2 from CodeCommit console<\/code>\u00a0and choose\u00a0<strong>Commit changes<\/strong>\u00a0directly on\u00a0<code>main<\/code>\u00a0for the automatic-trigger demonstration. (In a governed production workflow, use a pull request with approvals.)<\/li>\n\n\n\n<li>Immediately return to\u00a0<strong>CodePipeline \u2192 awsdevlab-web-pipeline<\/strong>. Observe a\u00a0<strong>new execution<\/strong>\u00a0created by the CodeCommit change. It can take a short time for the event to arrive.<\/li>\n\n\n\n<li>Verify Source, Build, Deploy each become\u00a0<strong>Succeeded<\/strong>. In\u00a0<strong>Build logs<\/strong>, look for PASS and the generated release. In\u00a0<strong>CodeDeploy<\/strong>, confirm ValidateService succeeded.<\/li>\n\n\n\n<li>Refresh the public page. Confirm the new heading\u00a0<strong>AWS Developer Services Lab \u2014 Version 2<\/strong>\u00a0and a changed UTC build time.<\/li>\n\n\n\n<li>Optionally open\u00a0<strong>CodeCommit \u2192 Commits<\/strong>,\u00a0<strong>CodePipeline \u2192 Executions<\/strong>,\u00a0<strong>CodeBuild \u2192 Build history<\/strong>, and\u00a0<strong>CodeDeploy \u2192 Deployments<\/strong>\u00a0side by side and connect the commit, pipeline, build and deployment IDs.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Checkpoint CP-4:<\/strong>&nbsp;A single CodeCommit browser edit automatically results in a tested, packaged and successfully deployed Version 2 website\u2014without manually starting a build or deployment.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5.5 Optional: introduce a controlled failure and practice recovery<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open\u00a0<code>index.html<\/code>\u00a0through CodeCommit\u00a0<strong>Edit<\/strong>\u00a0and temporarily remove the HTML element with\u00a0<code>id=\"lab-check\"<\/code>. Commit this change on a\u00a0<strong>separate temporary branch<\/strong>\u00a0or on\u00a0<code>main<\/code>\u00a0only if the class permits deliberately failing the training pipeline.<\/li>\n\n\n\n<li>Observe the subsequent Build stage fail its source test in CodeBuild. Confirm CodePipeline\u00a0<strong>does not run a new successful Deploy action<\/strong>\u00a0for that failed source revision; the old website should remain reachable.<\/li>\n\n\n\n<li>Restore the\u00a0<code>id=\"lab-check\"<\/code>\u00a0element using the CodeCommit browser editor and commit the corrected file. Re-run (or allow the trigger to start) the pipeline.<\/li>\n\n\n\n<li>Verify the next pipeline execution becomes\u00a0<strong>Succeeded<\/strong>\u00a0and the website is healthy. Explain why build-time tests prevent a defective revision from reaching the deployment stage.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Safety note:<\/strong>&nbsp;A pipeline source-stage rule, branch permission or manual approval may prevent an automatic trigger. If so, capture that governance behavior as part of the exercise rather than disabling organizational controls without permission.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Lab 5 troubleshooting matrix<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Symptom<\/th><th class=\"has-text-align-left\" data-align=\"left\">Inspect<\/th><th class=\"has-text-align-left\" data-align=\"left\">Corrective action in console<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline build says wrong source type<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild Source settings<\/td><td class=\"has-text-align-left\" data-align=\"left\">Change CodeBuild Source to AWS CodePipeline<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild artifact type mismatch<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild Artifacts settings<\/td><td class=\"has-text-align-left\" data-align=\"left\">Change Type to AWS CodePipeline<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Deploy step says missing AppSpec or raw template shown<\/td><td class=\"has-text-align-left\" data-align=\"left\">Deploy action Input artifacts<\/td><td class=\"has-text-align-left\" data-align=\"left\">Select&nbsp;<strong>BuildArtifact<\/strong>, not SourceArtifact<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">No auto-trigger after CodeCommit commit<\/td><td class=\"has-text-align-left\" data-align=\"left\">Source stage change detection<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check&nbsp;<code>main<\/code>&nbsp;branch, EventBridge rule and pipeline trigger settings; release manually to isolate fault<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline cannot use CodeBuild<\/td><td class=\"has-text-align-left\" data-align=\"left\">Pipeline service role permissions<\/td><td class=\"has-text-align-left\" data-align=\"left\">Confirm&nbsp;<code>codebuild:StartBuild<\/code>,&nbsp;<code>codebuild:BatchGetBuilds<\/code>, build project ARN<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy cannot read pipeline artifact<\/td><td class=\"has-text-align-left\" data-align=\"left\">EC2 instance role \/ artifact bucket and KMS policy<\/td><td class=\"has-text-align-left\" data-align=\"left\">Check managed S3 GetObject and any extra KMS decrypt rights<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Only first pipeline works<\/td><td class=\"has-text-align-left\" data-align=\"left\">Region\/branch, token refresh, artifact names<\/td><td class=\"has-text-align-left\" data-align=\"left\">Trace each stage&#8217;s current input\/output and cloud log references<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Old website after green run<\/td><td class=\"has-text-align-left\" data-align=\"left\">Browser cache, wrong public IP, artifact input<\/td><td class=\"has-text-align-left\" data-align=\"left\">Hard-refresh browser, inspect build timestamp, deploy action artifact and EC2 target tag<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Instructor verification and assessment<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Deliverable checklist<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Gate<\/th><th class=\"has-text-align-left\" data-align=\"left\">Must-have evidence<\/th><th class=\"has-text-align-left\" data-align=\"left\">Pass condition<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">CC-1\/2<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeCommit repo tree; PR diff; merged status<\/td><td class=\"has-text-align-left\" data-align=\"left\">Correct root\/nested paths, main branch, completed review<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CA-1\/2<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact domain, npm upstream, cached lodash<\/td><td class=\"has-text-align-left\" data-align=\"left\"><code>web-npm<\/code>&nbsp;and&nbsp;<code>npm-store<\/code>;&nbsp;<code>lodash<\/code>&nbsp;4.17.21 after successful build<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CB-1\/3<\/td><td class=\"has-text-align-left\" data-align=\"left\">Private artifact bucket; CodeBuild status\/log; release ZIP<\/td><td class=\"has-text-align-left\" data-align=\"left\">Succeeded, tests PASS, AppSpec at ZIP root, readable release content<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CD-1\/5<\/td><td class=\"has-text-align-left\" data-align=\"left\">EC2 role\/instance\/SSM; deployment detail; web page<\/td><td class=\"has-text-align-left\" data-align=\"left\">Managed EC2 target, CodeDeploy Succeeded, ValidateService passed, HTTP page loads<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">CP-1\/4<\/td><td class=\"has-text-align-left\" data-align=\"left\">Pipeline wiring; second execution; Version 2 page<\/td><td class=\"has-text-align-left\" data-align=\"left\">V2 pipeline, BuildArtifact to Deploy, automatic trigger, page changes<\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">Clean-up<\/td><td class=\"has-text-align-left\" data-align=\"left\">Empty artifact buckets; deleted EC2 and lab resources<\/td><td class=\"has-text-align-left\" data-align=\"left\">No running instances\/pipelines or remaining paid lab artifacts<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Suggested assessment (100 points):<\/strong>&nbsp;CodeCommit 15; CodeArtifact 15; CodeBuild 20; CodeDeploy 25; CodePipeline 20; safe clean-up 5. Award points only for screenshots\/IDs or in-console evidence; do not award on the basis of claimed success alone.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Security and production-hardening discussion<\/h2>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>IAM:<\/strong>\u00a0The provided CodeBuild CodeArtifact policy is scoped to one repository\/domain. The beginner-friendly EC2\u00a0<code>AmazonEC2RoleforAWSCodeDeploy<\/code>\u00a0managed policy is broad (<code>s3:*<\/code>\u00a0read-related actions on all resources); consider a custom scope for production, including service-specific buckets, and any required customer-managed KMS permissions.<\/li>\n\n\n\n<li><strong>Package supply chain:<\/strong>\u00a0CodeArtifact is an upstream\/cache boundary, not malware scanning by itself. Pin versions, adopt lockfiles, scan dependency vulnerabilities, govern upstream repositories and consider repository package-origin controls.<\/li>\n\n\n\n<li><strong>Deployment:<\/strong>\u00a0A single EC2 instance and HTTP from My IP are instructional. For production use private instances, an ALB, TLS, launch templates or images with the CodeDeploy agent, Auto Scaling or blue\/green, alarms and rollback.<\/li>\n\n\n\n<li><strong>Build security:<\/strong>\u00a0Keep CodeBuild privileged mode OFF when not needed; avoid plaintext secrets and broad service roles; log and monitor builds, consider VPC endpoints and private package access.<\/li>\n\n\n\n<li><strong>Release governance:<\/strong>\u00a0Prefer PR reviews, protected main branch, manual approval for production stages, deployment windows, change records and automated failure alarms.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">No-terminal cleanup runbook \u2014 perform in this order<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Why the order matters:<\/strong>&nbsp;Pipelines may retrigger from new source commits, deployments may create Systems Manager associations, and S3 buckets may contain automatically generated artifacts. Removing high-level orchestration first reduces orphaned resources.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>CodePipeline:<\/strong>\u00a0Open Pipelines \u2192\u00a0<code>awsdevlab-web-pipeline<\/code>. Stop\/disable active executions or transitions if possible; then select\u00a0<strong>Delete pipeline<\/strong>\u00a0and confirm. Record the CodePipeline-managed S3 artifact bucket from pipeline settings\u00a0<strong>before<\/strong>\u00a0deleting if you have not already recorded it.<\/li>\n\n\n\n<li><strong>CodeDeploy:<\/strong>\u00a0Open Applications \u2192\u00a0<code>awsdevlab-web-app<\/code>; inspect deployment group and any active deployments. Delete the deployment group and application through their\u00a0<strong>Delete<\/strong>\u00a0controls. Review\u00a0<strong>Systems Manager \u2192 State Manager\/Associations<\/strong>\u00a0for any CodeDeploy agent installation\/update associations created for the target and remove lab-only associations if they remain.<\/li>\n\n\n\n<li><strong>EC2:<\/strong>\u00a0Open EC2 \u2192 Instances; select\u00a0<code>awsdevlab-web-ec2<\/code>\u00a0and choose\u00a0<strong>Instance state \u2192 Terminate instance<\/strong>. Confirm termination. Inspect Volumes, Snapshots and Elastic IPs for any lab-only resources left behind; delete only those created by this lab. Delete\u00a0<code>awsdevlab-http-sg<\/code>\u00a0after the instance releases the security group.<\/li>\n\n\n\n<li><strong>CodeBuild:<\/strong>\u00a0Open Build projects \u2192\u00a0<code>awsdevlab-web-build<\/code>\u00a0\u2192\u00a0<strong>Delete<\/strong>. Check its optional CloudWatch Logs group; delete the lab-specific log group after saving any instructional evidence.<\/li>\n\n\n\n<li><strong>CodeCommit:<\/strong>\u00a0Open Repositories \u2192\u00a0<code>awsdevlab-webapp<\/code>\u00a0\u2192\u00a0<strong>Delete repository<\/strong>. Confirm that there is no source data you still need.<\/li>\n\n\n\n<li><strong>CodeArtifact:<\/strong>\u00a0Under Repositories delete\u00a0<code>web-npm<\/code>\u00a0and\u00a0<code>npm-store<\/code>\u00a0(including package contents per prompts), then go to Domains and delete\u00a0<code>awsdevlab<\/code>. You\u00a0<strong>cannot delete a domain until its repositories have been removed<\/strong>.<\/li>\n\n\n\n<li><strong>Amazon S3:<\/strong>\u00a0Empty the standalone\u00a0<code>awsdevlab-artifacts-ACCOUNTID-apne1<\/code>\u00a0bucket, then\u00a0<strong>Delete bucket<\/strong>. Identify the separate CodePipeline-generated artifact bucket\/folder; remove the pipeline&#8217;s lab objects, and delete the bucket\u00a0<strong>only if you confirm no other pipeline shares it<\/strong>. Versioned buckets require removal of\u00a0<strong>all object versions and delete markers<\/strong>.<\/li>\n\n\n\n<li><strong>IAM:<\/strong>\u00a0Delete the lab-specific IAM roles\u00a0<code>awsdevlab-ec2-role<\/code>,\u00a0<code>awsdevlab-codedeploy-role<\/code>, the generated CodeBuild service role, and the generated CodePipeline role\u00a0<strong>only after confirming nothing else uses them<\/strong>. Delete any custom\u00a0<code>AWSDevLabCodeArtifactRead<\/code>\u00a0policy if not reused. Detach policies before deleting roles when the console requests it.<\/li>\n\n\n\n<li><strong>CloudWatch\/EventBridge:<\/strong>\u00a0Inspect for lab-only log groups, alarms and EventBridge rules still present; delete orphaned lab-only resources. Some change detection rules are removed automatically when the pipeline is deleted.<\/li>\n\n\n\n<li><strong>Cost review:<\/strong>\u00a0Open\u00a0<strong>Billing and Cost Management \u2192 Cost Explorer<\/strong>\u00a0after billing data posts. Look for EC2, CodeBuild, CodeArtifact, CodePipeline, S3, public IPv4 and CloudWatch charges. Cost data is not necessarily real time.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Final cleanup gate:<\/strong>&nbsp;EC2 Instances shows no running training EC2, CodePipeline and CodeBuild no longer list training resources, CodeArtifact domain is deleted, the standalone S3 bucket is gone, and training IAM roles are removed or explicitly retained by policy.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Reference guide: verified documentation and sample provenance<\/h1>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th class=\"has-text-align-left\" data-align=\"left\">Key<\/th><th class=\"has-text-align-left\" data-align=\"left\">Current authoritative\/reference material<\/th><th class=\"has-text-align-left\" data-align=\"left\">URL<\/th><\/tr><\/thead><tbody><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS01<\/td><td class=\"has-text-align-left\" data-align=\"left\">AWS announcement: CodeCommit returned to general availability (24 November 2025)<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/aws.amazon.com\/blogs\/devops\/aws-codecommit-returns-to-general-availability\/\">https:\/\/aws.amazon.com\/blogs\/devops\/aws-codecommit-returns-to-general-availability\/<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS02<\/td><td class=\"has-text-align-left\" data-align=\"left\">AWS CodePipeline: create a custom pipeline (console), V1\/V2, stages and change detection<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/pipelines-create.html\">https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/pipelines-create.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS03<\/td><td class=\"has-text-align-left\" data-align=\"left\">AWS CodePipeline tutorial: CodeCommit browser files and nested paths<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/tutorials-simple-codecommit.html\">https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/tutorials-simple-codecommit.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS04<\/td><td class=\"has-text-align-left\" data-align=\"left\">AWS CodeArtifact: getting started using the console<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/getting-started-console.html\">https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/getting-started-console.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS05<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact authentication\/token behavior<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/tokens-authentication.html\">https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/tokens-authentication.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS06<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeArtifact: using npm packages in CodeBuild and IAM permissions<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/using-npm-packages-in-codebuild.html\">https:\/\/docs.aws.amazon.com\/codeartifact\/latest\/ug\/using-npm-packages-in-codebuild.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS07<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild: create build project through console<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/create-project.html\">https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/create-project.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS08<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild: buildspec syntax and artifact base-directory<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/build-spec-ref.html\">https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/build-spec-ref.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS09<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild: currently available runtimes and images<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/available-runtimes.html\">https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/available-runtimes.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS10<\/td><td class=\"has-text-align-left\" data-align=\"left\">Managed EC2 CodeDeploy role scope (AWS managed policy)<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/aws-managed-policy\/latest\/reference\/AmazonEC2RoleforAWSCodeDeploy.html\">https:\/\/docs.aws.amazon.com\/aws-managed-policy\/latest\/reference\/AmazonEC2RoleforAWSCodeDeploy.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS11<\/td><td class=\"has-text-align-left\" data-align=\"left\">Systems Manager: managing EC2 as managed nodes<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/systems-manager\/latest\/userguide\/systems-manager-setting-up-nodes.html\">https:\/\/docs.aws.amazon.com\/systems-manager\/latest\/userguide\/systems-manager-setting-up-nodes.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS12<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy\/CodePipeline tutorial: configure agent using SSM in deployment group<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/tutorials-simple-codecommit.html\">https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/tutorials-simple-codecommit.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS13<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy: install CodeDeploy agent through Systems Manager Distributor<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codedeploy\/latest\/userguide\/codedeploy-agent-operations-install-ssm.html\">https:\/\/docs.aws.amazon.com\/codedeploy\/latest\/userguide\/codedeploy-agent-operations-install-ssm.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS14<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeDeploy: create EC2\/on-prem deployment with S3 revision<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codedeploy\/latest\/userguide\/deployments-create-console.html\">https:\/\/docs.aws.amazon.com\/codedeploy\/latest\/userguide\/deployments-create-console.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS15<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodeBuild: change project source and artifacts in the console<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/change-project.html\">https:\/\/docs.aws.amazon.com\/codebuild\/latest\/userguide\/change-project.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS16<\/td><td class=\"has-text-align-left\" data-align=\"left\">CodePipeline: CodeDeploy deploy action and artifact requirements<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/action-reference-CodeDeploy.html\">https:\/\/docs.aws.amazon.com\/codepipeline\/latest\/userguide\/action-reference-CodeDeploy.html<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS17<\/td><td class=\"has-text-align-left\" data-align=\"left\">GitHub sample: AWS CodeDeploy&nbsp;<code>SampleApp_Linux<\/code>&nbsp;(architecture and origin)<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/github.com\/aws-samples\/aws-codedeploy-samples\/tree\/master\/applications\/SampleApp_Linux\">https:\/\/github.com\/aws-samples\/aws-codedeploy-samples\/tree\/master\/applications\/SampleApp_Linux<\/a><\/td><\/tr><tr><td class=\"has-text-align-left\" data-align=\"left\">AWS18<\/td><td class=\"has-text-align-left\" data-align=\"left\">lodash package source and current npm package information<\/td><td class=\"has-text-align-left\" data-align=\"left\"><a href=\"https:\/\/www.npmjs.com\/package\/lodash\">https:\/\/www.npmjs.com\/package\/lodash<\/a><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Source integrity reminder:<\/strong>&nbsp;This guide is an original training adaptation, not a claim that the GitHub sample was written for CodeArtifact or AL2023. For exact upstream source and license, review the AWS GitHub repository. The downloadable training ZIP contains the files participants should transfer through the CodeCommit browser editor. No AWS or GitHub credentials are bundled.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>title AWS Developer Services: Gold-Standard Console Lab Guide subtitle CodeCommit \u2022 CodeArtifact \u2022 CodeBuild \u2022 CodeDeploy \u2022 CodePipeline author Instructor Edition | Browser-Only Labs date 10 November&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-1278","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1278","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/comments?post=1278"}],"version-history":[{"count":1,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1278\/revisions"}],"predecessor-version":[{"id":1279,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/posts\/1278\/revisions\/1279"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/media?parent=1278"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/categories?post=1278"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/tutorials\/wp-json\/wp\/v2\/tags?post=1278"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}