<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: KUSEH SIMON WEWOLIAMO</title>
    <description>The latest articles on Forem by KUSEH SIMON WEWOLIAMO (@kodecapsule).</description>
    <link>https://forem.com/kodecapsule</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1111924%2F1f15df91-edd5-47aa-bea9-d810edc3b321.jpg</url>
      <title>Forem: KUSEH SIMON WEWOLIAMO</title>
      <link>https://forem.com/kodecapsule</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/kodecapsule"/>
    <language>en</language>
    <item>
      <title>Stop Storing AWS Access Keys in GitHub Secrets — Use OIDC Instead to Authenticate GitHub Actions to AWS</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Thu, 12 Feb 2026 03:58:17 +0000</pubDate>
      <link>https://forem.com/kodecapsule/stop-storing-aws-access-keys-in-github-secrets-use-oidc-instead-to-authenticate-github-actions-to-47g9</link>
      <guid>https://forem.com/kodecapsule/stop-storing-aws-access-keys-in-github-secrets-use-oidc-instead-to-authenticate-github-actions-to-47g9</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;If you’re storing AWS access keys in GitHub Secrets, you’re already behind modern cloud security practices.Let’s all be honest to ourselves, we have in one way or the other dump AWS access keys into GitHub Secrets or we might have read somewhere especially on Reddit about someone  dumping AWS access keys into GitHub Secrets. Well, this works, but you’re carrying unnecessary risk.  Access keys are long-lived credentials and don’t rotate automatically, and once leaked, they’re hard to contain. &lt;/p&gt;

&lt;p&gt;OpenID Connect (OIDC) offers  a better option for authentication without storing a long-lived credentials in GitHub secrets. In this post, I will walk you through  how  GitHub OIDC actually works, why it is more secure compared to long-lived credentials like access keys and how to integrate AWS with GitHub Actions using OIDC.&lt;br&gt;
If you care about safer pipelines and cleaner CloudOps practices, this is one upgrade you don’t want to skip. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Access Keys&lt;/th&gt;
&lt;th&gt;OIDC&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Credential Type&lt;/td&gt;
&lt;td&gt;Long-lived&lt;/td&gt;
&lt;td&gt;Short-lived&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Rotation Required&lt;/td&gt;
&lt;td&gt;Manual&lt;/td&gt;
&lt;td&gt;Automatic&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Stored in GitHub&lt;/td&gt;
&lt;td&gt;Yes&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Blast Radius&lt;/td&gt;
&lt;td&gt;High&lt;/td&gt;
&lt;td&gt;Low&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h2&gt;
  
  
  How GitHub Actions OIDC integrates with AWS to access resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6cmamzr8t27hnx0nrvf.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj6cmamzr8t27hnx0nrvf.gif" alt="How GitHub Actions OIDC integrates with AWS to access resources" width="760" height="351"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Step 1 Establish trust relationship:&lt;/strong&gt; A trust relationship needs to be established between GitHub (the Identity Provider – IdP) and AWS (the Service Provider / Relying Party - RP). This relationship will register GitHub as a trusted OIDC provider and will tell AWS where to fetch GitHub’s public signing keys and which token claims AWS should trust.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 2 Authentication Request:&lt;/strong&gt; When a workflow runs, GitHub generates a  signed  JSON Web Token (JWT) with identity claims that include repository name, branch or tag, workflow name, commit SHA, GitHub org, etc., which proves where the job is running at the moment.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 3 Token Validation:&lt;/strong&gt; The Relying Party (RP), AWS,  validates the token using the token signature, issuer, audience, and if token claims match IAM trust policy conditions. The checks either fail or succeed. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 4 Issues Short-Lived Credentials:&lt;/strong&gt; If the validation is successful, it allows the workflow to assume an IAM role, and temporary credentials are issued via STS. The credentials have an automatic expiration period. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Step 5 Workflow Uses AWS:&lt;/strong&gt; The workflow then executes/access AWS resources based on actions that are defined in the IAM role. After the job is completed, the credentials expire, requiring no cleanup. &lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Configuring GitHub Actions OIDC with AWS IAM
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Step 1:&lt;/strong&gt; Create an OIDC provider in your AWS  IAM for GitHub
&lt;/h3&gt;

&lt;p&gt;In this step,  you will set up the OpenID Provider, which is GitHub.  We will be using the AWS console but you can also use AWS CLI too if that is your preference.   &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in to AWS and open the IAM console, and select Identity providers in the left navigation menu&lt;/li&gt;
&lt;li&gt; Click  Add provider button, and in the provider details, enter these details:

&lt;ul&gt;
&lt;li&gt;Provider type: OpenID Connect&lt;/li&gt;
&lt;li&gt;Provider URL: &lt;a href="https://token.actions.githubusercontent.com" rel="noopener noreferrer"&gt;https://token.actions.githubusercontent.com&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Audience: sts.amazonaws.com&lt;/li&gt;
&lt;li&gt;Add tags: optional&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkxz7wjfk435fogo45e7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqkxz7wjfk435fogo45e7.png" alt="Create an OIDC provider in your AWS  IAM for GitHub" width="800" height="337"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Step 2:&lt;/strong&gt; Create an IAM role
&lt;/h3&gt;

&lt;p&gt;1.In the Identity providers screen, select the provider you just created and choose the &lt;code&gt;Assign role&lt;/code&gt; button. Select Create new role and then choose Next.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Select Identity provider&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0c504b08ovt73y2bdh3i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0c504b08ovt73y2bdh3i.png" alt="Select Identity provider" width="800" height="342"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;em&gt;Select Assign role&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhl9v4jkg6q0l5mi3eln.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuhl9v4jkg6q0l5mi3eln.png" alt="Select Assign role" width="800" height="338"&gt;&lt;/a&gt;&lt;br&gt;
 &lt;em&gt;Select Create new role&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1d7m0xterlu8qecv5bgt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1d7m0xterlu8qecv5bgt.png" alt="Select Create new role" width="800" height="342"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;2.Select Web identity and provide these details&lt;br&gt;
      - Identity provider: token.actions.githubusercontent.com&lt;br&gt;
      - Audience: sts.amazonaws.com&lt;br&gt;
      - GitHub organization: Provide your GitHub organization. &lt;br&gt;
If you don't have a GitHub organization, you can use &lt;a href="https://docs.github.com/en/organizations/collaborating-with-groups-in-organizations/creating-a-new-organization-from-scratch" rel="noopener noreferrer"&gt;Creating a new organization from scratch&lt;/a&gt;  to create one.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Select Web identity&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fccb5rnhtsdhihyl732ej.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fccb5rnhtsdhihyl732ej.png" alt="Select Web identity" width="800" height="220"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Web identity details&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmsxt0kjbnu86lb16mj7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhmsxt0kjbnu86lb16mj7.png" alt="Web identity details" width="800" height="341"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;3.On the Permissions page, search for &lt;code&gt;AmazonS3FullAccess&lt;/code&gt; and select it  for this demo, and select Next to continue&lt;br&gt;
&lt;em&gt;S3 Permissions&lt;/em&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsx3vb5mybanarc8n1enw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsx3vb5mybanarc8n1enw.png" alt="S3 Permissions" width="800" height="236"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4.In the next step, enter a role name, for this demo, &lt;code&gt;GitHubAction-AssumeRoleWithAction&lt;/code&gt;. You can optionally add a description. Review and click Create role. &lt;br&gt;
&lt;em&gt;Review and create role&lt;/em&gt; &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpil7zeqtiaunuhabje0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpil7zeqtiaunuhabje0.png" alt="Review and create role" width="800" height="217"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Step 3:&lt;/strong&gt; Create a trust policy condition to restrict access by repository, branch, or environment
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;In the IAM console,  select the newly created role, &lt;code&gt;GitHubAction-AssumeRoleWithAction&lt;/code&gt;, and choose the &lt;code&gt;Trust relationship&lt;/code&gt; tab and select Edit trust policy. &lt;/li&gt;
&lt;li&gt;Copy and paste this policy into the editor and save the changes. Make sure to replace &lt;code&gt;&amp;lt;AWS_ACCOUNT_ID&amp;gt;&lt;/code&gt; with your AWS account ID, &lt;code&gt;&amp;lt;OWNER&amp;gt;&lt;/code&gt; with your GitHub username, &lt;code&gt;&amp;lt;REPO_NAME&amp;gt;&lt;/code&gt; with your repository name and &lt;code&gt;&amp;lt;BRANCH&amp;gt;&lt;/code&gt; with your branch name.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
    &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
        &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
            &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"Federated"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:iam::&amp;lt;AWS_ACCOUNT_ID&amp;gt;:oidc-provider/token.actions.githubusercontent.com"&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;,
            &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRoleWithWebIdentity"&lt;/span&gt;,
            &lt;span class="s2"&gt;"Condition"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                &lt;span class="s2"&gt;"StringEquals"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"token.actions.githubusercontent.com:aud"&lt;/span&gt;: &lt;span class="s2"&gt;"sts.amazonaws.com"&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;,
                &lt;span class="s2"&gt;"StringLike"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
                    &lt;span class="s2"&gt;"token.actions.githubusercontent.com:sub"&lt;/span&gt;: &lt;span class="s2"&gt;"repo:&amp;lt;OWNER&amp;gt;/&amp;lt;REPO_NAME&amp;gt;/ref:refs/heads/&amp;lt;BRANCH&amp;gt;"&lt;/span&gt;
                &lt;span class="o"&gt;}&lt;/span&gt;
            &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Understanding OIDC Token Claims (Advanced but Important)
&lt;/h3&gt;

&lt;p&gt;When GitHub issues the OIDC token, it includes several claims that AWS evaluates in the trust policy. The most important claim is the &lt;code&gt;sub (subject)&lt;/code&gt;. The &lt;code&gt;sub&lt;/code&gt; claim typically follows this format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;repo:OWNER/REPO:ref:refs/heads/BRANCH
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;example&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;repo:my-org/my-repo:ref:refs/heads/main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that the workflow is running in &lt;code&gt;my-org/my-repo&lt;/code&gt; and it was triggered from the main branch. Restricting by repository name means that any branch in that repo can assume the role, but if you restrict by branch, only workflows from that branch can assume the role. This is the best security practice because it prevents:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Malicious pull requests&lt;/li&gt;
&lt;li&gt;Feature branches gaining production access and &lt;/li&gt;
&lt;li&gt;Unauthorized role assumption
This is where OIDC becomes truly powerful — it allows fine-grained, identity-based authorization instead of relying on static secrets.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 4:Optional:&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;You can attach more permissions policies, either AWS  or custom policies (remember to use the principle of least privilege), to the IAM role, defining what AWS actions are allowed when using the role.  &lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Step 5:&lt;/strong&gt;  Add the IAM Role  ARN  to the GitHub repository as  secrets
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;1.&lt;/strong&gt; In your GitHub account, create a repo or select an existing repo that you want to use. The repo I am using is  "Zero-Trust CI/CD: Using OIDC to Authenticate GitHub Actions to AWS".&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;2.&lt;/strong&gt; Select the repo settings and, in the left menu, select Secrets and variables. Choose Actions in the sub menu and click on the &lt;code&gt;New repository secret&lt;/code&gt; button. Add these details&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Name: AWS_OIDC_ROLE_ARN&lt;/li&gt;
&lt;li&gt;Secret: arn:aws:iam:::role/. 
&lt;em&gt;NOTE&lt;/em&gt; Copy the role ARN and add it as a secret. You are now ready to use it in your workflows.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fecpspklxmlz5umt9uf6a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fecpspklxmlz5umt9uf6a.png" alt="Add role ARN as GitHub secret step 1" width="800" height="364"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm2kf5ya2btg5fw62ncq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhm2kf5ya2btg5fw62ncq.png" alt="Add role ARN as GitHub secret step 2" width="800" height="313"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;Step 6:&lt;/strong&gt;  Create a  workflow to use the role ARN and specify the AWS region
&lt;/h3&gt;

&lt;p&gt;In this next step, we will   validate the integration of OIDC with AWS. To do this we will create a workflow. Create this workflow &lt;/p&gt;

&lt;p&gt;&lt;code&gt;.github/workflows/create-s3-bucket.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;name: Create S3 Bucket with OIDC

on:
  workflow_dispatch:

permissions:
  id-token: write
  contents: &lt;span class="nb"&gt;read
  &lt;/span&gt;pull-requests: write
  security-events: write

&lt;span class="nb"&gt;jobs&lt;/span&gt;:
  create-bucket:
    runs-on: ubuntu-latest

    steps:
      - name: Configure AWS credentials
        uses: aws-actions/configure-aws-credentials@v5.1.0
        with:
          role-to-assume: &lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="p"&gt;{ secrets.AWS_OIDC_ROLE_ARN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
          role-session-name: GitHubAction-AssumeRoleWithAction
          aws-region: us-east-1


      - name: Create S3 bucket
        run: |
          aws s3api create-bucket &lt;span class="se"&gt;\&lt;/span&gt;
            &lt;span class="nt"&gt;--bucket&lt;/span&gt; just-another-new-bucket-124 &lt;span class="se"&gt;\&lt;/span&gt;
            &lt;span class="nt"&gt;--region&lt;/span&gt; us-east-1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the  OIDC Connection by running the workflow.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Workflow ran successfully&lt;/strong&gt;.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25lfj0yatezyk1t2s34d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F25lfj0yatezyk1t2s34d.png" alt="Workflow success 1" width="800" height="363"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;S3 bucket created&lt;/strong&gt; &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq5xs1lrftma5t0t4x1nq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fq5xs1lrftma5t0t4x1nq.png" alt="Workflow success 2 " width="800" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Building a secure CI/CD pipeline forms a crucial part of modern software development. Storing long-lived credentials in CI/CD pipelines is a bad security practice that is still being used by some teams. OIDC offers a better alternative for enhancing your workflows using identity-based and short-lived credentials. This approach reduces your attack surface and simplifies credentials management. Your pipelines still rely on stored AWS Access keys; the question is no longer “Why switch to OIDC?”&lt;br&gt;
It’s “Why haven’t you switched yet?” Modern CloudOps is identity-driven. If you're still using static credentials in 2026, it's time to upgrade your pipeline security posture. I'd like to find out from you how you manage AWS credentials using GitHub Actions. Have you tried the OIDC approach? Please let me know in the comments.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>devops</category>
      <category>github</category>
    </item>
    <item>
      <title>AWS Community Builder Applications for 2026 is Now Open! Here's Why You Should Apply.</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Thu, 08 Jan 2026 17:15:46 +0000</pubDate>
      <link>https://forem.com/aws-builders/aws-community-builder-applications-for-2026-is-now-open-heres-why-you-should-apply-17c6</link>
      <guid>https://forem.com/aws-builders/aws-community-builder-applications-for-2026-is-now-open-heres-why-you-should-apply-17c6</guid>
      <description>&lt;p&gt;I remember last year, I had a couple of people in my DM asking me how they could become an AWS Community Builder. Well,&lt;/p&gt;

&lt;p&gt;it is that time of the year again when you get the opportunity to join and become an AWS Community Builder. This community is made up of AWS enthusiasts who are willing to learn and share their knowledge and expertise on AWS. By joining this amazing community, you get to network with like-minded people ready to help accelerate their growth. I have personally gained so much from being an AWS Community Builder.&lt;/p&gt;

&lt;p&gt;The benefits that you get when you join AWS Community Builder include:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;$500 AWS credits for personal projects&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Discounted re:Invent tickets&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A free AWS certification voucher&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Learn about new services and features.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Exclusive trainings and events&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Premium swag and resources&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This community is mainly focused on AWS, but this year the aperture has been widened to bring in more builders who are not heavy users of AWS yet. What this means is that if you are someone who creates high-quality content in the areas of AI, MCP, containers, open-source projects, etc., then you are welcome to apply and be part of this amazing community.&lt;/p&gt;

&lt;p&gt;Please DM me or get in touch with any current AWS Community Builder if you're interested and would need more information about the application process. You can also ask questions in the comments section, and I'll be pleased to assist you.&lt;/p&gt;

&lt;p&gt;Apply using this link: &lt;a href="https://lnkd.in/efmwMgcs" rel="noopener noreferrer"&gt;https://lnkd.in/efmwMgcs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Best of luck.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloud</category>
      <category>containers</category>
      <category>ai</category>
    </item>
    <item>
      <title>Mastering AWS Lambda Layers: Build, Deploy, and Manage Reusable Components</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Mon, 02 Jun 2025 12:17:51 +0000</pubDate>
      <link>https://forem.com/aws-builders/mastering-aws-lambda-layers-build-deploy-and-manage-reusable-components-444c</link>
      <guid>https://forem.com/aws-builders/mastering-aws-lambda-layers-build-deploy-and-manage-reusable-components-444c</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;
Understanding Lambda Layers

&lt;ul&gt;
&lt;li&gt;
How Layers Work &lt;/li&gt;
&lt;li&gt;
Layer Versions  &lt;/li&gt;
&lt;li&gt;
Benefits of Using Lambda Layers  &lt;/li&gt;
&lt;li&gt;
Common Use Cases for AWS Lambda Layers &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Creating Your First Lambda Layer

&lt;ul&gt;
&lt;li&gt;Prepare and package your  Lambda layer Content&lt;/li&gt;
&lt;li&gt;Create and Publish your Lambda Layer in AWS&lt;/li&gt;
&lt;li&gt;
Use the Layer in Your Lambda Function
&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Advanced Layer Techniques

&lt;ul&gt;
&lt;li&gt;Multi-language Layers&lt;/li&gt;
&lt;li&gt;
Layer Size Optimization &lt;/li&gt;
&lt;li&gt;Automated Layer Updates&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Best Practices for Lambda Layers &lt;/li&gt;

&lt;li&gt;Conclusion&lt;/li&gt;

&lt;li&gt;References and Additional Resources&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Serverless computing is a computing technique and an execution model that enables you to build and run application code without having to think about provisioning and managing servers and/or back-end infrastructure. In AWS Lambda, a serverless service is the backbone when it comes to building serverless applications on AWS. AWS Lambda allows you to focus on your application code while it handles infrastructure management, auto-scaling and other heavy lifting.&lt;/p&gt;

&lt;p&gt;As your serverless applications grow in complexity and the number of Lambda functions becomes numerous, certain challenges, such as dependency management and code reuse, are inevitable. To address these issues, our hero , Lambda Layers, comes to the rescue. In this article we will explore everything you need to know about Lambda Layers, from the basics to some advanced concepts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding AWS Lambda Layers
&lt;/h2&gt;

&lt;p&gt;A lambda layer is a special container, a &lt;code&gt;.zip&lt;/code&gt; file archive that contains supplementary code or data. Lambda layers serve as a distribution mechanism for function dependencies, custom runtime, or configuration files for your Lambda functions. Layers let you keep your function deployment packages small and organized by separating your function business logic code from its dependencies.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvojxwlx4wq8xmj3fqp13.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvojxwlx4wq8xmj3fqp13.gif" alt="Lambda Layer Architecture" width="720" height="521"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the diagram shown above, using the traditional approach without layers, each of the Lambda functions packages contains everything it needs to function. Lambda Function &lt;strong&gt;A&lt;/strong&gt;  includes requests, pyshorteners , qrcode dependencies and custom runtime libraries (logging, authentication), along with its  business logic code, (requests, pyshorteners, qrcode). Function  &lt;strong&gt;B&lt;/strong&gt; also uses the same  dependencies and custom runtime libraries, plus its own business logic. With this approach, you can clearly see there is code duplication across the two functions, leading to larger deployment packages.&lt;/p&gt;

&lt;p&gt;The optimized approach as shown in the diagram using Lambda Layers showsthat , both functions &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B&lt;/strong&gt; now  only contain their business logic code which has much smaller packages and dependencies requests, pyshorteners, qrcode are bundled into a layer. The custom runtime libraries (logging, authentication) are also put in another layer that is shared by both functions.&lt;/p&gt;

&lt;h3&gt;
  
  
  How Layers Work
&lt;/h3&gt;

&lt;p&gt;A layer essentially bundles code or data into a &lt;code&gt;ZIP&lt;/code&gt; archive that is automatically extracted by the lambda service into the &lt;code&gt;/opt&lt;/code&gt;  directory in your function’s execution environment. Your function code can then access the Layer's content during its execution.&lt;/p&gt;

&lt;p&gt;Lambda Layers operate using a simple workflow.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. First, you package your function's, dependencies or shared code into a &lt;code&gt;ZIP&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;2. You then create and publish the Layer to the  Lambda service.&lt;/li&gt;
&lt;li&gt;3. After creating the layer, you can attach the layer to one or more lambda functions.&lt;/li&gt;
&lt;li&gt;4. When your function executes, it can then access the Layer's content as if it were part of the function's deployment package.&lt;/li&gt;
&lt;li&gt;5. You can then update the layer and create different versions of the layer depending on your needs. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lambda allows you to add up to a maximum of five Layers per function, and the layer content still counts towards the function's deployment package size quota (i.e. 250MB for .zip file archives).&lt;br&gt;
&lt;strong&gt;NOTE&lt;/strong&gt; All the packages in your layer must  be Linux compatible, since  Lambda functions run on Amazon Linux.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraqifd4fy14x3huvhu74.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fraqifd4fy14x3huvhu74.gif" alt="Lambda Layer Architecture" width="720" height="520"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The diagram above depicts three Lambda functions &lt;strong&gt;A&lt;/strong&gt;, &lt;strong&gt;B&lt;/strong&gt;, and &lt;strong&gt;C&lt;/strong&gt; each function containing its own business logic code.Three shared Lambda layers, &lt;code&gt;Layer 1&lt;/code&gt;, &lt;code&gt;Layer 2&lt;/code&gt; and &lt;code&gt;Layer 3&lt;/code&gt; are mounted at /opt in  function &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B&lt;/strong&gt; execution environments whiles  &lt;code&gt;Layer 1&lt;/code&gt;and &lt;code&gt;Layer 2&lt;/code&gt; are mounted at /opt in  function &lt;code&gt;C&lt;/code&gt; execution environment.&lt;/p&gt;

&lt;p&gt;Layer 1 contains the common libraries that are used most frequently,such as  &lt;code&gt;requests&lt;/code&gt; and &lt;code&gt;boto3&lt;/code&gt; by most AWS applications. Layer 2, packages some  custom utilities such as &lt;strong&gt;authentication&lt;/strong&gt; and &lt;strong&gt;logging&lt;/strong&gt; functionalities. Layer 3  bundles some ML models, that is only used by Functions &lt;strong&gt;A&lt;/strong&gt; and &lt;strong&gt;B&lt;/strong&gt; but function &lt;strong&gt;C&lt;/strong&gt; doesn't use this layer.&lt;/p&gt;
&lt;h3&gt;
  
  
  Layer Versions
&lt;/h3&gt;

&lt;p&gt;Lambda layers are versioned. A layer version is an immutable snapshot of a layer's specific release. When you add a new layer, Lambda creates a new layer version with the version number 1. When you publish an update to a layer, Lambda automatically increments the version number by 1 and creates a new layer version. Each layer version has a unique Amazon Resource Name (ARN). When adding a layer to a function, ensure you specify the layer version you wish to use.&lt;/p&gt;
&lt;h3&gt;
  
  
  Benefits of Using Lambda Layers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;1.Reduced the size of a function's deployment packages:Instead of including all of your function dependencies in your deployment package, place them in a layer.  This keeps deployment bundles simple and manageable.&lt;/li&gt;
&lt;li&gt;2.Separation of Concerns: Layers can help  separate your function's  business logic from its  dependencies and allows different team members to focus on different aspects of the application.&lt;/li&gt;
&lt;li&gt;3.Code Reusability:Layers allow you to share dependencies across multiple lambda functions. Without layers, you need to include the same dependencies in each of your function's deployment package which goes agains the the DRY (Don't Repeat Yourself) principle in programming.&lt;/li&gt;
&lt;li&gt;4.To use the Lambda console code editor:The code editor is a helpful tool for rapidly evaluating small changes to function code.  However, if your deployment package is too big, you won't be able to use the editor.  Layers allow you to use the code editor and reduce the size of your package.&lt;/li&gt;
&lt;li&gt;5.Faster Deployment Times:When you use smaller Lambda deployment packages, your Lambda uploads are faster, resulting in faster function updates.  This efficiency is especially useful in CI/CD pipelines, where deployment speed influences overall development velocity.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Common Use Cases for AWS Lambda Layers
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;1.Database Connectors: Database drivers and connectors in applications  often include some complex dependencies, bundling  such dependencies  in a layer ensures that your  database access patterns are uniform for all your Lambda functions.&lt;/li&gt;
&lt;li&gt;2.Monitoring and Logging Utilities: You may have some  instrumentation code used for monitoring, logging, and tracing in your applications, it is best practice to use  a shared layer that  can easily be  used across functions without any changes. This makes sure that your applications  uses the same observability best practices.&lt;/li&gt;
&lt;li&gt;3.Internal Company Libraries: Many organisations mostly develop their own internal tools and libraries. Packing these tools and libraries as Layers encourages reuse and standardisation in  multiple  projects in the organization.&lt;/li&gt;
&lt;li&gt;4.Frameworks and SDKs: Layers can be used  to package complete frameworks or SDKs, ensuring that there is some  consistency in functions.  This approach is good for organization-specific frameworks or some huge third-party SDKs that might otherwise bloat your function packages.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Real-World Example of using layers
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Shared Authentication Layer&lt;/strong&gt;&lt;br&gt;
Authentication is a common action that is often implemented in many applications  and frequently needed by   multiple lambda functions. A shared authentication  layer that standardize the authentication process is commonly used  for this  functionality. An example of such functionality is demostrated in the code below.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# In the Lambda Layer (python/lib/python3.9/site-packages/auth_utils.py)
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;
&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;verify_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Verify JWT token and return payload if valid&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="n"&gt;secret&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;JWT_SECRET&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
        &lt;span class="n"&gt;payload&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;decode&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;secret&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;algorithms&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;HS256&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;valid&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;payload&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;payload&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;InvalidTokenError&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;valid&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Invalid token&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;except&lt;/span&gt; &lt;span class="nb"&gt;Exception&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;valid&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;str&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Multiple functions that need authentication can then use this shared athentication layer as in the below code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="c1"&gt;# In the Lambda function
&lt;/span&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;
&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;auth_utils&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;verify_token&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;handler&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="c1"&gt;# Extract token from event
&lt;/span&gt;    &lt;span class="n"&gt;auth_header&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;event&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;headers&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{}).&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Authorization&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;token&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;auth_header&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Bearer &lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;auth_header&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="sh"&gt;''&lt;/span&gt;

    &lt;span class="c1"&gt;# Verify token
&lt;/span&gt;    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;verify_token&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;token&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;valid&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;statusCode&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;401&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;body&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;json&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dumps&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;error&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;Unauthorized&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="c1"&gt;# Continue with authorized operation
&lt;/span&gt;    &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;payload&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;][&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;sub&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="c1"&gt;# ...
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating Your First Lambda Layer
&lt;/h2&gt;

&lt;p&gt;In this section i will walk you through  the process of creating and using  Lambda Layers. In this demo i will be creating a python application that generates a short url given a long url. The main dependencies, will be bundled in a lambda layer.&lt;/p&gt;

&lt;p&gt;First we will create a python virtual environments at install all the neccessory dependencies&lt;/p&gt;

&lt;h3&gt;
  
  
  Prepare and package your  Lambda layer Content
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt; Creat a Python virtual environment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  python &lt;span class="nt"&gt;-m&lt;/span&gt; venv venv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt; Activate the virtual environment and install the dependcies in the requiremnets.txt file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;source &lt;/span&gt;venv/Scripts/activate
  pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; requirements.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt; Create a directory called &lt;code&gt;python&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="nb"&gt;mkdir &lt;/span&gt;python 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: The directory structure matters! Python packages must be in a directory named &lt;code&gt;python&lt;/code&gt; to be automatically added to the PYTHONPATH when the layer is attached to a Lambda function.&lt;br&gt;
&lt;strong&gt;Step 4&lt;/strong&gt; copy the content in venv/Lib/site-packages/ directory  to python/&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; venv/Lib/site-packages/&lt;span class="k"&gt;*&lt;/span&gt; python/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt; Zip the content of the python directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  zip &lt;span class="nt"&gt;-r&lt;/span&gt; python.zip python
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create and Publish your Lambda Layer in AWS
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Method 1:Using AWS Console
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Login into your AWS account and  open the AWS Lambda console&lt;/li&gt;
&lt;li&gt;Navigate to &lt;code&gt;Layers&lt;/code&gt;in the left navigation&lt;/li&gt;
&lt;li&gt;Choose &lt;code&gt;Create layer&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Enter details:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Name&lt;/strong&gt;: Give your layer a descriptive name (e.g., &lt;code&gt;url-shortener-lib&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Description(Optional)&lt;/strong&gt;: enter a description of what's in the layer&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Upload ZIP&lt;/strong&gt;: Upload your layer zip,&lt;code&gt;python-layer.zip&lt;/code&gt; file. You can upload directly from you computer or Amazon S3&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatible architectures(Optional)&lt;/strong&gt;: Select  one value or both values. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compatible runtimes(Optional)&lt;/strong&gt;: Select the appropriate runtimes (e.g., python 3.10 python 3.11 python 3.12, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;License(Optional)&lt;/strong&gt;: enter any necessary license information&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Choose &lt;code&gt;Create&lt;/code&gt; to publish your layer&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Method 2:Using AWS CLI
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  aws lambda publish-layer-version &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--layer-name&lt;/span&gt; url-shortener-lib &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"Layer contains all the dependecies for the url-shortener lambda function"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--zip-file&lt;/span&gt; fileb://python-layer.zip &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--compatible-runtimes&lt;/span&gt; python3.10 python3.11 python3.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: If the size of your python.zip file is greater than 10mb, it is recommended to uplaod the zip file to an S3 bucket and use the object ARN.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Create a Lambda Function
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Method 1:Using AWS Console
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Open the AWS Lambda console&lt;/li&gt;
&lt;li&gt;Click the "Create function" button&lt;/li&gt;
&lt;li&gt;Choose one of the creation options:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Author from scratch:&lt;/strong&gt; Start with a basic function ✅&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Use a blueprint:&lt;/strong&gt; Use pre-built templates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Container image:&lt;/strong&gt;Deploy from a container image&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browse serverless app repository:&lt;/strong&gt; Use existing applications
4 Choose Author from scratch:

&lt;ul&gt;
&lt;li&gt; &lt;strong&gt;Function name:&lt;/strong&gt; Enter a descriptive name (url-shortener)&lt;/li&gt;
&lt;li&gt; &lt;strong&gt;Runtime:&lt;/strong&gt; Select your preferred runtime (Python 3.12)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Architecture:&lt;/strong&gt; Choose x86_64 or arm64&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Permissions:&lt;/strong&gt; Choose &lt;code&gt;Create a new role with basic Lambda permissions&lt;/code&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Click "Create function"&lt;/li&gt;
&lt;li&gt;Upload the code from the python script, &lt;code&gt;url-shortener.py&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Method 2: Using AWS CLI
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="c"&gt;# Create a basic Lambda function&lt;/span&gt;
aws lambda create-function &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--function-name&lt;/span&gt; url-shortener &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--runtime&lt;/span&gt; python3.12 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--role&lt;/span&gt; arn:aws:iam::YOUR_ACCOUNT_ID:role/lambda-execution-role &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--handler&lt;/span&gt; lambda_function.lambda_handler &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--zip-file&lt;/span&gt; fileb://function.zip &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--description&lt;/span&gt; &lt;span class="s2"&gt;"My url-shortener function"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use the Layer in Your Lambda Function (url-shortener)
&lt;/h3&gt;

&lt;p&gt;Now you can attach this layer to any Lambda function:&lt;/p&gt;

&lt;h4&gt;
  
  
  Method 1:Using AWS Console
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to your Lambda function ,url-shortener&lt;/li&gt;
&lt;li&gt;Go to the "Layers" section below the code editor&lt;/li&gt;
&lt;li&gt;Click "Add a layer"&lt;/li&gt;
&lt;li&gt;Select "Custom layers"&lt;/li&gt;
&lt;li&gt;Choose your layer and version&lt;/li&gt;
&lt;li&gt;Click "Add"&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Method 2:Using AWS CLI
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws lambda update-function-configuration &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--function-name&lt;/span&gt; url-shortener &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--layers&lt;/span&gt; arn:aws:lambda:&amp;lt;REGION&amp;gt;:&amp;lt;ACCOUNT-ID&amp;gt;:&amp;lt;lLAMBDA LAYER NAME&amp;gt;:&amp;lt;VERSION&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace &lt;code&gt;&amp;lt;REGION&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;ACCOUNT-ID&amp;gt;&lt;/code&gt; &lt;code&gt;&amp;lt;lLAMBDA LAYER NAME&amp;gt;&lt;/code&gt; and &lt;code&gt;&amp;lt;VERSION&amp;gt;&lt;/code&gt; with the respective values&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing  Your Lambda Function.
&lt;/h3&gt;

&lt;p&gt;After you have successfully created your function and layer ,we need to test to make sure everything is working fine. &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Click on the "Test" tab (located near the top, next to "Code" and "Configuration")&lt;/li&gt;
&lt;li&gt;If this is your first test, you'll see "Configure test event" &lt;/li&gt;
&lt;li&gt;Click &lt;code&gt;Create new event&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Give your test event a name (url_url-shortener)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"url"&lt;/span&gt;: &lt;span class="s2"&gt;"https://www.example.com/very/long/path/to/some/resource?param1=value1&amp;amp;param2=value2"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Click test.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;expected response&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"statusCode"&lt;/span&gt;: 200,
  &lt;span class="s2"&gt;"headers"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"Content-Type"&lt;/span&gt;: &lt;span class="s2"&gt;"application/json"&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;,
  &lt;span class="s2"&gt;"body"&lt;/span&gt;: &lt;span class="s2"&gt;"{&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;original_url&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;https://www.example.com/very/long/path/to/some/resource?param1=value1&amp;amp;param2=value2&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;short_url&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;https://tinyurl.com/abc123&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;}"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advanced Layer Techniques
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Multi-language Layers
&lt;/h3&gt;

&lt;p&gt;A single Layer can support multiple runtimes by including the appropriate directory structure for each. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;layer-content/
├── python/
│   └── lib/
│       └── python3.9/
│           └── site-packages/
│               └── shared_package/
└── nodejs/
    └── node_modules/
        └── shared-package/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is particularly useful for cross-language utilities or when implementing polyglot applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Layer Size Optimization
&lt;/h3&gt;

&lt;p&gt;Your lambda layers, just like function deployment packages, have a size limit of 250 MB unzipped file. In order to optimize your layer size:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Only include  production dependencies in your layer; make sure to  exclude any  development and testing dependencies that will bloat your layer size&lt;/li&gt;
&lt;li&gt;Use specific and selective imports for large libraries, for example, do not import a whole library but rather import specific components that you need.&lt;/li&gt;
&lt;li&gt;Try and compress static assets when possible&lt;/li&gt;
&lt;li&gt;Remove some  unnecessary files like documentation and examples, which are likely to increase the size of your layer&lt;/li&gt;
&lt;li&gt;Always consider splitting very large dependencies  into multiple Layers &lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Automating Layer Updates
&lt;/h3&gt;

&lt;p&gt;When you have  dependencies that require frequent updates, it is best you consider automating  these  layer updates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can  first create a CI/CD pipeline that will:

&lt;ul&gt;
&lt;li&gt;periodically checks for dependency updates&lt;/li&gt;
&lt;li&gt;builds a new Layer version when updates are available&lt;/li&gt;
&lt;li&gt;publishe the new Layer version&lt;/li&gt;
&lt;li&gt;and optionally updates functions that depend on the layer to use the new version&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You can also  use AWS EventBridge to trigger the pipeline on a schedule or in response to security breaches&lt;/li&gt;
&lt;li&gt;Add  testing and validation of  new Layer versions before deployment.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Best Practices for using Lambda Layers
&lt;/h2&gt;

&lt;p&gt;The following section describes the best practices that will help you get the most out of Lambda Layers.It is not everything belongs in a Layer. You should consider these guidelines as best practices   when you want to opt for layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You only use layers when you want to share dependencies  across multiple functions&lt;/li&gt;
&lt;li&gt;You have large libraries that would bloat your lambda function packages&lt;/li&gt;
&lt;li&gt;You want to use custom runtimes and some Organization-wide utilities&lt;/li&gt;
&lt;li&gt;Separating your function business logic from dependencies.&lt;/li&gt;
&lt;li&gt;Consider versioning  your lambda layers for  layer stability&lt;/li&gt;
&lt;li&gt;Ensure you regularly scan Layer dependencies for vulnerabilities, and also make sure to audit third-party packages before including them in your  Layers&lt;/li&gt;
&lt;li&gt;As much as possible, avoid including sensitive data or any  credentials in Layers&lt;/li&gt;
&lt;li&gt;Monitor and debug functions that use layers.
## Conclusion
AWS Lambda Layers represent  are a great tool that  lets you keep your function deployment packages small and organized by separating your function business logic code from its dependencies. This article dived deep into what lambda layers are, how to create and use layers and some advance concepts and best practices. 
## References and Additional Resources&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html" rel="noopener noreferrer"&gt;AWS Lambda Layers Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-sam-cli.html" rel="noopener noreferrer"&gt;AWS Serverless Application Model (SAM) Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://awslabs.github.io/aws-lambda-powertools-python/" rel="noopener noreferrer"&gt;AWS Lambda Power Tools&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.serverless.com/framework/docs/providers/aws/guide/layers" rel="noopener noreferrer"&gt;Serverless Framework Documentation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html" rel="noopener noreferrer"&gt;AWS Lambda Extensions API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html" rel="noopener noreferrer"&gt;Best practices for working with AWS Lambda functions&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;This blog post was last updated on May 21, 2025, and reflects the current Lambda Layers functionality as of that date.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>serverless</category>
      <category>lambda</category>
    </item>
    <item>
      <title>AWS Trust Policy Complete Guide: How to Control IAM Role Access in 2025</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Wed, 28 May 2025 09:16:43 +0000</pubDate>
      <link>https://forem.com/aws-builders/aws-trust-policy-complete-guide-how-to-control-iam-role-access-in-2025-cfi</link>
      <guid>https://forem.com/aws-builders/aws-trust-policy-complete-guide-how-to-control-iam-role-access-in-2025-cfi</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;What is AWS Trust Policy?&lt;/li&gt;
&lt;li&gt;&lt;a href="//#Trust-Policy-vs.-Permission-Policy"&gt;Trust Policy vs. Permission Policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;How trust Policy Works&lt;/li&gt;
&lt;li&gt;Common Use Cases of Trust Policies&lt;/li&gt;
&lt;li&gt;Best Practices for Trust Policies&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Most AWS architects and developers create and use IAM roles but do not understand how the permissions described in the policies attached to a role are assigned to principals. The permissions assigned to the principal are always temporary and short-lived. These short-lived credentials are generated by AWS Security Token Service (STS), but wait – what ensures that the right principals assume a role? In this article we will look at AWS Trust Policy, the security gatekeeper that ensures that the right principal can assume a role to perform its actions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is AWS Trust Policy?
&lt;/h2&gt;

&lt;p&gt;A trust policy is a type of AWS resource-policy that controls which principals and under which conditions can assume a role. Trust policy essentially enforces " who can wear this hat" and under what condition. You can think of trust policy as the "front door" to a role, before anyone can use the permissions define in the role, they must first pass a trust policy to verify their eligibility.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Basic Trust Policy Structure
&lt;/h3&gt;

&lt;p&gt;Just like AWS traditional policy document, a trust policy is made up of 3 main components,&lt;code&gt;statement&lt;/code&gt;, &lt;code&gt;Effect&lt;/code&gt; and &lt;code&gt;Action&lt;/code&gt;, but because this is a resource -based policy there is an additional component, the &lt;code&gt;Princpal&lt;/code&gt; that is required. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trust Policy Structure&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Service"&lt;/span&gt;: &lt;span class="s2"&gt;"ec2.amazonaws.com"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How trust Policy Works
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqx70x00xcyirfrndv18.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqx70x00xcyirfrndv18.png" alt="Trust policy works" width="800" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;First the principals, IAM user, AWS service or Federated Users (SAML/OIDC) will  request to assume a  role&lt;/li&gt;
&lt;li&gt;The trust policy will then evaluate the request based on,who is making the request, if there are any conditions specified and Whether if the actions are allowed. &lt;/li&gt;
&lt;li&gt;If the  request is comming from right principal who is allowed to assume the role and meets the conditions specified, the request is approved.&lt;/li&gt;
&lt;li&gt;If approved, the principal gets temporary credentials, Permission policies then control what actions the assumed role can perform on AWS resource&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Principal Types
&lt;/h3&gt;

&lt;p&gt;The principal component of a trust policy defines which principals can assume a role.  The table below summarizes the various types of principals that can be used with a trust policy. &lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Principal Type&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Use Case&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Service&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"Service": "lambda.amazonaws.com"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;AWS services assuming roles&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AWS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"AWS": "arn:aws:iam::123456789012:user/john"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IAM users, roles, or accounts&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Federated&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"Federated": "arn:aws:iam::123456789012:saml-provider/ExampleProvider"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Identity federation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Root&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;"AWS": "arn:aws:iam::123456789012:root"&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Entire AWS account&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Adding Conditions to Trust Policies
&lt;/h3&gt;

&lt;p&gt;It is possible to add conditions to a trust policy.  Conditions add extra security layers and it is best practice to use conditions in your trust plocies.&lt;br&gt;
&lt;strong&gt;EXAMPLE Require MFA&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"AWS"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:iam::123456789012:user/AdminUser"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Condition"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Bool"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"aws:MultiFactorAuthPresent"&lt;/span&gt;: &lt;span class="s2"&gt;"true"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;,
        &lt;span class="s2"&gt;"NumericLessThan"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"aws:MultiFactorAuthAge"&lt;/span&gt;: &lt;span class="s2"&gt;"3600"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;EXAMPLE Restrict by Source IP&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"AWS"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:iam::123456789012:user/RemoteUser"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Condition"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"IpAddress"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"aws:SourceIp"&lt;/span&gt;: &lt;span class="s2"&gt;"203.0.113.0/24"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Trust Policy vs. Permission Policy
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Trust Policy&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Permission Policy&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Controls &lt;strong&gt;who&lt;/strong&gt; can assume the role&lt;/td&gt;
&lt;td&gt;Controls &lt;strong&gt;what&lt;/strong&gt; the role can do&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Attached to the role itself&lt;/td&gt;
&lt;td&gt;Attached to the role or inherited&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Uses &lt;code&gt;sts:AssumeRole&lt;/code&gt; action&lt;/td&gt;
&lt;td&gt;Uses various AWS service actions&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Defines principals (who)&lt;/td&gt;
&lt;td&gt;Defines resources and actions (what)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Common Use Cases of Trust Policies
&lt;/h2&gt;

&lt;p&gt;Trust policies are fundamental to AWS security architecture and enable secure, temporary access patterns without sharing long-term credentials.&lt;br&gt;
&lt;strong&gt;Cross-account access:&lt;/strong&gt; Allow users in Account A to access resources in Account B&lt;br&gt;
&lt;strong&gt;Service roles:&lt;/strong&gt; Allow AWS services (like EC2, Lambda) to access other AWS resources&lt;br&gt;
&lt;strong&gt;Federation:&lt;/strong&gt; Enable users from external identity providers to access AWS resources&lt;br&gt;
&lt;strong&gt;Temporary access:&lt;/strong&gt; Grant time-limited access to external parties or contractors&lt;br&gt;
&lt;strong&gt;CI/CD pipelines:&lt;/strong&gt; Allow deployment tools to assume roles for automated deployments&lt;/p&gt;
&lt;h2&gt;
  
  
  Common Trust Policy Examples
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Allow EC2 Service to Assume Role&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Service"&lt;/span&gt;: &lt;span class="s2"&gt;"ec2.amazonaws.com"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Allow Specific AWS Account to Assume Role&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"AWS"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:iam::123456789012:root"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Allow Specific IAM User to Assume Role&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"AWS"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:iam::123456789012:user/DevOpsEngineer"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;4. Cross-Account Access with External ID&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"AWS"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:iam::987654321098:root"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRole"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Condition"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"StringEquals"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"sts:ExternalId"&lt;/span&gt;: &lt;span class="s2"&gt;"unique-external-id-12345"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;5. Web Identity Federation (for Mobile/Web Apps)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Federated"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:iam::123456789012:oidc-provider/accounts.google.com"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRoleWithWebIdentity"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Condition"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"StringEquals"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"accounts.google.com:aud"&lt;/span&gt;: &lt;span class="s2"&gt;"your-app-client-id"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;6. SAML Federation&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"Version"&lt;/span&gt;: &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;,
  &lt;span class="s2"&gt;"Statement"&lt;/span&gt;: &lt;span class="o"&gt;[&lt;/span&gt;
    &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"Effect"&lt;/span&gt;: &lt;span class="s2"&gt;"Allow"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Principal"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"Federated"&lt;/span&gt;: &lt;span class="s2"&gt;"arn:aws:iam::123456789012:oidc-provider/accounts.google.com"&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;,
      &lt;span class="s2"&gt;"Action"&lt;/span&gt;: &lt;span class="s2"&gt;"sts:AssumeRoleWithWebIdentity"&lt;/span&gt;,
      &lt;span class="s2"&gt;"Condition"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="s2"&gt;"StringEquals"&lt;/span&gt;: &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="s2"&gt;"accounts.google.com:aud"&lt;/span&gt;: &lt;span class="s2"&gt;"your-app-client-id"&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
      &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices for Trust Policies
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1.Principle of Least Privilege:&lt;/strong&gt; Only grant assume role permissions to entities that actually need them &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2.Use External IDs:&lt;/strong&gt; For third-party access to prevent confused deputy attacks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;3.Add Conditions:&lt;/strong&gt; Use conditions to restrict when and how roles can be assumed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;4.Regular Audits:&lt;/strong&gt; Periodically review who has permission to assume critical roles&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5.Avoid Wildcards:&lt;/strong&gt; Be specific about which principals can assume roles and avoid using the wildcard,&lt;code&gt;*&lt;/code&gt;. &lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;6.Monitor Usage:&lt;/strong&gt; Use CloudTrail to monitor role assumption activities&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Security is paramount when it comes to the cloud. In this article, we dive deep into one of the security features of AWS, AWS Trust Policy, which controls who can assume an IAM role. In my next article, we will examine the service that generates temporal and short-lived credentials, AWS Security Token Service (STS). Till then, it's a bye for now. Don't forget to add a  comment &lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/" rel="noopener noreferrer"&gt;https://aws.amazon.com/blogs/security/how-to-use-trust-policies-with-iam-roles/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_principal.html&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html" rel="noopener noreferrer"&gt;https://docs.aws.amazon.com/STS/latest/APIReference/welcome.html&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
    </item>
    <item>
      <title>Ultimate Guide to Using NGINX as a Reverse Proxy and Load Balancer:Best Practices and Tips</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Wed, 26 Feb 2025 16:06:43 +0000</pubDate>
      <link>https://forem.com/kodecapsule/ultimate-guide-to-using-nginx-as-a-reverse-proxy-and-load-balancerbest-practices-and-tips-2hfo</link>
      <guid>https://forem.com/kodecapsule/ultimate-guide-to-using-nginx-as-a-reverse-proxy-and-load-balancerbest-practices-and-tips-2hfo</guid>
      <description>&lt;h2&gt;
  
  
  What is NGINX and Why Use It?
&lt;/h2&gt;

&lt;p&gt;Nginx (pronounced "engine-X) is an open-source high-performance   HTTP web server that can also be used as a  reverse proxy. Other uses cases of nginx include Load Balancing, API Gateway,SSL/TLS Termination and Content caching. Over the years Nginx has grown to become one of the most popular and widely used webserver  for its high performance, scalability, and low resource usage. Some companies that use Nginx include Uber Netflix,Instagram,Airbnb etc. &lt;/p&gt;

&lt;p&gt;This article will demonstrate how to  configure and use  Nginx as a Reverse proxy and a Load Balancer. We will configure nginx as reverse proxy and load balancer to distribute traffic  between three django applications. Before we dive into the details of configuring nginx , lets first understand what reverse proxy and load balancer are. &lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding Reverse Proxy and Load Balancing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is a Reverse Proxy?&lt;/strong&gt;  A reverse proxy( proxy means to act on behalf ) is a special type of  server that sits in front of other  webservers and directs requests from clients (such as web browsers) to those servers. Reverse proxies are often used to improve security, performance, and dependability.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Load Balancing?&lt;/strong&gt;Load balancing is a technique  of distributing computational workloads between two or more computing nodes.  Load balancing is often employed to evenly distribute  network traffic among several servers. This reduces the strain on each server and makes the servers more efficient, speeding up performance and reducing latency.&lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up NGINX as a Reverse Proxy and Load Balancer
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt; &lt;br&gt;
 To follow this guide, you should have  &lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A Linux OS, preferably ubuntu. &lt;/li&gt;
&lt;li&gt;Basic knowledge of using the terminal.&lt;/li&gt;
&lt;li&gt;Docker Installed. The Official &lt;a href="https://docs.docker.com/engine/install/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt; will guide you through how to install Docker&lt;/li&gt;
&lt;li&gt;Nginx Installed . You can follow the official &lt;a href="https://nginx.org/en/docs/install.html" rel="noopener noreferrer"&gt;Documentation&lt;/a&gt; to install Nginx on your preferred OS.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 1 Setting up docker Containers&lt;/strong&gt;&lt;br&gt;
We will be setting up 3 docker Containers to server as the backend servers. &lt;br&gt;
The docker containers run will be running a django blog application.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;1. Create a directory on your computer for the project:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="s"&gt;mkdr projects/DjangoApps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;2. cd into the  directory you created
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="s"&gt;cd projects/Djangoapps&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;3. Create a docker-compose.yml file
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="s"&gt;touch docker-compose.yml&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;open the  docker-compose.yml file and past this code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;

&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;app1&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kodecapsule/django-blog-app:dark-server&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dark-server&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;

  &lt;span class="na"&gt;app2&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kodecapsule/django-blog-app:green-server&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;green-server&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8001:8000"&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;

  &lt;span class="na"&gt;app3&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;kodecapsule/django-blog-app:blue-server&lt;/span&gt;
    &lt;span class="na"&gt;container_name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;blue-server&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8002:8000"&lt;/span&gt;
    &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above  docker-compose.yml file setsup three Docker containers running different versions of the same Django blog application, &lt;br&gt;
each tagged with a different server name (dark-server, green-server, blue-server) from the Docker Hub repository kodecapsule/django-blog-app.&lt;br&gt;
Each container is mapped to a unique host port (8000, 8001, 8002) so they can be accessed individually, while internally all containers listen on port 8000. The restart: always policy ensures that the containers automatically restart if they fail or if the Docker service restarts.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;4. Run the docker containers
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="s"&gt;docker-compose up&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will  download and run three docker containers  dark-server, green-server and  blue-server.Open your browser and make sure you are able to access the three applications&lt;/p&gt;

&lt;p&gt;dark-server &lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqo1aghys1xkcldo2zmh3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqo1aghys1xkcldo2zmh3.png" alt="dark-server" width="800" height="469"&gt;&lt;/a&gt;. &lt;br&gt;
green-server&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Femgf7910h8wsr4uqrm4i.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Femgf7910h8wsr4uqrm4i.png" alt="green-server" width="800" height="473"&gt;&lt;/a&gt;. &lt;br&gt;
blue-server&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgb393qo6i8c6s5uqgek.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxgb393qo6i8c6s5uqgek.png" alt="blue-server" width="800" height="467"&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2 Configure  NGINX as a Reverse Proxy&lt;/strong&gt;&lt;br&gt;
Nginx configuration is  always in  nginx.conf file. The nginx.conf file is the main file that is mainly  used to  configure nginx behavior. &lt;br&gt;
By default this file is located in /etc/nginx/nginx.conf .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;  &lt;span class="k"&gt;worker_processes&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
  &lt;span class="k"&gt;events&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kn"&gt;worker_connections&lt;/span&gt; &lt;span class="mi"&gt;1024&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;http&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="kn"&gt;include&lt;/span&gt; &lt;span class="n"&gt;/etc/nginx/mime.types&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

      &lt;span class="kn"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;django_servers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
              &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
              &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8002&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;  

      &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kn"&gt;listen&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="c1"&gt;# Proxy requests to Django backend&lt;/span&gt;
        &lt;span class="kn"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://django_servers&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;Host&lt;/span&gt; &lt;span class="nv"&gt;$host&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Real-IP&lt;/span&gt; &lt;span class="nv"&gt;$remote_addr&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-For&lt;/span&gt; &lt;span class="nv"&gt;$proxy_add_x_forwarded_for&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_set_header&lt;/span&gt; &lt;span class="s"&gt;X-Forwarded-Proto&lt;/span&gt; &lt;span class="nv"&gt;$scheme&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

            &lt;span class="c1"&gt;# Handle timeouts&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_connect_timeout&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;proxy_read_timeout&lt;/span&gt; &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="p"&gt;}&lt;/span&gt;


  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The server context  defines all the configuration needed for nginx to act as a reverse proxy.The NGINX configuration above  defines a server with the  listen directive listening on port 8080. &lt;br&gt;
To configure Nginx as a reverse proxy the  proxy_pass directive is used which enables nginx to  forward all incoming requests to a group of backend Django servers. It sets headers like Host, X-Real-IP, &lt;br&gt;
and X-Forwarded-For to pass client information to the backend servers, preserving the original request details.&lt;/p&gt;

&lt;p&gt;Additionally, it configures timeout settings (connect and read) to control how long NGINX waits for a response from the backend servers, ensuring smooth handling of slow responses or potential server delays.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3 Configure  Nginx as a Load Balancer&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;configure nginx as load bala using round-robin&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;    &lt;span class="k"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;django_servers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
              &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
              &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
              &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8002&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; 

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The upstream block defines a load balancer named django_servers, which distributes incoming requests across the three Django application instances running on ports 8000, 8001, and 8002 on localhost.&lt;br&gt;
By default, NGINX uses a round-robin strategy, sending each new request to a different server in sequence to balance the load.&lt;br&gt;
This setup helps improve performance and reliability, as traffic is spread across multiple instances, preventing any single server from being overwhelmed.&lt;br&gt;
You can read more about &lt;a href="https://nginx.org/en/docs/http/load_balancing.html" rel="noopener noreferrer"&gt;Using nginx as HTTP load balancer&lt;/a&gt;&lt;br&gt;
Open your browser and enter localhost:8080. Reload several the site several time  to see how nginx is able to  route the traffic between the three servers.&lt;br&gt;
Other load balancing algorithms that can be used  are Weighted load balancing, Least connected load balancing,ip-hash&lt;/p&gt;
&lt;h2&gt;
  
  
  Common Errors and Troubleshooting
&lt;/h2&gt;

&lt;p&gt;Below are some list of some errors you are likely to face when &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🛑 1. NGINX Fails to Start or Reload&lt;/strong&gt;&lt;br&gt;
NGINX won't start or reload after changing the configuration. This is usually causee by Syntax or configuration errors in your nginx.conf&lt;br&gt;
solution: Run a config test to catch syntax errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="s"&gt;nginx -t&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there's an error, it will show the line and reason, like this&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt; &lt;span class="na"&gt;nginx&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;emerg&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;server"&lt;/span&gt; &lt;span class="s"&gt;directive is not allowed here in /etc/nginx/nginx.conf:34&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fix the error, then restart nginx:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="s"&gt;sudo systemctl restart nginx&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;📛 2. 502 Bad Gateway&lt;/strong&gt;&lt;br&gt;
The browser shows a 502 Bad Gateway error. This error occures when nginx can't reach the backend servers ( Django containers).&lt;br&gt;
Some common reasons maybe backend server(s)  down or misconfigured, incorrect proxy_pass address, port mismatches (e.g., app runs on port 8000, but NGINX tries 8001).&lt;br&gt;
solution:Check  and make sure the backend servers are running.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⏳ 3. 504 Gateway Timeout&lt;/strong&gt;&lt;br&gt;
If the browser shows a 504 Gateway Timeout error , the error might be due to backend server(s)&lt;br&gt;
takeing too long to respond, or NGINX can't establish a connection to the servers.&lt;br&gt;
This maybe due to slow application responses (e.g., long-running DB queries) or timeout values are too low.&lt;/p&gt;

&lt;p&gt;Solution:&lt;br&gt;
     Increase timeout settings in nginx.conf&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;  &lt;span class="k"&gt;proxy_connect_timeout&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;proxy_read_timeout&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;proxy_send_timeout&lt;/span&gt; &lt;span class="mi"&gt;120&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;🚩 4. Connection Refused&lt;/strong&gt;&lt;br&gt;
If you have connection refused in logs this may likely be due to the backend server not  accepting connections or is bound to the wrong address.&lt;/p&gt;

&lt;p&gt;Solution:&lt;br&gt;
    Ensure the app listens on the right IP:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;⚠️ 5. Load Balancer Not Distributing Traffic Properly&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you have only one server getting  all the traffic, or traffic doesn't balance as expected.This maybe due to the default round-robin behavior or  sticky sessions or caching issues.&lt;br&gt;
Solution:&lt;br&gt;
    Check and make sure  the you are using the right load balancing algorithm:&lt;/p&gt;

&lt;p&gt;Default round-robin behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;  &lt;span class="k"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;django_servers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8002&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Least Connections behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;  &lt;span class="k"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;django_servers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;least_conn&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8002&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;IP Hash behavior:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;  &lt;span class="k"&gt;upstream&lt;/span&gt; &lt;span class="s"&gt;django_servers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="kn"&gt;ip_hash&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="kn"&gt;server&lt;/span&gt; &lt;span class="nf"&gt;localhost&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="mi"&gt;8002&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion and Next Steps
&lt;/h2&gt;

&lt;p&gt;Nginx is a versatal webserver that  can be used as a reverse proxy and load balancer  for any web application.&lt;br&gt;
With Nginx's simple configuration and vast ecosystem, you'll have plenty of flexibility to adapt to your application's evolving needs.&lt;br&gt;
So, what's next? Explore how to configure nginx for  SSL/TLS termination connections, caching static content and other features of Nginx.&lt;/p&gt;

&lt;h2&gt;
  
  
  References and Additional Resources
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://nginx.org/" rel="noopener noreferrer"&gt;https://nginx.org/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://nginx.org/en/docs/http/load_balancing.html" rel="noopener noreferrer"&gt;https://nginx.org/en/docs/http/load_balancing.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Nginx" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Nginx&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.keycdn.com/support/nginx" rel="noopener noreferrer"&gt;https://www.keycdn.com/support/nginx&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Avoiding Playbook Failures:Techniques to Handle Errors in Ansible Like an Expert</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Tue, 18 Feb 2025 12:21:20 +0000</pubDate>
      <link>https://forem.com/kodecapsule/avoiding-playbook-failurestechniques-to-handle-errors-in-ansible-like-an-expert-1dgf</link>
      <guid>https://forem.com/kodecapsule/avoiding-playbook-failurestechniques-to-handle-errors-in-ansible-like-an-expert-1dgf</guid>
      <description>&lt;h2&gt;
  
  
  Article Outline
&lt;/h2&gt;

&lt;p&gt;1. Introduction&lt;br&gt;
2. Techniques  to Handling Errors in Ansible&lt;br&gt;
3. Breakdown of Error Handling in Ansible &lt;br&gt;
4. Error handling Best practices&lt;br&gt;
5. Conclusion &lt;br&gt;
6. References&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Introduction: Why Error Handling Matters in Ansible
&lt;/h2&gt;

&lt;p&gt;Ansible,  an open source  IT automation  tool used for configuration management, software provisioning and application deployment is &lt;br&gt;
widely  used among DevOps, Cloud and IT professionals. Ansible's main strengths are it's simplicity, agentless architecture and  ease of use  as compared to other tools in that domain. Despite  Ansible's strengths  unexpected failures can and will  occur   due to unreachable hosts, failed commands, or misconfiguration etc.If failures are not handled properly, these errors can disrupt entire deployments and  cause downtime.&lt;/p&gt;

&lt;p&gt;Writing  robust playbooks with proper error  handling in Ansible is essential to ensure reliability and resilience in your Ansible automation workflows.&lt;br&gt;
In this article I will take you through common techniques and methods that can assist you to properly handle errors in playbook&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Techniques  to Handling Errors in Ansible
&lt;/h2&gt;

&lt;p&gt;There are several techniques  for  handling errors in Ansible include using ignore_errors, failed_when ,block and rescue ,any_errors_fatal etc. In this section we dive into some of these techniques and methods and how and when to use each technique. &lt;/p&gt;
&lt;h4&gt;
  
  
  Ignoring Failed Commands: When Failure is Acceptable
&lt;/h4&gt;

&lt;p&gt;Ansible will stop executing the current  task and subsequent task(s) when it encounters an error and  will stop executing a playbook entirely when there is an error in one of the task. &lt;br&gt;
The "ignore_errors" directive  allows continues executing of subsequent task(s) despite the failure of a task. The ignore_errors directive only works when the task is able to run and returns a value as "failed". This can be useful in scenarios where certain failures are expected or do not impact the overall automation process. &lt;br&gt;
You can use   ignore_errors in situations where there are no non-critical tasks,  testing and debugging, checking for optional dependencies and Best-Effort Action. &lt;br&gt;
Bellow is an example of how to use ignore_errors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    - name: Restart Apache &lt;span class="o"&gt;(&lt;/span&gt;ignore failure&lt;span class="o"&gt;)&lt;/span&gt;
      ansible.builtin.service:
         name: apache2
         state: restarted
         ignore_errors: &lt;span class="nb"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Handling Unreachable Hosts.
&lt;/h4&gt;

&lt;p&gt;One other failure types  that can occur in playbooks is unreachable host. This failure usually occurs when Ansible cannot establish a connection with the host. Unreachable host errors  can be  due to network issues, incorrect SSH credentials, or a system/server being down. By default, Ansible will stop executing  the current task  and the  playbook on that host  if that host becomes unreachable. You can use ignore_unreachable  to handle  a task failure due to  host(s) instance being ‘UNREACHABLE. When you use the  "ignore_unreachable" directive, Ansible   ignores the task errors but continues to execute future tasks against the unreachable host.&lt;/p&gt;

&lt;p&gt;Usage of ignore_unreachable a task.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   - name: This executes, fails, and the failure is ignored
     ansible.builtin.command: /bin/true
     ignore_unreachable: &lt;span class="nb"&gt;true&lt;/span&gt;

  - name: This executes, fails, and ends the play &lt;span class="k"&gt;for &lt;/span&gt;this host
    ansible.builtin.command: /bin/true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage of ignore_unreachable in a  playbook&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;  - hosts: all
  ignore_unreachable: &lt;span class="nb"&gt;true
  &lt;/span&gt;tasks:
    - name: This executes, fails, and the failure is ignored
        ansible.builtin.command: /bin/true

    - name: This executes, fails, and ends the play &lt;span class="k"&gt;for &lt;/span&gt;this host
        ansible.builtin.command: /bin/true

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Handlers and Failure: Triggering the Right Actions
&lt;/h4&gt;

&lt;p&gt;In Ansible handlers are special type of tasks that only run when they are notified by another task. They are usually runned at the end of each play and normally used to Restart a service only on successful execution that service. If a task notifies a handler but the next  task fails in the that same play, by default the handler will not run  leaving the host in an unexpected state. To override this default behavior you can use the "force-handlers" directive either in a play or in the ansible.cfg file and Ansible  will forcefully  run all notified handlers. &lt;/p&gt;

&lt;p&gt;Usage of ignore_unreachable in a  playbook&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;- name: Demonstrate force_handlers
  hosts: webservers
  force_handlers: &lt;span class="nb"&gt;yes&lt;/span&gt;  &lt;span class="c"&gt;# Ensures handlers run even if a task fails&lt;/span&gt;
  tasks:
    - name: Deploy a web application
      ansible.builtin.command: /usr/local/bin/deploy_app.sh
      notify: Stop Web Service  &lt;span class="c"&gt;# Handler will be triggered&lt;/span&gt;

    - name: Simulate a failure
      ansible.builtin.command: /usr/local/bin/failing_task.sh
      ignore_errors: no  &lt;span class="c"&gt;# This will fail the playbook&lt;/span&gt;

  handlers:
    - name: Stop Web Service
      ansible.builtin.service:
        name: nginx
        state: stopped
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Defining Failure and Change: Controlling When a Task Fails
&lt;/h4&gt;

&lt;p&gt;There are some situations where you will want to explicitly trigger an error when certain conditions are met. &lt;br&gt;
In Ansible , a  task is considered failed when it returns a non-zero erro exit code but there are certain situations you may want to override this default behavoir. &lt;br&gt;
Ansible allows you to override this default behavoir by  defining  custom failure conditions for a task by using the "failed_when" directive.&lt;br&gt;&lt;br&gt;
The "failed_when" directive commonly  used for handling commands that return non-standard exit codes, conditional task failures based on some logic &lt;br&gt;
and preventing false failures in debugging and logging. As with all conditions in Ansible you can use the "failed_when" with "and" and "or"&lt;/p&gt;

&lt;p&gt;Handling Commands with Non-Standard Exit Codes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;- name: Run a script that exits with code 2 on success
  ansible.builtin.command: /usr/local/bin/custom_script.sh
  register: script_output
  failed_when: script_output.rc &lt;span class="o"&gt;!=&lt;/span&gt; 0 and script_output.rc &lt;span class="o"&gt;!=&lt;/span&gt; 2

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Handling Conditional task failures based on some logic&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;- name: Check available disk space
  ansible.builtin.shell: &lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; / | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'NR==2 {print $5}'&lt;/span&gt; | &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/%//'&lt;/span&gt;
  register: disk_usage
  failed_when: disk_usage.stdout | int &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 90
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Aborting a Play on All Hosts: When to Stop Everything
&lt;/h3&gt;

&lt;p&gt;In handling errors in Ansible playbooks there maybe some situations where  you may want to abort the play on all host or some number of host&lt;br&gt;
when there is a  failure on a single host. &lt;br&gt;
The "any_errors_fatal" and "max_fail_percentage" allows you to stop a playbook execution on all host or a number of host respectively. &lt;br&gt;
In critical deployments, you may want to stop everything immediately to prevent further issues, in this case you need to use "any_errors_fatal" &lt;br&gt;
in your playbook.&lt;/p&gt;

&lt;p&gt;Stopping Execution on All Hosts if a Critical Task Fails&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;- name: Configure firewall rules across servers
  hosts: all
  any_errors_fatal: &lt;span class="nb"&gt;true
  &lt;/span&gt;tasks:
    - name: Apply firewall rules
      ansible.builtin.iptables:
        chain: INPUT
        protocol: tcp
        destination_port: 22
        jump: ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code snippets above , if one server fails to apply the rules, the playbook stops execution for all servers to prevent security inconsistencies.&lt;/p&gt;

&lt;h4&gt;
  
  
  Controlling Errors with Blocks, Rescue, and Always
&lt;/h4&gt;

&lt;p&gt;Ansible blocks are used to group common tasks in a logical manner and  all tasks in a "block" inherit directives applied at the block level. &lt;br&gt;
Blocks offers ways to handle errors compared to the way exceptions are   handled in common programming languages. Blocks are used together&lt;br&gt;
with "rescue" and "always" to handle errors. Rescue block contains a list of task to run whenever a task in a block fails. The rescue block will &lt;br&gt;
only run when a task returns a "failed" state. Bad task definitions and unreachable hosts will not trigger the rescue block.&lt;br&gt;
Always block will run all the time no matter what the task status of the previous block is.&lt;br&gt;
when block,rescue and always blocks directives are used together , they offer   a structured way to handle complex task failures. &lt;/p&gt;

&lt;p&gt;Installing Nginx with Apache2 as a fallback&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    - name: Install web server with error handling
  hosts: all
  become: &lt;span class="nb"&gt;yes
  &lt;/span&gt;tasks:
    - name: Attempt to &lt;span class="nb"&gt;install &lt;/span&gt;Nginx with fallback to Apache
      block:
        - name: Install Nginx
          ansible.builtin.apt:
            name: nginx
            state: present
            update_cache: &lt;span class="nb"&gt;yes
          &lt;/span&gt;register: nginx_install_status

      rescue:
        - name: Log failure and &lt;span class="nb"&gt;install &lt;/span&gt;Apache2 instead
          ansible.builtin.debug:
            msg: &lt;span class="s2"&gt;"Failed to install Nginx, installing Apache2 instead."&lt;/span&gt;

        - name: Install Apache2
          ansible.builtin.apt:
            name: apache2
            state: present

      always:
        - name: Cleanup temporary files......
          ansible.builtin.file:
            path: /tmp/install_logs
            state: absent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Summary  of Error Handling in Ansible
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;strong&gt;Scenario&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Error Handling Method&lt;/strong&gt;&lt;/th&gt;
&lt;th&gt;&lt;strong&gt;Best Practice&lt;/strong&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Task fails but should not stop playbook&lt;/td&gt;
&lt;td&gt;ignore_errors: yes&lt;/td&gt;
&lt;td&gt;Use when failure is non-critical but log output for debugging.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Host is unreachable but should not affect others&lt;/td&gt;
&lt;td&gt;ignore_unreachable: yes&lt;/td&gt;
&lt;td&gt;Useful in large environments with occasional host failures.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Define custom failure conditions&lt;/td&gt;
&lt;td&gt;failed_when&lt;/td&gt;
&lt;td&gt;Use when command output doesn't align with default error codes.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Play should stop if any critical task fails&lt;/td&gt;
&lt;td&gt;any_errors_fatal: true&lt;/td&gt;
&lt;td&gt;Use for high-risk changes like database updates.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Catch task failure and attempt alternative action&lt;/td&gt;
&lt;td&gt;block, rescue, always&lt;/td&gt;
&lt;td&gt;Ensures graceful error handling with a fallback mechanism.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Prevent unnecessary task execution&lt;/td&gt;
&lt;td&gt;changed_when&lt;/td&gt;
&lt;td&gt;Avoids triggering handlers when no real changes occur.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  4.  Some Common Errors in Ansible Playbooks
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Syntax Errors: These occurs when there are some  erroneous YAML formatting or incorrect Ansible syntax.&lt;/li&gt;
&lt;li&gt;Module Errors:Caused by specific Ansible modules with incorrect parameters or incompatible versions of the same module..&lt;/li&gt;
&lt;li&gt;Connection Errors: Problems with SSH connections to distant hosts.ts. &lt;/li&gt;
&lt;li&gt;Resource Unavailability: A necessary resource is either missing or unavailable.&lt;/li&gt;
&lt;li&gt;Task Failures: Tasks may fail because they do not meet particular conditions or are executed in an inappropriate execution environment. . &lt;/li&gt;
&lt;li&gt;Variable Errors:  Variables that are undefined or wrongly declared, causing the process to fail. &lt;/li&gt;
&lt;li&gt;Dependency Errors: Errors caused by lacking dependencies between tasks, roles, or playbook. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  5.  Conclusion: Making Your Ansible Playbooks More Resilient
&lt;/h2&gt;

&lt;p&gt;Overall effective error handling in Ansible is very essential for building resilient and fault-tolerant automation workflows.&lt;br&gt;
  By using some directives like ignore_errors for non-critical failures, failed_when for custom conditions, and block/rescue/always for structured recovery etc you can ensure that your playbooks can  handle  errors without disrupting the entire deployment. &lt;br&gt;
  Thats all for now till we meet again on my next article its by for now. &lt;/p&gt;

&lt;h2&gt;
  
  
  6.  References: More Reading
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html" rel="noopener noreferrer"&gt;https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_handlers.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_error_handling.html" rel="noopener noreferrer"&gt;https://docs.ansible.com/ansible/latest/playbook_guide/playbooks_error_handling.html&lt;/a&gt;&lt;br&gt;
&lt;a href="https://medium.com/@vinoji2005/day-13-error-handling-in-playbooks-ensuring-robust-ansible-automation-%EF%B8%8F-2abb62cd52f9" rel="noopener noreferrer"&gt;https://medium.com/@vinoji2005/day-13-error-handling-in-playbooks-ensuring-robust-ansible-automation-%EF%B8%8F-2abb62cd52f9&lt;/a&gt;&lt;br&gt;
&lt;a href="https://spacelift.io/blog/ansible-handlers" rel="noopener noreferrer"&gt;https://spacelift.io/blog/ansible-handlers&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ansible</category>
      <category>devops</category>
      <category>cloudcomputing</category>
    </item>
    <item>
      <title>How I passed the AWS Solutions Architect Associate (SAA-C03) : Resources and my study strategies and Tips.</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Sun, 16 Feb 2025 20:05:40 +0000</pubDate>
      <link>https://forem.com/kodecapsule/how-i-passed-the-aws-solutions-architect-associate-saa-c03-resources-and-my-study-strategies-1jpk</link>
      <guid>https://forem.com/kodecapsule/how-i-passed-the-aws-solutions-architect-associate-saa-c03-resources-and-my-study-strategies-1jpk</guid>
      <description>&lt;p&gt;At the beginning of this year one of my goals was to become an AWS solutions architect (Associate). So earning the AWS Solutions Architect Associate certification was going to be significant achievement for me in helping me build and advance my career in cloud computing. Many organizations are increasingly migrating to the cloud and AWS continues to dominate in the market as one of the most sought-after platforms for cloud deployment. AWS certifications have become a standard for validating your AWS cloud skills.&lt;/p&gt;

&lt;p&gt;For me, the AWS Solutions Architect Associate exam was more than just earning a badge, it was an opportunity for me to deepen my understanding of AWS services and to prove my skills in designing scalable, cost effective and resilient solutions on AWS.&lt;/p&gt;

&lt;p&gt;In this article, I will share with you the resources and my study strategies and tips I used on my journey to becoming AWS certified. I hope my experience will serve as a guide for anyone aspiring to pass the AWS Solutions Architect Associate exam.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Understanding the Exam structure and Format&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;One of the most import things to consider when preparing for any exam not only SAA-C03 is to understand how the exam is structured and the areas which are covered in the exam. This gives you an idea on the areas to study and focus your attention on and prevents you from focusing and wasting your energy and resources that are not relevant.&lt;/p&gt;

&lt;p&gt;AWS has provided a detailed exam guide which explains the composition exam structure and the services that are covered by the SAA-C03 exams. The exam is mainly based on four domains:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Domain 1 Design Secure Architectures (30%)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Domain 2 Design Resilient Architectures (26%)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Domain 3 Design High-Performing Architectures (24%)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Domain 4 Design Cost-Optimized Architectures (20%)&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;I personally went through this guide most of the time to help me in the areas I should focus on in my preparation for the SAA-C03 exam. I suggest you use this as a guide in your exam preparation. More about this guide use this link, &lt;a href="https://d1.awsstatic.com/training-and-certification/docs-sa-assoc/AWS-Certified-Solutions-Architect-Associate_Exam-Guide.pdf" rel="noopener noreferrer"&gt;https://d1.awsstatic.com/training-and-certification/docs-sa-assoc/AWS-Certified-Solutions-Architect-Associate_Exam-Guide.pdf&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;My Study Plan and resources I used&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;The resources I used are of two types, paid and free.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Free Resources.&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Solutions architect -Knowledge Badge readiness path on AWS Skill Builder: AWS skill builder has some amazing course and this course is one of them. The course consists of 32 modules that helped me in my preparation journey. After completing the course, you will also receive a badge after passing a final test. &lt;a href="https://explore.skillbuilder.aws/learn/lp/1044/Solutions%2520Architect%2520-%2520Knowledge%2520Badge%2520Readiness%2520Path" rel="noopener noreferrer"&gt;https://explore.skillbuilder.aws/learn/lp/1044/Solutions%2520Architect%2520-%2520Knowledge%2520Badge%2520Readiness%2520Path&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AWS Certified Solutions Architect Associate Practice Questions Playlist on Youtube by Sthithapragna. This Playlist is one of the best resources for you to use practice for your exams. The playlist consists of 41 videos. Sthithapragna does an amazing job by explaining into details all the possible answers and some keywords that will help you in selecting the right answers. &lt;a href="https://www.youtube.com/watch?v=4Y6lDKCAGOQ&amp;amp;list=PL7GozF-qZ4KeQtVB9Nt_gXwDD0HvykrsD" rel="noopener noreferrer"&gt;https://www.youtube.com/watch?v=4Y6lDKCAGOQ&amp;amp;list=PL7GozF-qZ4KeQtVB9Nt_gXwDD0HvykrsD&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AWS documentation: AWS official documentations should be your go to resources whenever you need to read more about any service that you need deeper understanding on. I constantly and always refer to the documentation when I need clarification and deeper understanding on a particular topic or service.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;AWS Free tier Account: The AWS free tier account played an essential part in my learning journey. I use the free tier account for hands on experience. I practice build some projects and gained some hands on experience with using this account.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Paid Resources&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;I purchased Stephane Maarek’s course, Ultimate AWS Certified Solutions Architect Associate SAA-C03 on Udemy. Maarek’s is an awesome teacher and explains complex topics in simpler ways for you to understand. The material is continuously updated, and the content slides are available in PDF format. &lt;a href="https://www.udemy.com/course/aws-certified-solutions-architect-associate-saa-c03/?couponCode=KEEPLEARNING" rel="noopener noreferrer"&gt;https://www.udemy.com/course/aws-certified-solutions-architect-associate-saa-c03/?couponCode=KEEPLEARNING&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;I also purchase Practice Exams | AWS Certified Solutions Architect Associate by Stephane Maarek and Abhishek Singh. This practice exams helped me to identify the areas that I needed to focus on. This practice text also provides detailed explanation to all the answer options with links to AWS documentations for reference. &lt;a href="https://www.udemy.com/course/practice-exams-aws-certified-solutions-architect-associate/?couponCode=KEEPLEARNING" rel="noopener noreferrer"&gt;https://www.udemy.com/course/practice-exams-aws-certified-solutions-architect-associate/?couponCode=KEEPLEARNING&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;My key challenges and how I overcame them&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Preparing for the AWS Solutions Architect Associate exam wasn’t without some challenges and hurdles. Here’s a breakdown of some of the major challenges I faced during my preparation journey and the strategies I used to overcome those challenges.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Balancing Studies with Work and Personal Life: Managing studies alongside a full-time job and personal responsibilities was my main headache. With limited free hours during the day, I am often overwhelmed and exhausted during the day. To overcome this challenge, I had a dedicated study period in the evenings, microlearning during short breaks and on commutes to work.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Handling some knowledge gaps in AWS Services. While I had some exposure to AWS, there were some services that I had some knowledge gaps. I read detailed about some those services in AWS documentation, practice some hands-on exercise and re-watch some videos on Stephane Maarek’s course and Youtube.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Overcoming Exam Anxiety: Despite my extensive preparation, the possibility of failing the exam created anxiety, especially as the exam day got closer. Because of this anxiety I had to reschedule my exam twice. I overcame this anxiety by doing more practice and reinforcing my knowledge on some concepts.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;As I reflect and look back on my journey to becoming an AWS Certified Solutions Architect Associate, I realise how much it has transformed me. It wasn’t just about passing exam but it was also about learning more about AWS services, getting better at using them, and feeling more confident about designing secure, cost effective, resilient and scalable solutions on AWS.&lt;/p&gt;

&lt;p&gt;I strongly recommend anyone who is willing to taking the AWS Solutions Architect Associate exam to do so. While the journey demands much efforts and dedication, the benefits greatly exceed the challenges. This certification will help you in advancing your career in cloud computing and validating your cloud skills.&lt;/p&gt;

&lt;p&gt;I hope this was helpful. Good luck on your certification journey.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>cloudcomputing</category>
      <category>softwaredevelopment</category>
    </item>
    <item>
      <title>The Ultimate guide to creating and using Terraform modules: Deploying a static Website Using Amazon S3</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Fri, 14 Feb 2025 07:39:39 +0000</pubDate>
      <link>https://forem.com/kodecapsule/the-ultimate-guide-to-creating-and-using-terraform-modules-deploying-a-static-website-using-4hc8</link>
      <guid>https://forem.com/kodecapsule/the-ultimate-guide-to-creating-and-using-terraform-modules-deploying-a-static-website-using-4hc8</guid>
      <description>&lt;h2&gt;
  
  
  Article Outline
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt; Introduction&lt;/li&gt;
&lt;li&gt; Prerequisites&lt;/li&gt;
&lt;li&gt; What are Terraform Modules?&lt;/li&gt;
&lt;li&gt; Anatomy of a Terraform Module&lt;/li&gt;
&lt;li&gt; Creating a Terraform Module (Step-by-Step)&lt;/li&gt;
&lt;li&gt; Using a Terraform Module&lt;/li&gt;
&lt;li&gt; Upload static  files to S3.&lt;/li&gt;
&lt;li&gt; Best Practices for Terraform Modules&lt;/li&gt;
&lt;li&gt; Conclusion&lt;/li&gt;
&lt;/ol&gt;

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

&lt;p&gt;Terraform, an open-source tool developed by  HashiCorp and  one of the most popular , if not the most popular IaC tool  is widely used  by Cloud and  DevOps engineers. As compared to other IaC tools, terraform is widely used because it is Platform Agnostic, employs a declarative language (HashiCorp Configuration Language (HCL)) , terraform is also allows for infrastructure to be modularized enabling reusable code and keeping your code DRY(Don't Repeat Yourself). Terrafrom also has an  large community and  ecosystem. &lt;/p&gt;

&lt;p&gt;As your terraform code becomes more complex, it becames difficlut to manage and that is where Terraform modules comes to the rescue. Modules are the key ingredient to writing reusable,maintainable, and testable Terraform code&lt;/p&gt;

&lt;p&gt;In this article, i will take you through how to write reuseable  modules in terraform. if you are ready grap a cap of coffe and lets get started. &lt;/p&gt;

&lt;h2&gt;
  
  
  2. Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you get started make sure you have the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Basic understanding of Terraform.&lt;/li&gt;
&lt;li&gt;AWS account with AWS CLI installed and configured&lt;/li&gt;
&lt;li&gt;Terraform Installed  CLI.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  3. What are Terraform Modules?
&lt;/h2&gt;

&lt;p&gt;HashiCorp defines modules as a container for multiple resources that are used together.In simple terms , a Terraform module is a list of terraform configuration files in a single diretory. Terraform module is analogous to a function in general-purpose programming constracts, they have parameters(input variables) and return values (output values). A module can be as simple as a directory with one or more confiuration files.tf files. For example you can define a resuable VPC module which might include subnets, route tables and security groups.  &lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of using modules
&lt;/h3&gt;

&lt;p&gt;Here are some benefits of using Modules in terraform:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Code Reusability: Modules makes it easier to reuse configurations written either by yourself, your team members, or other Terraform practitioners.&lt;/li&gt;
&lt;li&gt;Encapsulation of Configuration: Modules enables you to  encapsulate configurations into distinct logical components which can help prevent unintended changes to your infrastructure as a result of a change in one part of your infrastructure. &lt;/li&gt;
&lt;li&gt;Provide consistency and ensure best practices - Modules also help to provide consistency in your configurations&lt;/li&gt;
&lt;li&gt;Organize configuration - Modules make it easier to navigate, understand, and update your configuration by keeping related parts of your configuration together. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  4. Anatomy of a Terraform Module
&lt;/h2&gt;

&lt;p&gt;The file structure of a terraform module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;    module_name/
            ├── LICENSE
            ├── main.tf
            ├── variables.tf
            ├── outputs.tf
            └── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;LICENSE: Contains the license under which your module will be distributed&lt;/li&gt;
&lt;li&gt;main.tf: This file contains all the main configurations for your module&lt;/li&gt;
&lt;li&gt;variables.tf: This is where you place all the variable definitions for your module. When your module is used by others, the variables will be configured as arguments in the module block.&lt;/li&gt;
&lt;li&gt;outputs.tf: The outputs definition for your module is placed in this file. Module outputs are made available to the configuration using the module.&lt;/li&gt;
&lt;li&gt;README.md: This is a markdown file  that describes how to use your module. This file is not used by terraform but helps people understand how to use your module.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  5. Creating a Terraform Module (Step-by-Step)
&lt;/h2&gt;

&lt;p&gt;In this section of the article we will be creating a terraform module that  creates an  S3 bucket for hosting a static website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1. Clone/Create the directory structure&lt;/strong&gt;&lt;br&gt;
You can clone this directory  into your prefered location: Below is the  folder structure&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terrform-modules/
├──modules/
│     └──static-S3-Website-bucket/
│         ├── main.tf              
│         ├── variables.tf        
│         ├── outputs.tf
│         ├── README.md   
│         ├── www/  
│         │   ├──index.html
│         │   └── error.html
│         └── LICENSE
├── .gitignore     
├── main.tf 
├── Readme.md   
└── outputs.tf   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2. writing the modules variables&lt;/strong&gt;&lt;br&gt;
There are only two variables used in this module for simplicity. You can  modify  and add your own variables if you want.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;s3-bucket-name variable: The name to assign to your S3 bucket. The bucket name should be globally unique&lt;/li&gt;
&lt;li&gt;tags variable: Defines a tag for your bucket, defualts to Dev if you do not provide.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"s3-bucket-name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Bucket name for the static website. The name must be globally uique "&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;string&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nx"&gt;variable&lt;/span&gt; &lt;span class="s2"&gt;"tags"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Tags to set on the bucket."&lt;/span&gt;
    &lt;span class="nx"&gt;type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;string&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;default&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="s2"&gt;"env"&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dev"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Step 3. writing the main configuration&lt;/strong&gt;&lt;br&gt;
This file creates all the resources that are needed to create a static S3 website. There are 6 resources in all&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;"aws_s3_bucket" resource: Creates an S3 bucket with the name and tag you provide as input variables&lt;/li&gt;
&lt;li&gt;"aws_s3_bucket_website_configuration" resource: Configures your S3 bucket for static website hosting&lt;/li&gt;
&lt;li&gt;"aws_s3_bucket_ownership_controls" resource: Configures  S3 Bucket Ownership Controls&lt;/li&gt;
&lt;li&gt;"aws_s3_bucket_public_access_block" resource: Enable public access&lt;/li&gt;
&lt;li&gt;"aws_s3_bucket_acl" resource: Defines S3 access control list (ACLs)&lt;/li&gt;
&lt;li&gt;"aws_s3_bucket_policy" resource: Configures S3 bucket policy
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"static-website-bucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3-bucket-name&lt;/span&gt;
    &lt;span class="nx"&gt;force_destroy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;var&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tags&lt;/span&gt;  
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_website_configuration"&lt;/span&gt; &lt;span class="s2"&gt;"s3-website-config"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="nx"&gt;index_document&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;suffix&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"index.html"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;error_document&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"error.html"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt; 

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_ownership_controls"&lt;/span&gt; &lt;span class="s2"&gt;"bucket-owner"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
  &lt;span class="nx"&gt;rule&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;object_ownership&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"BucketOwnerPreferred"&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;aws_s3_bucket_public_access_block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public-acl-block&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_public_access_block"&lt;/span&gt; &lt;span class="s2"&gt;"public-acl-block"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;  

  &lt;span class="nx"&gt;block_public_acls&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;block_public_policy&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;ignore_public_acls&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;restrict_public_buckets&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;  

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_acl"&lt;/span&gt; &lt;span class="s2"&gt;"s3-website-bucket-acl"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="nx"&gt;acl&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"public-read"&lt;/span&gt;  
  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket_ownership_controls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket-owner&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket_policy"&lt;/span&gt; &lt;span class="s2"&gt;"s3-website-bucket-policy"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;
    &lt;span class="nx"&gt;policy&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;jsonencode&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="nx"&gt;Version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"2012-10-17"&lt;/span&gt;
    &lt;span class="nx"&gt;Statement&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;Sid&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"PublicReadGetObject"&lt;/span&gt;
        &lt;span class="nx"&gt;Effect&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Allow"&lt;/span&gt;
        &lt;span class="nx"&gt;Principal&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"*"&lt;/span&gt;
        &lt;span class="nx"&gt;Action&lt;/span&gt;    &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"*"&lt;/span&gt;
        &lt;span class="nx"&gt;Resource&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="s2"&gt;"${aws_s3_bucket.static-website-bucket.arn}/*"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;


  &lt;span class="nx"&gt;depends_on&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket_public_access_block&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;public-acl-block&lt;/span&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Step 4. writing the outputs configuration file&lt;/strong&gt;&lt;br&gt;
The output file  defines three outputs for the S3 bucket module:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;bucket's ARN&lt;/li&gt;
&lt;li&gt;website domain&lt;/li&gt;
&lt;li&gt;bucket id
These outputs allow other configurations to reference key attributes of the static S3 website bucket after it's provisioned.
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"bucket-arn"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ARN for the S3 bucket static website"&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;arn&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"bucket-id"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Id of the static S3 bu;cket"&lt;/span&gt;
    &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;

&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"website-domian"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Domain for the static Website"&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;aws_s3_bucket_website_configuration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;s3-website-config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;website_domain&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Step 5. writing the Readme and License files&lt;/strong&gt;&lt;br&gt;
For the README file a dettailed description of how to use the module is proivded. A sample Licence is also provided in the LICENSE file. You can generate your own licencse file using &lt;a href="https://choosealicense.com/" rel="noopener noreferrer"&gt;Choose a License&lt;/a&gt; &lt;/p&gt;
&lt;h2&gt;
  
  
  6 Using a Terraform Module.
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1. Define the module block&lt;/strong&gt;&lt;br&gt;
To use the module you need to use the module block in the main.tf file  that is at  the root directory and provide the required input variables. &lt;br&gt;
The root module also contains the configurations for  terraform and AWS provider. &lt;/p&gt;

&lt;p&gt;module block usage&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"static-S3-Website-bucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./modules/static-S3-Website-bucket"&lt;/span&gt;
    &lt;span class="nx"&gt;s3-bucket-name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"kodecapsule-website-101"&lt;/span&gt;

    &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;Environment&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"DEV"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Terraform and AWS provider configurations&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;
&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 4.16"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.2.0"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combined configurations&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;
&lt;span class="nx"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"~&amp;gt; 4.16"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;required_version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&amp;gt;= 1.2.0"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;region&lt;/span&gt;  &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"us-east-1"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;


&lt;span class="nx"&gt;module&lt;/span&gt; &lt;span class="s2"&gt;"static-S3-Website-bucket"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"./modules/static-S3-Website-bucket"&lt;/span&gt;
    &lt;span class="nx"&gt;s3-bucket-name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"kodecapsule-website-101"&lt;/span&gt;

    &lt;span class="nx"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;Environment&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="s2"&gt;"DEV"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2. writing the outputs configuration file&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight hcl"&gt;&lt;code&gt;&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"website_bucket_arn"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ARN of the bucket"&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-S3-Website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket-arn&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"website_bucket_name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Name (id) of the bucket"&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-S3-Website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket-id&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"website_bucket_domain"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;description&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Domain name of the bucket"&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;static-S3-Website-bucket&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;website-domian&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 3. Running the code&lt;/strong&gt;&lt;br&gt;
To run the code use the following commands&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;terraform init will initialize the project and download the neccessory provider code
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;terraform plan  to preview the changes that Terraform will make to your infrastructure
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform plan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ol&gt;
&lt;li&gt;The terraform apply command is used to apply the changes defined in your Terraform configuration files
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;terraform apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  7 Upload static  files to S3.
&lt;/h2&gt;

&lt;p&gt;After terraform creates the  infrastructure , you can now upload your static files into the S3 bucket.&lt;br&gt;
The static files for this peoject are found in the www folder. &lt;br&gt;
You can upload the files using AWS console or AWS CLI.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1.Uploading static files using AWS CLI&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aws s3 &lt;span class="nb"&gt;cp &lt;/span&gt;modules/static-S3-Website-bucket/www/ s3://&amp;lt;YOUR-BUCKET-NAME&amp;gt;/ &lt;span class="nt"&gt;--recursive&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;replace  with the name of your bucket&lt;/p&gt;

&lt;h2&gt;
  
  
  8. Best Practices for Terraform Modules
&lt;/h2&gt;

&lt;p&gt;Here are some best practices to follow when writing and using modules.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Always parameterize your modules. &lt;/li&gt;
&lt;li&gt;Follow the "DRY" Principle (Don’t Repeat Yourself)&lt;/li&gt;
&lt;li&gt;Write Documentation for your Modules &lt;/li&gt;
&lt;li&gt;Avoid hardcoding sensitive data (e.g., keys, passwords) in your module variables. &lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  9. Conclusion
&lt;/h2&gt;

&lt;p&gt;Well well, we have come to the end of this deep dive into terraform modules. There are other advance topics about terraform modules that are not covered in this tutorial. To learn more about terrafrom modules , visit the official &lt;a href="https://developer.hashicorp.com/terraform/language/modules" rel="noopener noreferrer"&gt;Terraform page&lt;/a&gt;  . Don't forget to add your comments , till then keep coding. &lt;/p&gt;

&lt;p&gt;Thanks&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>cloudcomputing</category>
      <category>aws</category>
    </item>
    <item>
      <title>Terraform Architecture Explained , Terraform Core, State, and Plugins: How Terraform Works Under the Hood.</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Fri, 14 Feb 2025 07:18:35 +0000</pubDate>
      <link>https://forem.com/kodecapsule/terraform-architecture-explained-terraform-core-state-and-plugins-how-terraform-works-under-3h0p</link>
      <guid>https://forem.com/kodecapsule/terraform-architecture-explained-terraform-core-state-and-plugins-how-terraform-works-under-3h0p</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Article Outline&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Introduction&lt;/li&gt;
&lt;li&gt;Terraform Architecture&lt;/li&gt;
&lt;li&gt;Terraform Workflow&lt;/li&gt;
&lt;li&gt;Terraform Best Practices&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;li&gt;References&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;1. Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Infrastructure as Code (IaC), is an approach to managing and provisioning infrastructure by writing code instead of the manual processes , “ClickOps”. IaC can be described as a mindset where you treat all aspects of operations (servers, databases, networks) as software. When you define your infrastructure using code , it enables you to automate and use all the best practices of software development. IaC eliminates human errors , speeds up infrastructure deployments and ensures infrastructure is version-controlled, just like software code.&lt;/p&gt;

&lt;p&gt;Terraform is an open-source tool developed by HashiCorp and the most popular and widely used IaC tool used by DevOps, SREs and cloud architects. Terraform is widely used because of it’s declarative syntax, platform agnostic and its simplicity. Understanding how terraform works behind the hood will go along way to help you in write better terraform code.&lt;/p&gt;

&lt;p&gt;In this article, we will explore Terraform architecture, its core components, and how it orchestrates infrastructure provisioning efficiently.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;2. Terraform Architecture&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmzow5nerjk3pfprpya0o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmzow5nerjk3pfprpya0o.gif" alt="Terraform Achitecture" width="760" height="475"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Terraform follows a standard architecture to fulfill the necessary IaC tasks. Terraform architecture mainly consists of the following components:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Terraform core&lt;/li&gt;
&lt;li&gt;Plugins (Providers and Provisioners)&lt;/li&gt;
&lt;li&gt;Terraform State&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Terraform core
&lt;/h3&gt;

&lt;p&gt;Terraform core is the engine/brain behind how terraform works. It is responsible for reading configurations files , building the dependency graphs from resources and data sources, managing state and applying changes. Terraform Core does not directly interact with cloud providers but communicates with plugins via remote procedure calls (RPCs) and the plugins in turn communicates with their corresponding platforms via HTTPs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plugins (Providers and Provisioners)
&lt;/h3&gt;

&lt;p&gt;Terraform ability is enhance by plugins, which enable terraform to interact with cloud services and configure resources dynamically. Plugins acts as connectors or the glue between terraform and external APIs such as AWS, Azure, GCP, Kubernetes, Docker etc. Each plugin is written in the Go programming language and implements a specific interface. Terraform core knows how to install and execute plugins. Provisioners in Terraform are used to execute scripts or commands on a resource after it has been created or modified.&lt;/p&gt;

&lt;h3&gt;
  
  
  Terraform State
&lt;/h3&gt;

&lt;p&gt;State is one of the most important core components of Terraform. Terraform state is a record about all the infrastructure and resources it created. It is a costumed JSON file that terraform uses to map real world resources to your configuration, keep track of metadata, and to improve performance for large infrastructures. By default, state is stored in a local file named “terraform.tfstate”. You can read more about terraform state here&lt;/p&gt;

&lt;p&gt;There are two ways to manage state:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Local State: Local State refers to the default way by which Terraform stores state files (terraform.tfstate). It is suitable for small-scale projects or development environments and single person managing Terraform.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Remote State: Remote State refers to storing the Terraform state file (terraform.tfstate) in a remote backend rather than locally on your machine. This enables collaboration, prevents state loss, and supports features like state locking and versioning. Some common remote backends include AWS S3,Terraform Cloud, Azure Blob Storage etc. More on &lt;a href="https://developer.hashicorp.com/terraform/language/state/remote" rel="noopener noreferrer"&gt;Remote State&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;3. Terraform Workflow&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Terraform follows a structured execution flow to provision, update, and manage infrastructure. This process ensures that infrastructure is deployed in a controlled and predictable manner. Terraform workflow consist of mainly three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Write: The first step is to write your terraform configuration just like any other code using any editor of your choice.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Plan: This is the step where you review your configurations. Terraform plan will define the infrastructure to be created, modified, or destroyed depending on the current configuration and infrastructure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Apply: The final step in the workflow is Apply, where you are ready to provision real infrastructure. Once you approve of the changes ,terraform will go ahead perform the desired actions as defined execution.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;4. Terraform Best Practices&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You should never edit the Terraform state files by hand or write code that reads them directly. If for some reason you need to manipulate the state file which should be a relatively rare occurrence, use the terraform import or terraform state commands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It’s a good practice to store your work in a version controlled repository even when you’re just operating as an individual.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;When working as a team, it’s important to delegate ownership of infrastructure across these teams and empower them to work in parallel without conflicts.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Never Store your state file in a version controlled repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Always use state locking on your state files to prevent data loss, conflicts and state file corruption.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integrate Terraform to your CI/CD pipelines to make your DevOps pipeline efficient.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  5. Conclusion
&lt;/h2&gt;

&lt;p&gt;Well well, we have come to the end of this deep dive into terraform Architecture. &lt;br&gt;
To learn more about Terrafrom  visit the official &lt;a href="https://developer.hashicorp.com/terraform/language/modules" rel="noopener noreferrer"&gt;Terraform page&lt;/a&gt;  . Don't forget to add your comments , till then keep coding. &lt;br&gt;
.&lt;/p&gt;

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

&lt;ol&gt;
&lt;li&gt; &lt;a href="https://developer.hashicorp.com/terraform/language/state" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/terraform/language/state&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt; &lt;a href="https://thinksys.com/cloud/terraform-architecture-best-practices/" rel="noopener noreferrer"&gt;https://thinksys.com/cloud/terraform-architecture-best-practices/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/intro/core-workflow" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/terraform/intro/core-workflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://spacelift.io/blog/terraform-architecture" rel="noopener noreferrer"&gt;https://spacelift.io/blog/terraform-architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/cloud-docs/recommended-practices" rel="noopener noreferrer"&gt;https://developer.hashicorp.com/terraform/cloud-docs/recommended-practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Terraform:Up &amp;amp; Running , Third Edition by Yevgeniy Brikman&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>devops</category>
      <category>terraform</category>
      <category>cloudcomputing</category>
      <category>aws</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Django Web Framework: Creating Apps, Views, Configuring URLs and Templates</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Mon, 05 Aug 2024 08:49:50 +0000</pubDate>
      <link>https://forem.com/kodecapsule/a-beginners-guide-to-django-web-framework-creating-apps-views-configuring-urls-and-templates-2ak</link>
      <guid>https://forem.com/kodecapsule/a-beginners-guide-to-django-web-framework-creating-apps-views-configuring-urls-and-templates-2ak</guid>
      <description>&lt;p&gt;Building Web Applications with Django ,A Practical Guide.🏗️ 🚀🐍🌐&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capsule 2&lt;/strong&gt;: Creating Apps ,Views, templates and configuring route&lt;/p&gt;

&lt;p&gt;Greetings comrades Welcome back to our Django tutorial series! it’s another week and we need to take our KodeCapsule of the week. In the previous article we, covered the foundations of Django framework, it’s architecture, Models, Views, templates and how to start a new project in Django. If you have not read the last article I suggest you go back and read that article, here before continuing. So, grab a cap of coffee and let’s dive in.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Outline of Article&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Introduction&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is an app in Django?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating an App in Django&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating Views for your App&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Creating URLs for your app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Adding templates to your app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conclusion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;In this tutorial we will dive deep into building and working with the core components of any Django project. We will look at how to create apps in Django, configuring settings, creating views to handle request and setting up URL routes. By the end of this tutorial, you should understand&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;How to create a new app in Django&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to include this app in your project’s settings&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to define URL patterns for your app&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to write views to display request and response&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;How to add templates to your app&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s Get Started!!!!!!!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is an App in Django?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;An app in django is a module that performs a specific function. An app can be as simple as a feature in your project like a contact form or a fully-fledged component such as a blog or a payment system. Apps are designed to be reusable across different projects. Organizing your code into apps enable code reusability, maintainability and scalability. The difference between an app and a project is that, an app does a specific function in your project and can be used in multiple projects but a project consists of a collection of configurations, apps for a particular website. Some key characteristics of an app are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Modularity: Django Apps are modular in nature which means that you can develop and test your apps independently and reuse them. This makes your project more organized and manageable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Reusability: Since apps are self-contained, you can easily reuse them in other Django projects. For example, you can create a blog app for one project and use the same app in another project without modifications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Separation of Concerns: Each app handles a specific aspect of your project. This separation makes it easier to manage different parts of your application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Encapsulation: Apps encapsulate models, views, templates, static files, and other components related to a specific functionality, keeping them organized within their own directories.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Creating an App in Django
&lt;/h2&gt;

&lt;p&gt;In the previous article we have already setup our project. We will create our first app. This app is going to be a blog application.&lt;/p&gt;

&lt;p&gt;1.To create the app, navigate into your project folder and in your terminal and run this command. Make sure you have activated your virtual environment.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python manage.py startapp blog&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This command creates a new directory with all the necessary setup files in a folder structure described below:&lt;/p&gt;

&lt;p&gt;├── blog/&lt;br&gt;
│ ├── migrations/&lt;br&gt;
│ │ └──&lt;strong&gt;init&lt;/strong&gt;.py&lt;br&gt;
│ ├── &lt;strong&gt;init&lt;/strong&gt;.py&lt;br&gt;
│ ├── admin.py&lt;br&gt;
│ ├── apps.py&lt;br&gt;
│ ├── models.py&lt;br&gt;
│ ├── tests.py&lt;br&gt;
│ └── views.py&lt;/p&gt;

&lt;p&gt;I. migrations/: This folder stores all the database migrations for your app&lt;/p&gt;

&lt;p&gt;II. &lt;strong&gt;init&lt;/strong&gt;.py: This is an empty file that informs python to treat that directory as a python package.&lt;/p&gt;

&lt;p&gt;III. admin.py: A configuration files for django admin interface. The function of admin.py file is to register your apps models in the django admin panel. We will look at Django admin later&lt;/p&gt;

&lt;p&gt;IV. apps.py: This contains configurations for the app and can include the app’s metadata as well.&lt;/p&gt;

&lt;p&gt;V. models.py: This script is where we fine the data models for our app.&lt;/p&gt;

&lt;p&gt;VI. tests.py: The test.py script is where you write test cases for your app&lt;/p&gt;

&lt;p&gt;VII. views.py: This script contains the views you define for your app. The views handle the business logic for your application.&lt;/p&gt;

&lt;p&gt;2.Add your blog app into the list of installed apps in the project settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INSTALLED_APPS = [ 'django.contrib.admin', 
'django.contrib.auth', 
'django.contrib.contenttypes', 
'django.contrib.sessions', 
'django.contrib.messages', 
'django.contrib.staticfiles', 

#my apps
'blog',
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating Views
&lt;/h2&gt;

&lt;p&gt;Views play an important role in your application. The business logic for your application is defined in Views. Views act as the glue between the presentation layer and the data layer. There are two main types of views in Django, Function-based views and Class-based views (more details about this in the upcoming articles). In this tutorial we will stick to using function-based views.&lt;/p&gt;

&lt;p&gt;1.Open the views.py file in your blog app&lt;/p&gt;

&lt;p&gt;2.Import HttpResponse from the http package&lt;/p&gt;

&lt;p&gt;&lt;code&gt;from django.http import HttpResponse&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3.Define a function called home (you can name the function whatever you want). The function will return an HttpResponse&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django.http import HttpResponse

 def home(request):
      return HttpResponse("&amp;lt;h1&amp;gt;Welcome to the Home Page&amp;lt;/h1&amp;gt;")
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;strong&gt;Creating URLs for your App&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;For users to access different sections of your web app, you have to define access points for each feature/functionality of your app; in Django you do so by creating urls for your app. URLs patterns are mapped to specific views.&lt;/p&gt;

&lt;p&gt;In Django, you can define all the urls for your project in the project urls.py script, but it is best practice to create a separate urls.py script for individual apps in your project.&lt;/p&gt;

&lt;p&gt;1.In the blog app directory create a urls.py script.&lt;/p&gt;

&lt;p&gt;2.Import the path function from the urls package in django. The path function takes three arguments, route, view, kwargs and name and returns an element. You can read more about this function here.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;from django.urls import path&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3.Import the views for your app&lt;/p&gt;

&lt;p&gt;&lt;code&gt;from . import views&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;4.Create a list called urlpatterns an define a url for the home page, this list is similar to the list in the project urlpatterns.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;urlpatterns = [ path('', views.home, name='home_page' ]&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;5.Update the project’s urls. To make your app accessible you need to update the main project urls.py . Open your project’s urls.py file and import the include function from urls package and update the urlpatterns list.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; from django.contrib import admin
 from django.urls import path, include

 urlpatterns = [
     path('admin/', admin.site.urls),
    path('', include('blog.urls')),
   ]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;6.After that save all your files and start the development server, using the usual command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python manage.py runserver&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open the url in your browser and the default django home page changes the response from the home function. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflh31c1bkhmey0bvzuuk.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fflh31c1bkhmey0bvzuuk.PNG" alt=" " width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding templates to your App
&lt;/h2&gt;

&lt;p&gt;In the previous section the repose from the home view return an http response that contains an HTML header tag. What if we want to return a whole page that contains a whole lot of HTML tags, what can we do? That’s where templates in django come in. Django templates allows you to define the HTML structure that will be displayed in the user's browser. Templates allow you to generate dynamic content using the Django Templating Language (DTL). In Django you put your templates in your app or at the root of your application( more details about django templates in my upcoming articles). &lt;/p&gt;

&lt;p&gt;1.Create a template directory: create a template directory in your blog app. In the template directory create another directory called blog. &lt;br&gt;
2.Create a template. Create and HTML file called&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;myproject/
    blog/
        templates/
            blog/
                index.html 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;3.Update the index.html  file with this code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;meta charset="UTF-8" /&amp;gt;
&amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
&amp;lt;title&amp;gt;Blog App&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
 &amp;lt;h1&amp;gt;Welcome to the Home page&amp;lt;/h1&amp;gt;
 &amp;lt;p&amp;gt;Lorem ipsum dolor, sit amet consectetur adipisicing elit. Voluptas maiores, modi facilis veritatis amet eum labore odio sit nemo eius?&amp;lt;/p&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;4.Update the home view: Open your views file and import render from shortcuts. Update the function body to return the index.html using the render function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;from django.shortcuts import render
def home(request):
   return render(request, 'blog/index.html')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save the changes  and reload  your browser. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc52vdm21mjklzpyjjvp8.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc52vdm21mjklzpyjjvp8.PNG" alt=" " width="800" height="269"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have come to the end of this week’s  Kodecapsule . In this article we looked at creating your first app in django, creating views, configuring urls and rendering templates in django. In the next article we will take a look at models and templates into details.&lt;br&gt;&lt;br&gt;
Be sure to watch out for the articles in this series as I take you from Zero to an expert in Django. &lt;br&gt;
Your Suggestions and Comments are always welcome. &lt;br&gt;
Kuseh Wewoliamo &lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/topics/http/views/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/5.0/topics/http/views/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.djangoproject.com/en/5.0/topics/templates/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/5.0/topics/templates/&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.djangoproject.com/en/5.0/ref/urls/#include" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/5.0/ref/urls/#include&lt;/a&gt;&lt;br&gt;
&lt;a href="https://docs.djangoproject.com/en/5.0/ref/urls/#path" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/5.0/ref/urls/#path&lt;/a&gt;&lt;br&gt;
&lt;a href="https://www.w3schools.com/django/django_create_app.php" rel="noopener noreferrer"&gt;https://www.w3schools.com/django/django_create_app.php&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>django</category>
      <category>webdev</category>
      <category>backenddevelopment</category>
    </item>
    <item>
      <title>A Beginner’s Guide to Django Web Framework: Django from Novice to Expert</title>
      <dc:creator>KUSEH SIMON WEWOLIAMO</dc:creator>
      <pubDate>Sun, 28 Jul 2024 16:00:46 +0000</pubDate>
      <link>https://forem.com/kodecapsule/a-beginners-guide-to-django-web-framework-django-from-novice-to-expert-4b4d</link>
      <guid>https://forem.com/kodecapsule/a-beginners-guide-to-django-web-framework-django-from-novice-to-expert-4b4d</guid>
      <description>&lt;p&gt;&lt;strong&gt;Building Web Applications with Django ,A Practical Guide.🏗️ 🚀🐍🌐&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Capsule 1, Introduction to Django&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Greetings comrades, it’s another brand-new day and we need to take our KodeCapsule of the week. I will be starting a tutorial blog series on one of the most popular python web development framework (WDF), Django. This tutorial series will take you from an absolute beginner to an expert in using Django to build web apps and REST APIs. So, stay turned and enjoy the cruise as we dive into the world of Django.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Outline of Article&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Introduction&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;What is Django?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Benefits of Django&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Architecture of Django&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Installing and Setting up Django&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Django project folder structure&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Conclusion&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;References&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;What is a Web development Framework (WDF)?&lt;/p&gt;

&lt;p&gt;Before we take a look at what Django is, lets first get to understand what a WDF and why we need web frameworks. In Simple terms a web development Framework (WDF) is a collection of tools that are purposely designed to help in the development of web applications including web services, web resources and web APIs. WDFs provide a standard approach to build and deploy web applications on the World Wide Web. The goal of WDFs is to automate the overhead associated with common activities that are carried out in web development. Some popular WDFs are,_ .NET (C#), Django(Python), Ruby on Rails (Ruby) Express (JavaScript/Node.js), Laravel (PHP), Spring Boot(Java)._&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;What is Django?&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Django, as describe on the Django website, ( The web framework for perfectionists with deadlines) is a high-level Python web framework that encourages rapid development, clean and pragmatic design. It was created to help web developers move from applications concept to completion as quickly as possible. With Django, you can build and deploy web applications in less time with few lines of code. Django is designed by skilled developers and helps to handle a lot of the hassle of web development, so you can focus on writing your application without having to reinvent the wheel. Django is also an open-source project that was released in 2005. You can learn more about Django here.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Benefits of Django&lt;/strong&gt;
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Fast Development: Django is designed based on the “batteries-included” philosophy which simply means that Django comes with a lot of baked in features and tools out of the box for faster application development. Django offers a lot of built-in features (Django’s ORM,Authentication system etc) and functionalities that developers commonly use when building applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Highly Secured: Django has a lot of build in security features that helps app developers avoid a number of common security mistakes by providing a secure way to manage user accounts and passwords through its built-in authentication system. Django also has features that offer protection against common web exploits such as cross-site scripting (XSS), cross-site request forgery (CSRF) and SQL injection.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Scalable: One other benefit of using Django is that it enables your applications to scale smoothly. Django can scale quickly to handle huge volumes of traffic demands from the smallest to the largest web applications.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Versatile: Whether you’re building a content management system, a social network, a REST API, machine learning application, Scientific computing platforms, Django provides you with all the tools you need to build any type of web application.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Architecture of Django&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Django is designed based on the Model View Template (MVT) architecture. MVT is a software design pattern.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Model: The model is the data access layer that is responsible for handling the data-logic and defines the structure for storing the application data in a database. Models are independent of the types of database used because Django has an inbuilt Object relational Mapper (ORM) that maps Python classes to database tables.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;View: The view is the “glue” between the Model and the Template. The view handles the business logic. The view receives request from the user via a template, process the data using a model and return a response. A View in Django is the same as a controller in other frameworks like spring boot that uses the MVC architecture.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Template: The presentation layer is the template which is responsible for handling the layout and structure of the user facing application. The template defines how data should be presented to the user. The template contains static content such as HTML, CSS and JavaScript usually injected with Django Template Language (DTL) which allows dynamic content to be inserted into a template.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Note: Django has a URL dispatcher that maps URLS to corresponding views. Find more details about the URL dispatcher here.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8qmymik202bdzerygak.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb8qmymik202bdzerygak.gif" alt="Architecture of Django" width="995" height="672"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Installing and Setting up Django&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1. Installing Python on your Computer&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;You have to have some basic knowledge of Python programming language.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Make sure you have Python installed on your computer. If you have not installed python visit the python website and follow the instructions for installing python on your preferred operating system. I will be using Windows OS in this tutorial series. Download and install Python.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Step 2. Setting Up a Virtual Environment, Installing Django and starting your first project.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A virtual environment is an isolated environment in which you can work on your Python projects independently of the Python that is installed on your system. You can set up the libraries and dependencies that your project needs without affecting the main Python libraries installed on your system.&lt;/p&gt;

&lt;p&gt;1.Install virtualenv: virtualenv is a tool that is use to create isolated Python environments. To install virtualenv run this command in your terminal.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install virtualenv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;2.Create a Virtual environment: Create a folder for your project and cd into the project folder in your terminal and run this command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;py -m venv django_venv&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;3.Activate virtual environment : To activate the virtual environment cd into your virtual environment using this command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;django_venv/scripts/activate&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;4.Install Django: Install Django in the virtual environment using this command.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip install django&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;5.Confirm Django installation: To confirm that Django is install type this command. This command list Django and other modules that Django uses.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;pip freeze&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;6.Start your first project: To start your first project run this command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;django-admin startproject myproject .&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;7.Run development Server: cd into myproject folder and start the development server by running this command&lt;/p&gt;

&lt;p&gt;&lt;code&gt;python manage.py runserver&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;8.The development server will start at &lt;a href="http://127.0.0.1:8000/" rel="noopener noreferrer"&gt;http://127.0.0.1:8000/&lt;/a&gt; Copy the url to your browser. Congrats you have successfully installed and start a new project&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0p0pqr0h92jvt0twp68.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0p0pqr0h92jvt0twp68.PNG" alt="Django start page" width="800" height="386"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Django project folder structure&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Django organizes and structure your project into separate and different components. This structure encourages code reusability, maintainability, and scalability. When you created the new django project using this command, django-admin startproject myproject, in the previous section, the following directory structure was generated.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;├── myproject/
│   ├── __init__.py
│   ├── settings.py
│   ├── urls.py
│   └── wsgi.py
├── manage.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;manage.py: This script is a command-line tool that allows you to interact with your Django project. It contains collection of commands that you can use to perform various task in your Django project like starting the development server, running tests, and perform other administrative tasks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;init&lt;/strong&gt;.py: This is an empty file that informs python to treat that directory as a python package.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;settings.py: This script is the heart of your Django project. It contains all the settings and configurations for your project and determines how Django behaves. Some common settings include database settings, installed apps, template directories, middleware and more. Settings Reference: &lt;a href="https://docs.djangoproject.com/en/5.0/ref/settings/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/5.0/ref/settings/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;urls.py: This script defines all the URL patterns for your project. It acts as a URL dispatcher, mapping all incoming URLs (request) to specific views that handle those requests. Refer to the official Django documentation for a deeper understanding of URL patterns and the urls.py file, &lt;a href="https://docs.djangoproject.com/en/5.0/topics/http/urls/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/5.0/topics/http/urls/&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;wsgi.py: This script is used by the web server to serve your application. Web Server Gateway Interface (WSGI) acts as a mediator that is responsible for conveying communications between a web server and a Python web application. It’s essential for deploying Django apps.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;asgi.py:This script acts as the entry point for ASGI compatible web servers to serve your Django project. Asynchronous Server Gateway Interface (ASGI) is used to handle asynchronous tasks. ASGI is a spiritual successor to WSGI, intended to provide a standard interface between async-capable Python web servers, frameworks, and applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Conclusion&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Well well , we have come to the end of the this weeks Kodecapsule. In this article we were introduced to Python web framework, Django, the benefits of using Django, it’s architecture and created our first project. In the next article we will take a look at Django apps, creating our own apps and getting our hands “dirty”.&lt;/p&gt;

&lt;p&gt;Be sure to watch out for the articles in this series as I take you from Zero to an expert in Django.&lt;/p&gt;

&lt;p&gt;_Your Suggestions and Comments are always welcome.&lt;/p&gt;

&lt;p&gt;Kuseh Wewoliamo_&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.python.org/" rel="noopener noreferrer"&gt;https://www.python.org/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.djangoproject.com/" rel="noopener noreferrer"&gt;https://www.djangoproject.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/ref/settings/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/5.0/ref/settings/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Django_(web_framework)" rel="noopener noreferrer"&gt;https://en.wikipedia.org/wiki/Django_(web_framework)&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/@commbigo/wsgi-vs-asgi-for-python-web-development-9d9a3c426aa9" rel="noopener noreferrer"&gt;https://medium.com/@commbigo/wsgi-vs-asgi-for-python-web-development-9d9a3c426aa9&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/" rel="noopener noreferrer"&gt;https://docs.djangoproject.com/en/5.0/howto/deployment/wsgi/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://builtin.com/data-science/wsgi" rel="noopener noreferrer"&gt;https://builtin.com/data-science/wsgi&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.freecodecamp.org/news/how-to-setup-virtual-environments-in-python/" rel="noopener noreferrer"&gt;https://www.freecodecamp.org/news/how-to-setup-virtual-environments-in-python/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>python</category>
      <category>backend</category>
      <category>django</category>
      <category>coding</category>
    </item>
  </channel>
</rss>
