<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Untitled Publication]]></title><description><![CDATA[Untitled Publication]]></description><link>https://musonza.dev</link><generator>RSS for Node</generator><lastBuildDate>Sun, 18 Oct 2026 00:06:08 GMT</lastBuildDate><atom:link href="https://musonza.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[AWS IAM Roles: A Guide to Cross-Account Access with Examples]]></title><description><![CDATA[Introduction
AWS IAM (Identity and Access Management) roles are the backbone of secure access control in cloud environments. However, managing cross-account IAM roles can quickly become challenging or confusing, especially if you’re missing critical ...]]></description><link>https://musonza.dev/aws-iam-roles-a-guide-to-cross-account-access-with-examples</link><guid isPermaLink="true">https://musonza.dev/aws-iam-roles-a-guide-to-cross-account-access-with-examples</guid><category><![CDATA[IAM]]></category><category><![CDATA[aws-cross-account]]></category><category><![CDATA[iam role in aws]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Sat, 23 Nov 2024 15:58:28 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/Nel8STCcWy8/upload/a98fedae49857b645aba65a3c91a0380.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-introduction">Introduction</h2>
<p>AWS IAM (Identity and Access Management) roles are the backbone of secure access control in cloud environments. However, managing cross-account IAM roles can quickly become challenging or confusing, especially if you’re missing critical permissions like <code>sts:AssumeRole</code>. Additionally, an incorrect or missing <code>ExternalId</code> can prevent roles, such as those used by third-party auditors or monitoring systems, from being assumed, as it is a key requirement for establishing cross-account trust.</p>
<p>This guide will walk you through common scenarios of cross-account communication, highlight potential pitfalls, and provide solutions with detailed flowcharts and examples.</p>
<h2 id="heading-why-cross-account-iam-roles-matter">Why Cross-Account IAM Roles Matter</h2>
<p>In large organizations, production accounts are often separated by business function for security, billing, and compliance reasons. For example:</p>
<ul>
<li><p>Analytics Account</p>
</li>
<li><p>Data Science Account</p>
</li>
<li><p>Centralized Logging Account</p>
</li>
</ul>
<p>Cross-account IAM roles enable secure interactions across these environments, ensuring proper access control and permissions while preventing overly permissive configurations.</p>
<h2 id="heading-real-life-analogy-checking-into-a-hotel">Real-Life Analogy: Checking into a Hotel</h2>
<p>Think of <strong>cross-account access</strong> like checking into a hotel:</p>
<ol>
<li><p><strong>Establish Trust</strong>:<br /> The receptionist verifies your reservation and identity.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732376304137/9ba5aa6e-61c6-4eba-bd76-768aa1f2e167.jpeg" alt /></p>
<ul>
<li>In AWS, this is the <strong>trust policy</strong> ensuring the target account trusts the source account.</li>
</ul>
</li>
<li><p><strong>Grant Permissions</strong>:<br /> You receive a key card programmed for your room.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732376597934/64d24c21-69fe-4138-bf2d-379586159ce5.jpeg" alt /></p>
<ul>
<li>In AWS, this is the <strong>sts:AssumeRole</strong> permission, allowing temporary access to the role.</li>
</ul>
</li>
<li><p><strong>Access Resources</strong>:<br /> You use the key card to access your room and amenities.</p>
<p> <img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732376620741/17538b1d-6797-4762-800f-7f05b8e60fab.jpeg" alt /></p>
<ul>
<li>In AWS, this corresponds to <strong>resource-specific permissions</strong> like accessing an S3 bucket or DynamoDB table.</li>
</ul>
</li>
</ol>
<p>This simple analogy illustrates how cross-account access works in AWS and why each step is critical.</p>
<h2 id="heading-what-is-a-principal">What is a Principal?</h2>
<p>In AWS, a <strong>Principal</strong> is an entity that can make requests to AWS services. A Principal must have permissions, either explicitly or implicitly granted, to access AWS resources.</p>
<h3 id="heading-types-of-principals-in-aws">Types of Principals in AWS</h3>
<ol>
<li><p><strong>IAM Users</strong>:</p>
<ul>
<li><p>A user created within an AWS account, typically representing an individual or application.</p>
</li>
<li><p><strong>Example</strong>: <code>arn:aws:iam::123456789012:user/Alice</code>.</p>
</li>
</ul>
</li>
<li><p><strong>IAM Roles</strong>:</p>
<ul>
<li><p>Temporary credentials associated with a specific role, allowing access to AWS resources. Roles can be assumed by users, applications, or other AWS services.</p>
</li>
<li><p><strong>Example</strong>: <code>arn:aws:iam::123456789012:role/EC2AccessRole</code></p>
</li>
</ul>
</li>
<li><p><strong>AWS Services:</strong></p>
<ul>
<li><p>Services like Lambda, EC2, or ECS that need access to other AWS resources to function.</p>
</li>
<li><p><strong>Example</strong>: <code>arn:aws:iam::123456789012:role/service-role/LambdaExecutionRole</code>.</p>
</li>
</ul>
</li>
<li><p><strong>Federated Users or Applications</strong>:</p>
<ul>
<li><p>External users authenticated by an identity provider (e.g., SAML, OpenID Connect) or by using AWS STS tokens.</p>
</li>
<li><p><strong>Example</strong>: A user accessing AWS through a corporate identity provider.</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-why-is-principal-important-in-cross-account-access">Why is "Principal" Important in Cross-Account Access?</h3>
<p>When setting up cross-account access, the first step is to identify the <strong>source Principal</strong> (the requester) and the <strong>target Principal</strong> (the resource owner). Knowing which entity assumes roles, accesses resources, and grants permissions helps clarify how AWS IAM policies and trust relationships function.</p>
<h2 id="heading-understanding-the-workflow">Understanding the Workflow</h2>
<p>The core of cross-account IAM role configuration involves the following steps:</p>
<ol>
<li><p><strong>Establish Trust</strong>: Make sure the target account trusts the role from the source account.</p>
</li>
<li><p><strong>Grant Permissions</strong>: Provide the necessary permissions for the source account to assume the role.</p>
</li>
<li><p><strong>Access Resources</strong>: Ensure the source account has the permissions needed to interact with resources in the target account.</p>
</li>
</ol>
<p>Below is a flowchart illustrating the decision-making process to consider when setting up IAM roles.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732331193569/a6c5abb8-2e6a-41ad-866d-079348a0a7c0.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-examples-of-cross-account-scenarios">Examples of Cross-Account Scenarios</h2>
<h3 id="heading-scenario-1-analytics-account-accessing-data-in-data-science-account">Scenario 1: Analytics Account Accessing Data in Data Science Account</h3>
<ul>
<li><p><strong>Accounts Involved</strong>:</p>
<ul>
<li><p><strong>Analytics Account</strong>: Runs business intelligence (BI) tools like Tableau or AWS QuickSight.</p>
</li>
<li><p><strong>Data Science Account</strong>: Stores cleaned and processed data in S3 for model training.</p>
</li>
</ul>
</li>
<li><p><strong>Steps</strong>:</p>
<ul>
<li><p>Add <strong>Analytics Account's IAM Role</strong> to the S3 bucket policy in <strong>Data Science Account</strong>.</p>
<pre><code class="lang-json">  {
    <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
    <span class="hljs-attr">"Statement"</span>: [
      {
        <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
        <span class="hljs-attr">"Principal"</span>: {
          <span class="hljs-attr">"AWS"</span>: <span class="hljs-string">"arn:aws:iam::ACCOUNT_ANALYTICS:role/BIReaderRole"</span>
        },
        <span class="hljs-attr">"Action"</span>: <span class="hljs-string">"s3:GetObject"</span>,
        <span class="hljs-attr">"Resource"</span>: <span class="hljs-string">"arn:aws:s3:::data-science-bucket/*"</span>
      }
    ]
  }
</code></pre>
<blockquote>
<p>The <code>arn:aws:s3:::</code> format for S3 ARNs is unique because S3 buckets are global resources, not account-specific. Unlike most AWS services, which include the account ID in their ARNs, S3 does not.</p>
</blockquote>
</li>
<li><p>Ensure `<strong>sts:AssumeRole</strong> permission for the Analytics Account's IAM Role.</p>
<pre><code class="lang-json">  {
    <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
    <span class="hljs-attr">"Statement"</span>: [
      {
        <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
        <span class="hljs-attr">"Action"</span>: <span class="hljs-string">"sts:AssumeRole"</span>,
        <span class="hljs-attr">"Resource"</span>: <span class="hljs-string">"arn:aws:iam::ACCOUNT_DATA_SCIENCE:role/DataAccessRole"</span>
      }
    ]
  }
</code></pre>
</li>
</ul>
</li>
</ul>
<h3 id="heading-scenario-2-data-science-account-accessing-centralized-logging">Scenario 2: Data Science Account Accessing Centralized Logging</h3>
<ul>
<li><p><strong>Accounts Involved</strong>:</p>
</li>
<li><p><strong>Data Science Account</strong>: Runs machine learning models that generate logs for debugging.</p>
</li>
<li><p><strong>Centralized Logging Account</strong>: Collects and stores all logs in CloudWatch.</p>
</li>
</ul>
<p><strong>Steps</strong>:</p>
<ul>
<li>Grant the <strong>Data Science Account IAM Role</strong> access to the CloudWatch Logs in <strong>Centralized Logging Account</strong>.</li>
</ul>
<pre><code class="lang-json">{
  <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
  <span class="hljs-attr">"Statement"</span>: [
    {
      <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
      <span class="hljs-attr">"Principal"</span>: {
        <span class="hljs-attr">"AWS"</span>: <span class="hljs-string">"arn:aws:iam::ACCOUNT_DATA_SCIENCE:role/LogWriterRole"</span>
      },
      <span class="hljs-attr">"Action"</span>: <span class="hljs-string">"logs:PutLogEvents"</span>,
      <span class="hljs-attr">"Resource"</span>: <span class="hljs-string">"arn:aws:logs:region:ACCOUNT_LOGGING:log-group:/data-science-logs:*"</span>
    }
  ]
}
</code></pre>
<ul>
<li>Add <strong>sts:AssumeRole</strong> permission for the Data Science Account IAM Role.</li>
</ul>
<pre><code class="lang-json">{
  <span class="hljs-attr">"Version"</span>: <span class="hljs-string">"2012-10-17"</span>,
  <span class="hljs-attr">"Statement"</span>: [
    {
      <span class="hljs-attr">"Effect"</span>: <span class="hljs-string">"Allow"</span>,
      <span class="hljs-attr">"Action"</span>: <span class="hljs-string">"sts:AssumeRole"</span>,
      <span class="hljs-attr">"Resource"</span>: <span class="hljs-string">"arn:aws:iam::ACCOUNT_LOGGING:role/LogAccessRole"</span>
    }
  ]
}
</code></pre>
<h2 id="heading-common-pitfalls-in-cross-account-access">Common Pitfalls in Cross-Account Access</h2>
<p>1. <strong>Missing</strong> <code>sts:AssumeRole</code> Permission:<br />Even with correct trust policies, access fails if this permission is not granted.</p>
<p>2. <strong>Misconfigured Resource Policies</strong>:<br />Ensure the target resource (e.g., S3 bucket or RDS) explicitly allows the requesting account.</p>
<p>3. <strong>Incorrect Role ARN</strong>:<br />Double-check ARNs in all trust and IAM policies to prevent mismatched configurations.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>AWS IAM roles are powerful, but cross-account setups can be tricky without proper configurations. Ensuring trust policies, <code>sts:AssumeRole</code> permissions, and resource policies are aligned is critical for secure and seamless communication across production accounts. Additionally, always verify the use of <code>ExternalId</code> in scenarios where it is required, such as for third-party auditors or external monitoring tools, to prevent unexpected access issues.</p>
<p>By following the workflow and using the examples above, you can navigate complex use cases and avoid common pitfalls, ensuring a secure and well-configured cloud environment.</p>
<h2 id="heading-references">References</h2>
<ul>
<li><p><a target="_blank" href="https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_common-scenarios_third-party.html">Using IAM Roles to Delegate Permissions to Third Parties</a></p>
</li>
<li><p><a target="_blank" href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_condition-keys.html#condition-keys-externalid">IAM Policies and Conditions: Using ExternalId</a></p>
</li>
<li><p><a target="_blank" href="https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_examples_aws_my-service-role.html">IAM Roles Trust Policy Examples</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[On My Bookshelf - 'Kubernetes Up and Running' by Kelsey Hightower…]]></title><description><![CDATA["Kubernetes: Up and Running" by Kelsey Hightower, Brendan Burns, and Joe Beda isn't just a guide; it's an invaluable reference I often lean on in my Kubernetes journey. Though I had ventured into container orchestration before, this book fortified my...]]></description><link>https://musonza.dev/on-my-bookshelf-kubernetes-up-and-running-by-kelsey-hightower</link><guid isPermaLink="true">https://musonza.dev/on-my-bookshelf-kubernetes-up-and-running-by-kelsey-hightower</guid><category><![CDATA[Kubernetes]]></category><category><![CDATA[k8s]]></category><category><![CDATA[containers]]></category><category><![CDATA[containerization]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Wed, 16 Aug 2023 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/tjX_sniNzgQ/upload/d90c256ec1a55ee4ecd935650c141422.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>"Kubernetes: Up and Running" by Kelsey Hightower, Brendan Burns, and Joe Beda isn't just a guide; it's an invaluable reference I often lean on in my Kubernetes journey. Though I had ventured into container orchestration before, this book fortified my understanding of Kubernetes' various aspects.</p>
<p>One of the standout teachings was the distinction between Jobs and Deployments. While both are controllers in Kubernetes designed to manage pods, they cater to different use cases. Jobs are suitable for one-off tasks, ensuring a particular task reaches completion. In contrast, Deployments ensure a specified number of pod replicas are consistently running. Grasping this difference proved pivotal in multiple projects, enhancing task performance and completion.</p>
<p>The authors also shed light on Kubernetes' robust rollback mechanisms. It's more than just retracing to a prior version; it's about appreciating the nuances and potential trip-ups. Given Kubernetes' inherent ability to revert deployments, I felt bolstered when initiating changes, assured that a trustworthy safety net was at my disposal should things veer off track.</p>
<p>Moreover, the strategic utility of labels and annotations was a revelation. Labels aid in the organization and resource selection, whereas annotations enable you to store extra metadata to elucidate the behavior of tools or libraries. This not only streamlines organization but offers a clearer picture when several teams or projects utilize the same cluster.</p>
<p>In summation, "Kubernetes: Up and Running" by Kelsey Hightower, Brendan Burns, and Joe Beda augmented my grasp of numerous Kubernetes elements and practices. It remains a preferred resource, offering clarity during moments of doubt.</p>
]]></content:encoded></item><item><title><![CDATA[On My Bookshelf - 'The Pragmatic Programmer' by Andrew Hunt and David Thomas]]></title><description><![CDATA[One of my recent reads was "The Pragmatic Programmer" by Andrew Hunt and David Thomas. This guide helps software developers improve their craft. Even after years in software engineering, I believe in continuous learning, especially since technology k...]]></description><link>https://musonza.dev/on-my-bookshelf-the-pragmatic-programmer-by-andrew-hunt-and-david-thomas</link><guid isPermaLink="true">https://musonza.dev/on-my-bookshelf-the-pragmatic-programmer-by-andrew-hunt-and-david-thomas</guid><category><![CDATA[pragmatic]]></category><category><![CDATA[General Programming]]></category><category><![CDATA[book summary]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Fri, 11 Aug 2023 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/zwsHjakE_iI/upload/5098eb8f5cdbe0baee7017ce56924593.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>One of my recent reads was "The Pragmatic Programmer" by Andrew Hunt and David Thomas. This guide helps software developers improve their craft. Even after years in software engineering, I believe in continuous learning, especially since technology keeps evolving. The book shares stories, tips, and advice to help programmers thrive in software development. It promotes adaptability, ongoing learning, and focusing on quality.</p>
<p>Here are some key takeaways:</p>
<ol>
<li><p><strong>Software as Craftsmanship</strong>: Just like a blacksmith shapes metals or a carpenter creates furniture, a software developer builds applications. It's not just about the tools but the skills. In the realm of craftsmanship, a blacksmith meticulously hones their skills to shape metals, while a carpenter refines their techniques to produce elegant furniture. Similarly, a software developer artfully molds code to birth applications. As time unfurls, this code matures and becomes more polished, mirroring the progression seen in a craftsman's masterpieces. Peer learning, knowledge sharing, and collective problem-solving act as the linchpins for improvement. And at the heart of it all is pride—just as craftsmen revel in their creations, developers too should take immense pride in their code.</p>
</li>
<li><p><strong>DRY Principle</strong>: It means "Don't Repeat Yourself." Avoid using the same code everywhere. Think of it like this: if you use the same piece of code in many places, you'll have a tough time making changes later on. By avoiding repeated code, you make your work easier to update and less prone to mistakes.</p>
</li>
<li><p><strong>Orthogonality</strong>: Make sure different parts of software can work on their own. Think of a set of toy building blocks. If you pull one block out, you wouldn't want the whole tower to fall, right? Keeping things orthogonal is like having different departments in a store; if the toy section is closed, it doesn't mean the whole store shuts down.</p>
</li>
<li><p><strong>Automate</strong>: Reduce repetitive tasks. Use tools that can do the work for you, like a dishwasher cleans dishes without you washing them by hand. Instead of doing repetitive tasks manually, we use tools that do the job for us. It's all about making things easier and more efficient.</p>
</li>
<li><p><strong>Code with Quality</strong>: Make your code clear, like a well-written story. Instead of using names like "x" or "y" for variables, use names that tell you what they are, like "totalPrice" or "userName". It's all about making sure that if someone else looks at your work, they can easily get the whole picture.</p>
</li>
<li><p><strong>Decoupling</strong>: Keep components independent. For instance, in software systems, rather than having one component directly call and depend on another, we might use a queue. This way, even if the email system is down or being updated, the website can continue to function normally.</p>
</li>
<li><p><strong>Stay Updated</strong>: The tech world is always changing, just like fashion trends. Keep up with the latest to stay relevant. It's about taking the time to learn about the newest tools, languages, or ways of doing things.</p>
</li>
<li><p><strong>Testing</strong>: Before sharing your software, test it. Automated testing is an even better helper. Instead of manually checking every detail, you have tools that run through your code, looking for any issues.</p>
</li>
<li><p><strong>Flexibility</strong>: Be ready to adapt. Being flexible means being ready to adapt when needed. It's like having a backup plan for that picnic. With a flexible approach, you can adjust your code or strategy, ensuring your software stays relevant and effective no matter what comes its way.</p>
</li>
<li><p><strong>Estimations</strong>: Plan realistically. When figuring out how long a project or task will take, it's essential to be realistic. By giving realistic estimates, you ensure a smoother journey in coding, with fewer surprises.</p>
</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2023/pragmatic-programmer-cover.jpeg" alt="Pragmatic Programmer" /></p>
<p><a target="_blank" href="https://www.amazon.com/Pragmatic-Programmer-journey-mastery-Anniversary/dp/0135957052/ref=asc_df_0135957052/?tag=hyprod-20&amp;linkCode=df0&amp;hvadid=385599638286&amp;hvpos=&amp;hvnetw=g&amp;hvrand=16342964313746866927&amp;hvpone=&amp;hvptwo=&amp;hvqmt=&amp;hvdev=c&amp;hvdvcmdl=&amp;hvlocint=&amp;hvlocphy=9009919&amp;hvtargid=pla-826212996228&amp;psc=1&amp;tag=&amp;ref=&amp;adgrpid=79288120515&amp;hvpone=&amp;hvptwo=&amp;hvadid=385599638286&amp;hvpos=&amp;hvnetw=g&amp;hvrand=16342964313746866927&amp;hvqmt=&amp;hvdev=c&amp;hvdvcmdl=&amp;hvlocint=&amp;hvlocphy=9009919&amp;hvtargid=pla-826212996228">Get the book on Amazon</a></p>
]]></content:encoded></item><item><title><![CDATA[On My Bookshelf - 'Clean Code - A Handbook of Agile Software Craftsmanship' by Robert Martin]]></title><description><![CDATA["Clean Code: A Handbook of Agile Software Craftsmanship" by Robert Martin, often affectionately referred to as "Uncle Bob" in the software community, is an enlightening guide not just for budding engineers but for professionals at any stage of their ...]]></description><link>https://musonza.dev/on-my-bookshelf-clean-code-a-handbook-of-agile-software-craftsmanship-by-robert-martin</link><guid isPermaLink="true">https://musonza.dev/on-my-bookshelf-clean-code-a-handbook-of-agile-software-craftsmanship-by-robert-martin</guid><category><![CDATA[book summary]]></category><category><![CDATA[clean code]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Fri, 28 Jul 2023 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697295701072/f633046f-246f-49dc-b18c-e468d29a3e14.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>"Clean Code: A Handbook of Agile Software Craftsmanship" by Robert Martin, often affectionately referred to as "Uncle Bob" in the software community, is an enlightening guide not just for budding engineers but for professionals at any stage of their journey.</p>
<p>The overarching message is clear: prioritize clean code. But what does "clean" really mean in the context of coding? Here are some of the defining elements and key takeaways from the book:</p>
<ol>
<li><p><strong>Readability</strong>: At its core, code is a form of communication. Clean code should read like well-written prose. This ensures that any developer, whether they wrote the code or not, can understand its purpose and functionality with ease.</p>
</li>
<li><p><strong>Meaningful Names</strong>: Naming is pivotal. A variable named <code>x</code> tells you nothing, but <code>userAge</code> is descriptive. The names you choose should reveal intent and make the code's functionality evident.</p>
</li>
<li><p><strong>Functions Should Do One Thing</strong>: A well-written function has a single responsibility. By ensuring each function is concise and serves one purpose, you maintain clarity and reduce potential points of failure.</p>
</li>
<li><p><strong>Error Handling</strong>: Proper error handling is an essential aspect of clean code. It's not just about catching errors but doing so in a manner that doesn't introduce more complexity or obscure the main logic.</p>
</li>
<li><p><strong>Avoid Duplication</strong>: The DRY (Don't Repeat Yourself) principle isn't just about reducing the amount of code but ensuring that there's a single, authoritative source of truth in the system.</p>
</li>
<li><p><strong>Comments Aren't Always Good</strong>: Contrary to popular belief, comments can sometimes be detrimental. If you're using comments as a crutch to explain complex code, it's often a sign that the code itself isn't clean or clear.</p>
</li>
<li><p><strong>Limit Function Arguments</strong>: The fewer arguments a function has, the easier it is to test and use. If a function is expecting numerous inputs, it might be doing too much.</p>
</li>
<li><p><strong>Embrace Testing</strong>: Automated tests provide a safety net, ensuring that as you refactor and clean your code, you aren't introducing new bugs.</p>
</li>
<li><p><strong>Concise Code</strong>: Verbosity doesn't equate to clarity. Clean code is often concise, devoid of unnecessary repetition or fluff.</p>
</li>
<li><p><strong>Continuous Refactoring</strong>: Clean code isn't a destination but a journey. As you gain new insights or as requirements change, continuously refactor your code to keep it clean.</p>
</li>
</ol>
<p>By internalizing the principles of clean code from the early stages of your career, you don't just set the foundation for professional growth. You pave the way for more efficient, maintainable, and scalable software projects. Remember, in the world of software, the quality of your code often mirrors the quality of the end product.</p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2023/clean-code-cover.jpeg" alt="Clean Code" /></p>
<p><a target="_blank" href="https://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882">Get the book on Amazon</a></p>
]]></content:encoded></item><item><title><![CDATA[On My Bookshelf - 'Dive into Design Patterns' by Alexander Shvets]]></title><description><![CDATA[If you've ever wondered about design patterns in software, 'Dive into Design Patterns' by Alexander Shvets is a great place to start. Shvets makes the topic easy to understand by using real-world examples. He doesn't just talk about ideas but shows h...]]></description><link>https://musonza.dev/on-my-bookshelf-dive-into-design-patterns-by-alexander-shvets</link><guid isPermaLink="true">https://musonza.dev/on-my-bookshelf-dive-into-design-patterns-by-alexander-shvets</guid><category><![CDATA[design patterns]]></category><category><![CDATA[General Programming]]></category><category><![CDATA[book summary]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Fri, 30 Jun 2023 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697295504804/b78a8703-1312-475e-813f-02f2e8a75793.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>If you've ever wondered about design patterns in software, 'Dive into Design Patterns' by Alexander Shvets is a great place to start. Shvets makes the topic easy to understand by using real-world examples. He doesn't just talk about ideas but shows how they work in practice.</p>
<p>Design patterns are like helpful shortcuts for developers. They're not ready-made code but more like problem-solving methods, we can use over and over again. These patterns help solve common design problems without starting from scratch each time.</p>
<p>I've found this book really handy on many projects. Whenever I'm not sure which design pattern to use, I turn to Shvets' clear guidance.</p>
<p>One of my go-to patterns from the book is the State Pattern. It lets an object change how it acts based on its current "state" or situation. Imagine a light switch: it behaves differently when it's "on" versus "off". The State Pattern makes managing such changes in behavior easy and clean.</p>
<p>Whether you're just starting out or have been coding for years, 'Dive into Design Patterns' is a helpful guide. It's all about using smart, tried-and-true methods to make software better.</p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2023/design-patterns-cover.png" alt="Dive into Design Patterns" /></p>
<p><a target="_blank" href="https://refactoring.guru/design-patterns/book">Get the book</a></p>
]]></content:encoded></item><item><title><![CDATA[On My Bookshelf - 'The DynamoDB Book' by Alex DeBri]]></title><description><![CDATA[Navigating the intricacies of DynamoDB after having a solid foundation in SQL databases like MySQL brings its own set of challenges. 'The DynamoDB Book' by Alex DeBrie served as an invaluable guide for refining my approach and diving deeper into adva...]]></description><link>https://musonza.dev/on-my-bookshelf-the-dynamodb-book-by-alex-debri</link><guid isPermaLink="true">https://musonza.dev/on-my-bookshelf-the-dynamodb-book-by-alex-debri</guid><category><![CDATA[books]]></category><category><![CDATA[DynamoDB]]></category><category><![CDATA[AWS]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Tue, 30 May 2023 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697295297988/5848c550-c317-40cb-8d92-392d2b4d618f.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Navigating the intricacies of DynamoDB after having a solid foundation in SQL databases like MySQL brings its own set of challenges. 'The DynamoDB Book' by Alex DeBrie served as an invaluable guide for refining my approach and diving deeper into advanced concepts.</p>
<p>Although familiar with NoSQL databases, DynamoDB's unique features initially seemed a bit unconventional. Concepts such as planning access patterns in advance or the single table approach were intriguing. DeBrie's explanations brought clarity to these concepts.</p>
<p>A key realization, emphasized in the book, is the importance of "thinking in access patterns." While the data structure is crucial, DynamoDB shifts the focus to how the data will be accessed. For a blog, considering how users access posts—whether by author, date, or tags—ensures efficient data retrieval. </p>
<p>DeBrie's insights on the single table design were illuminating. In traditional databases, one might maintain separate tables for related data entities. With DynamoDB, related items can coexist in one table, leveraging proper indexing. It requires an adjusted mindset, but the benefits in terms of flexibility and performance are evident once grasped.</p>
<p>The book also delves deep into best practices for designing tables, offering insights on leveraging DynamoDB's capabilities, especially when operating at scale. DeBrie's expertise aids in understanding the platform's nuances, ensuring optimal utilization while avoiding common pitfalls.</p>
<p>For anyone already familiar with NoSQL but aiming to deepen their knowledge of DynamoDB's unique offerings, 'The DynamoDB Book' is a must-read. It demystifies the advanced concepts and bridges the gap between traditional databases and DynamoDB's innovations.</p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2023/dynamodb-book-cover.png" alt="Pragmatic Programmer" /></p>
<p><a target="_blank" href="https://www.dynamodbbook.com/">Get the book</a></p>
]]></content:encoded></item><item><title><![CDATA[On My Bookshelf - 'Clean Architecture - A Craftsman’s Guide to Software Structure and Design' by Robert C. Martin]]></title><description><![CDATA["Clean Architecture" by Robert C. Martin is a book that further deepens and refines the perspective on software design. While I was already familiar with core concepts like the 'SOLID' principles, this book provided nuanced insights and reinforced th...]]></description><link>https://musonza.dev/on-my-bookshelf-clean-architecture-a-craftsmans-guide-to-software-structure-and-design-by-robert-c-martin</link><guid isPermaLink="true">https://musonza.dev/on-my-bookshelf-clean-architecture-a-craftsmans-guide-to-software-structure-and-design-by-robert-c-martin</guid><category><![CDATA[books]]></category><category><![CDATA[book summary]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Fri, 28 Apr 2023 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/VviFtDJakYk/upload/4020ae94f007a237001607e106eb9e39.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>"Clean Architecture" by Robert C. Martin is a book that further deepens and refines the perspective on software design. While I was already familiar with core concepts like the 'SOLID' principles, this book provided nuanced insights and reinforced the value of those principles in the broader context of clean architecture.</p>
<p>A significant takeaway for me was the importance of simplicity in design, regardless of how intricate the problem or the system might be. This emphasis on simplicity helps ensure the longevity and maintainability of software.</p>
<p>Martin's discussion about managing dependencies was enlightening. It's crucial to ensure that the dependencies within our software don't create complexities that become hard to navigate later on.</p>
<p>One concept that truly resonated with me was the idea of ‘screaming architecture’. It suggests that the structure of the software should clearly reflect its functionality and purpose. This promotes transparency and immediate understanding for anyone diving into the system.</p>
<p>In essence, while "Clean Architecture" aligns with many principles I already knew, it gave depth to those ideas and presented actionable strategies to ensure our software remains robust and easy to evolve over time.</p>
]]></content:encoded></item><item><title><![CDATA[Database connection pooling with Amazon RDS Proxy]]></title><description><![CDATA[What is database connection pooling?
Database pooling is a technique to reduce the opening and closing of connections by maintaining a set of open connections that can be passed among database operations. As a result, the connection overhead is sprea...]]></description><link>https://musonza.dev/database-connection-pooling-with-amazon-rds-proxy</link><guid isPermaLink="true">https://musonza.dev/database-connection-pooling-with-amazon-rds-proxy</guid><category><![CDATA[AWS]]></category><category><![CDATA[AWS RDS]]></category><category><![CDATA[Databases]]></category><category><![CDATA[MySQL]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Wed, 09 Nov 2022 17:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/cckf4TsHAuw/upload/3393edd4d39915b8d860139c517b15f1.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-is-database-connection-pooling">What is database connection pooling?</h2>
<p>Database pooling is a technique to reduce the opening and closing of connections by maintaining a set of open connections that can be passed among database operations. As a result, the connection overhead is spread across several client requests.</p>
<h2 id="heading-why-use-amazon-rds-proxy">Why use Amazon RDS Proxy?</h2>
<p>Opening multiple connections is expensive. Establishing a connection includes DNS lookup to locate the server IP address, handshakes to establish a TCP connection, encryption, validating credentials, and more. In addition, all the established connections will consume some CPU to be maintained.</p>
<ul>
<li><p><a target="_blank" href="https://aws.amazon.com/rds/proxy/">Amazon RDS Proxy</a> allows applications to pool and share database connections to improve scalability.</p>
</li>
<li><p>Enables application resilience by automatically connecting to a standby Database instance when there is a failure while preserving the established connections.</p>
</li>
<li><p>Additional security as you can enforce AWS Identity and Access Management authentication for databases and securely store the credentials in AWS Secrets Manager.</p>
</li>
<li><p>Queues or throttles application connections that can’t be served immediately from the pool, thus can keep your application running in a degraded state.</p>
</li>
</ul>
<h2 id="heading-compare-a-database-instances-performance-before-and-after-implementing-rds-proxy">Compare a database instance’s performance before and after implementing RDS Proxy</h2>
<p>Now let’s see RDS Proxy in action. We want to see how the instance behaves with and without RDS Proxy. Here are the steps we are going to conduct:</p>
<ol>
<li><p>Create a db.t3.medium RDS instance. We want at least a t3 so we can leverage <a target="_blank" href="https://aws.amazon.com/rds/performance-insights/">Performance Insights</a> for comparisons</p>
</li>
<li><p>Create a <a target="_blank" href="https://aws.amazon.com/cloud9/">Cloud9</a> environment to run load tests for our database instance.</p>
</li>
<li><p>Import a test database from <a target="_blank" href="https://github.com/datacharmer/test_db">https://github.com/datacharmer/test_db</a>. Otherwise you could use your own simple schema since we will just be testing connections.</p>
</li>
<li><p>Run <a target="_blank" href="https://dev.mysql.com/doc/refman/8.0/en/mysqlslap.html">mysqlslap</a> commands to emulate database connections using the DNS endpoint for our database instance</p>
</li>
<li><p>Create Amazon RDS Proxy</p>
</li>
<li><p>Run the same <a target="_blank" href="https://dev.mysql.com/doc/refman/8.0/en/mysqlslap.html">mysqlslap</a> commands using the RDS Proxy endpoint as host</p>
</li>
</ol>
<h3 id="heading-create-amazon-rds-instance">Create Amazon RDS instance</h3>
<ul>
<li><p>Navigate to the AWS console and search for RDS</p>
</li>
<li><p>For the database creation method, select the Standard create option.</p>
</li>
<li><p>Select MySQL for the Engine options.</p>
</li>
</ul>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/create-mysql-database.png" alt="Create Database" /></p>
<ul>
<li><p>Select Production template</p>
</li>
<li><p>Select Single DB instance for Availability and durability (in production, you will want to use Multi-AZ)</p>
</li>
</ul>
<p><img src="https://github.com/musonza/blog-images/blob/master/2022-11/rds-templates.png?raw=true" alt="RDS templates" /></p>
<ul>
<li><p>On the Settings screen, enter the password and leave the rest of the settings as is.</p>
</li>
<li><p>For database instance configuration, select Burstable classes and choose at least a db.t3.medium instance size (we need more memory to enable Performance Insights)</p>
</li>
<li><p>For Storage type, select General Purpose SSD (gp2) and keep the rest of the settings default.</p>
</li>
<li><p>In terms of Connectivity, keep the default settings, maintaining No public access for the database instance; you can optionally create a new VPC if you like.</p>
</li>
<li><p>For Database authentication, select Password authentication</p>
</li>
<li><p>Under Monitoring, make sure Turn Performance Insights is checked</p>
</li>
<li><p>When done, click the Create Database button to launch your database instance.</p>
</li>
</ul>
<p><img src="https://github.com/musonza/blog-images/blob/master/2022-11/instance-configuration-storage.png?raw=true" alt="Instance configuration" /></p>
<h3 id="heading-create-cloud9-environment">Create Cloud9 environment</h3>
<h4 id="heading-create-environment">Create environment</h4>
<ol>
<li><p>Navigate to your AWS console and search for Cloud9.</p>
</li>
<li><p>Click on the Create environment button.</p>
</li>
<li><p>Provide a name for your environment.</p>
</li>
<li><p>Select <strong>Additional instance types</strong> then choose a <strong>m5.xlarge</strong>. We are selecting a larger instance because we want more resources for test load scripts. Otherwise, the kernel will kill our processes.</p>
</li>
</ol>
<p><em>To avoid additional costs, always tear down your AWS resources when done.</em></p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/cloud9-env-create-m5-instance.png" alt="Cloud9 env name" /></p>
<p>5. Proceed with all the remaining steps and create your environment. The creation process may take a few minutes. 6. Give Cloud9 permission to access MySQL. Our Cloud9 environment will need permission to access our database instance. We achieve that by going to the instance’s security group and adding an inbound rule that allows MySQL traffic from our Cloud9 instance as below:</p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/cloud9-mysql-permission.png" alt="Cloud9 mysql permission" /></p>
<h3 id="heading-import-test-database">Import test database</h3>
<p>AWS Cloud9 EC2 environments come preinstalled with Git. In your Cloud9 environment terminal, run the following commands:</p>
<pre><code class="lang-shell">git clone https://github.com/datacharmer/test_db.git &amp;&amp; cd test_db
</code></pre>
<p>Run the script to create the database schema and load the data. Replace the host with your own database DNS endpoint.</p>
<pre><code class="lang-shell">mysql -h database-1.cxyzjeifrqhn.us-east-1.rds.amazonaws.com \ 
-u admin -p \
-t &lt; employees.sql \
</code></pre>
<p>You should see output similar to the following:</p>
<pre><code class="lang-plaintext">+-----------------------------+
| INFO                        |
+-----------------------------+
| CREATING DATABASE STRUCTURE |
+-----------------------------+
+------------------------+
| INFO                   |
+------------------------+
| storage engine: InnoDB |
+------------------------+
+---------------------+
| INFO                |
+---------------------+
| LOADING departments |
+---------------------+
...
</code></pre>
<h3 id="heading-test-database-instance-without-rds-proxy">Test database instance without RDS Proxy</h3>
<h4 id="heading-how-many-connections-is-too-many">How many connections is too many?</h4>
<p>Before we start testing, let's figure out how many connections are too many for our database instance. For example, the maximum number of simultaneous database connections varies by the DB engine type and the memory allocation for the DB instance class. The larger the database instance, the larger the connections it can handle. So there is a formula that you can use to calculate the maximum number of connections. For MySQL, we use:</p>
<p><code>max_connections = {DBInstanceClassMemory/12582880}</code></p>
<p>In our case, we are using a <code>db.t3.medium</code> instance with a memory of 4 GiB.</p>
<p><code>max_connections = 1024*1024*1024*4/12582880 ~= 341</code></p>
<h4 id="heading-less-than-maxconnections-test">Less than max_connections test</h4>
<pre><code class="lang-shell">mysqlslap -h database-1.cxyzjeifrqhn.us-east-1.rds.amazonaws.com -u admin -p \
--concurrency=100 \
--create-schema=employees \
--query="SELECT * FROM employees;" \
--verbose
Enter password: 
Benchmark
        Average number of seconds to run all queries: 18.414 seconds
        Minimum number of seconds to run all queries: 18.414 seconds
        Maximum number of seconds to run all queries: 18.414 seconds
        Number of clients running queries: 100
        Average number of queries per client: 1
</code></pre>
<h4 id="heading-more-than-maxconnections-test">More than max_connections test</h4>
<p>Remember 341 is our max_connections. Let's try with 345.</p>
<pre><code class="lang-shell">$ mysqlslap -h database-1.cxyzjeifrqhn.us-east-1.rds.amazonaws.com -u admin -p \
&gt; --concurrency=345 \
&gt; --create-schema=employees \
&gt; --query="SELECT * FROM employees;" \
&gt; --verbose
Enter password: 
mysqlslap: Error when connecting to server: 1040 Too many connections
mysqlslap: Error when connecting to server: 1040 Too many connections
mysqlslap: Error when connecting to server: 1040 Too many connections
mysqlslap: Error when connecting to server: 1040 Too many connections
...
...
mysqlslap: Error when connecting to server: 1040 Too many connections
mysqlslap: Error when connecting to server: 1040 Too many connections
Benchmark
        Average number of seconds to run all queries: 54.603 seconds
        Minimum number of seconds to run all queries: 54.603 seconds
        Maximum number of seconds to run all queries: 54.603 seconds
        Number of clients running queries: 345
        Average number of queries per client: 1
</code></pre>
<h3 id="heading-create-rds-proxy">Create RDS Proxy</h3>
<p>Click proxies on the left menu of RDS</p>
<p>Our next step is creating the RDS Proxy to pool our connections.</p>
<ol>
<li>Click on the Proxies link on the left menu in the Amazon RDS console.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/0-click-proxies.png" alt="click proxies" /></p>
<ol>
<li>Click <strong>Create proxy</strong> button and enter name it <strong>database-1-proxy</strong> or anything.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/1-proxy-name-database-1-proxy.png" alt="name proxy" /></p>
<ol>
<li>Next, we need a target database instance for the proxy by selecting it from the database dropdown.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/2-proxy-target-database-instance.png" alt="name proxy" /></p>
<ol>
<li>Supply a secret from AWS Secrets Manager; RDS proxy stores credentials in AWS Secrets Manager, and we will create a new secret.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/3-proxy-connectivity.png" alt="secrets" /></p>
<ol>
<li>AWS Secrets Manager will open in a new tab. Choose Credentials for <strong>Amazon RDS database</strong> and enter a username and password. You will need these credentials to connect to your RDS proxy.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/4-proxy-choose-secret-type.png" alt="AWS Secrets Manage" /></p>
<p>Select your database at the bottom and click next.</p>
<ol>
<li>Enter a name for your secret.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/5-proxy-configure-secret.png" alt="AWS Configure Secret" /></p>
<ol>
<li>Now go back to the tab with the RDS Proxy creation form, refresh the secret selection and choose your created secret.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/6-select-created-secret.png" alt="AWS Configure Secret" /></p>
<ol>
<li><p>Scroll down and click Create proxy. Creation may take up to 20 mins</p>
</li>
<li><p>You need to wait until you have both endpoint and target group identifier statuses set to available, as seen below.</p>
</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/7-proxy-available.png" alt="Proxy Available" /></p>
<ol>
<li>Copy your proxy endpoint, and we will use that next.</li>
</ol>
<h3 id="heading-test-database-instance-with-rds-proxy">Test database instance with RDS Proxy</h3>
<h4 id="heading-more-than-maxconnections-test-rds-proxy">More than max_connections test - RDS Proxy</h4>
<p>Let's test with the same number of connections that errored out when we didn't use RDS proxy.</p>
<pre><code class="lang-shell">mysqlslap -h database-1-proxy.proxy-ctttjeifrqhn.us-east-1.rds.amazonaws.com \
&gt; -u admin -p \
&gt; --concurrency=345 \
&gt; --create-schema=employees \
&gt; --query="SELECT * FROM employees;" \
&gt; --verbose
Enter password: 
Benchmark
        Average number of seconds to run all queries: 65.294 seconds
        Minimum number of seconds to run all queries: 65.294 seconds
        Maximum number of seconds to run all queries: 65.294 seconds
        Number of clients running queries: 345
        Average number of queries per client: 1
</code></pre>
<h2 id="heading-results">Results</h2>
<p>You will notice that we didn't get <strong>Error when connecting to server: 1040 Too many connections</strong>, and we completed our queries (despite being slow).</p>
<p><em>Counter Metrics</em></p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/rds-proxy-counter-metrics.png" alt="RDS Proxy counter metrics" /></p>
<p>In the chart above, you will notice that without an RDS proxy, we have several <code>db.Users.Aborted_clients</code>. However, when we ran the queries using the proxy, we didn't experience any aborted connections. As a result, we could read more rows, as shown by the <code>db.SQL.Innodb_rows_read</code> metric.</p>
<p><em>Waits comparison</em></p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/rds-proxy-waits-comparison.png" alt="RDS Proxy waits comparison" /></p>
<p>Waits dimension is an integral part of performance troubleshooting. Waits are reasons why execution threads have to wait. So when you issue queries, various wait stats could prevent your query execution from completing. These can range from CPU or connection waits. In other words, your execution threads will be waiting for resources.</p>
<p>Now, if we look at our chart above, <code>wait/io/socket/sql/client_connection</code> dimension is higher for operations not using an RDS proxy. <code>io/socket/sql/client_connection</code> event occurs when a thread is handling a new connection, and it makes sense that we have many such events when we aren't pooling our database connections with the RDS proxy. So mysqld will be busy creating threads to handle incoming new client connections. Thus, the event <code>io/socket/sql/client_connection</code> slows down the process of servicing new client connection requests since other database connections will be waiting for the thread to be assigned.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>RDS proxy can make your applications more scalable, resilient, and secure.</p>
<p>Applications' scalability is improved when they share a pool of database connections. For example, an instance using an RDS proxy can scale better than one, not managing database connections.</p>
<p>Resilience is achieved by a proxy connecting to a standby Database when there is a failure.</p>
<p>Using IAM authentication and retrieving credentials from AWS Secrets Manager improves the security of your database. These credentials can be automatically rotated as AWS Secrets Manager supports that functionality out of the box.</p>
<p>RDS proxy can be handy in serverless applications which support highly variable workloads. For example, the variable workloads may attempt to open a burst of new database connections.</p>
<p><a target="_blank" href="https://aws.amazon.com/rds/proxy/">Read more on RDS proxy</a>.</p>
]]></content:encoded></item><item><title><![CDATA[Offloading Amazon RDS reads to read replicas]]></title><description><![CDATA[In this post; we will look at adding read replicas to a single Amazon Relational Database Service (RDS) database instance. We will compare the database load before and after adding read replicas. We will use Mysqlslap to emulate our database load and...]]></description><link>https://musonza.dev/offloading-amazon-rds-reads-to-read-replicas</link><guid isPermaLink="true">https://musonza.dev/offloading-amazon-rds-reads-to-read-replicas</guid><category><![CDATA[AWS]]></category><category><![CDATA[AWS RDS]]></category><category><![CDATA[MySQL]]></category><category><![CDATA[Databases]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Fri, 04 Nov 2022 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/upload/v1697294848056/4534f036-0249-4bf3-be19-fffd2ee5c051.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>In this post; we will look at adding read replicas to a single <a target="_blank" href="https://aws.amazon.com/rds/">Amazon Relational Database Service (RDS)</a> database instance. We will compare the database load before and after adding read replicas. We will use <a target="_blank" href="https://dev.mysql.com/doc/refman/8.0/en/mysqlslap.html">Mysqlslap</a> to emulate our database load and Performance Insights to monitor the database load.</p>
<p>Our final setup will look as below:</p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/read-replicas-final.png" alt="Architecture" /></p>
<h2 id="heading-why">Why?</h2>
<ul>
<li><p>Replicas benefit read-heavy workloads as they improve performance by minimizing the load on the primary database instance. They make it easy to elastically scale out beyond the capacity constraints of a single DB instance. Before you reach for the next database instance class (scaling up), consider replicas (scaling out).
You can use replica endpoints for your ETL processes for the analytics team etc.</p>
</li>
<li><p>Replicas can be promoted in disaster recovery. If the primary goes offline, a replica can be promoted to become primary. However, replication lag should be considered to avoid data loss. You want to promote a replica that has a near-zero replication lag.</p>
</li>
</ul>
<p>We will follow these steps:</p>
<p><strong>Step 1</strong> - Create a single RDS Instance</p>
<p><strong>Step 2</strong> - Run benchmark queries on our RDS instance using mysqlslap. Mysqlslap is a diagnostic program designed to emulate client load for a MySQL server and to report the timing
of each stage. It works as if multiple clients are accessing the server.</p>
<p><strong>Step 3</strong> - Create a read replica(s) from our RDS instance</p>
<p><strong>Step 4</strong> - Use <a target="_blank" href="https://aws.amazon.com/route53/">Route53</a> to distribute read requests across multiple RDS read replicas.</p>
<p><strong>Step 5</strong> - Run the same benchmark queries leveraging Route53 record sets.</p>
<h2 id="heading-create-a-single-amazon-rds-instance">Create a single Amazon RDS Instance</h2>
<ul>
<li>Navigate to the AWS console and search for RDS</li>
<li>For the database creation method, select the Standard create option.</li>
<li>Select MySQL for the Engine options.</li>
</ul>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/create-mysql-database.png" alt="Create Database" /></p>
<ul>
<li>Select Production template</li>
<li>Select Single DB instance for Availability and durability (in production, you will want to use Multi-AZ)</li>
</ul>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/rds-templates.png" alt="RDS templates" /></p>
<ul>
<li>On the Settings screen, enter the password and leave the rest of the settings as is.</li>
<li>For instance configuration, select Burstable classes and choose at least a db.t3.medium instance size (we need more memory to enable Performance Insights)</li>
<li>For Storage type, select General Purpose SSD (gp2) and keep the rest of the settings default.</li>
<li>In terms of Connectivity, keep the default settings, maintaining No public access for the database instance. You can optionally create a new VPC if you like.</li>
<li>For Database authentication, select Password authentication</li>
<li>Under Monitoring, make sure Turn Performance Insights is checked</li>
<li>When done, click the Create Database button to launch your database instance.</li>
</ul>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/instance-configuration-storage.png" alt="Instance configuration" /></p>
<h2 id="heading-benchmark-queries-using-mysqlslap">Benchmark queries using mysqlslap</h2>
<p>We can run the benchmark queries in an Amazon <a target="_blank" href="https://aws.amazon.com/ec2/">EC2</a> instance or <a target="_blank" href="https://aws.amazon.com/cloud9/">AWS Cloud9</a> environment. Our database instance is not accessible publicly, so we need to access it within our VPC. I’m going to use the Cloud9 environment. AWS Cloud9 is a cloud-based integrated development environment (IDE) that allows you to write, run and debug code via the browser.</p>
<h3 id="heading-cloud9-setup">Cloud9 Setup</h3>
<h4 id="heading-create-environment">Create environment</h4>
<ol>
<li>Navigate to your AWS console and search for Cloud9.</li>
<li>Click on the Create environment button.</li>
<li>Provide a name for your environment.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/cloud9-1-environment-name.png" alt="Cloud9 env name" /></p>
<ol>
<li>Click next, and you should be ok with the default settings.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/cloud9-2-environment-settings.png" alt="Cloud9 settings" /></p>
<ol>
<li><p>Proceed with all the remaining steps and create your environment. The creation process may take a few minutes.</p>
</li>
<li><p>Give Cloud9 permission to access MySQL. Our Cloud9 environment will need permission to access our database instance. We achieve that by going to the instance’s security group and adding an inbound rule that allows MySQL traffic from our Cloud9 instance as below:</p>
</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/cloud9-mysql-access.png" alt="Cloud9 mysql access" /></p>
<h4 id="heading-clone-sample-database-repository">Clone sample database repository</h4>
<p>Next, we must pull in a sample database to test our database instances. The sample database can be found at <a target="_blank" href="https://github.com/datacharmer/test_db">https://github.com/datacharmer/test_db</a>, and you can also read more about it at <a target="_blank" href="https://dev.mysql.com/doc/employee/en/">https://dev.mysql.com/doc/employee/en/</a>.</p>
<p>AWS Cloud9 EC2 environments come preinstalled with Git. In your Cloud9 environment terminal, run the following commands:</p>
<pre><code class="lang-shell">git clone https://github.com/datacharmer/test_db.git &amp;&amp; cd test_db
</code></pre>
<p>Run the script to create the database schema and load the data. Replace the host with your own database DNS endpoint.</p>
<pre><code class="lang-shell">mysql -h database-1.ctlblrdarm7c.us-east-1.rds.amazonaws.com \ 
-u admin -p \
-t &lt; employees.sql \
</code></pre>
<blockquote>
<p>If you get an error similar to ERROR 2002 (HY000): Can't connect to MySQL server on … go back and make sure your Cloud9 environment security group has inbound permission to your database instance security group.</p>
</blockquote>
<p>Otherwise, you should see output similar to below:</p>
<pre><code class="lang-bash">mysql -h database-1.ctlblrdarm7c.us-east-1.rds.amazonaws.com \ 
-u admin -p -t &lt; employees.sql 
Enter password: 
+-----------------------------+
| INFO                        |
+-----------------------------+
| CREATING DATABASE STRUCTURE |
+-----------------------------+
+------------------------+
| INFO                   |
+------------------------+
| storage engine: InnoDB |
+------------------------+
+---------------------+
| INFO                |
+---------------------+
| LOADING departments |
+---------------------+
+-------------------+
| INFO              |
+-------------------+
| LOADING employees |
+-------------------+
+------------------+
| INFO             |
+------------------+
| LOADING dept_emp |
+------------------+
+----------------------+
| INFO                 |
+----------------------+
| LOADING dept_manager |
+----------------------+
+----------------+
| INFO           |
+----------------+
| LOADING titles |
+----------------+
+------------------+
| INFO             |
+------------------+
| LOADING salaries |
+------------------+
+---------------------+
| data_load_time_diff |
+---------------------+
| 00:00:39            |
+---------------------+
</code></pre>
<h3 id="heading-run-mysqlslap-on-primary-instance">Run mysqlslap on primary instance</h3>
<p>We are going to use the following mysqlslap command to emulate load on our primary database instance.</p>
<pre><code class="lang-bash">mysqlslap -h database-1.ctlblrdarm7c.us-east-1.rds.amazonaws.com -u admin -p \
--concurrency=10 \
--iterations=15 \
--create-schema=employees \
--query=<span class="hljs-string">"SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager;SELECT * FROM departments;"</span> --delimiter=<span class="hljs-string">";"</span> \
--verbose
</code></pre>
<p>Let’s explain some of the mysqlslap options.</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Option</td><td>Explanation</td></tr>
</thead>
<tbody>
<tr>
<td>concurrency</td><td>Number of clients to simulate when issuing the SELECT statement</td></tr>
<tr>
<td>iterations</td><td>Number of times to run the tests</td></tr>
<tr>
<td>create-schema</td><td>Schema in which to run the tests</td></tr>
</tbody>
</table>
</div><p><em>Database load sliced by Waits</em></p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/primary-load.png" alt="Primary load" /></p>
<p><em>Database load sliced by SQL queries</em></p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/primary-load-sql.png" alt="Primary load sql" /></p>
<h2 id="heading-create-read-replicas">Create read replicas</h2>
<p>Now let’s create our read replicas.</p>
<ol>
<li>Navigate to your AWS RDS console</li>
<li>Select your primary database instance, and from the Actions drop-down click <strong>Create read replica</strong>
<img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/create-read-replica.png" alt="Create read replica" /></li>
<li>Add a title for your read replica as below. Keep the other defaults and create the replica
<img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/replica-title.png" alt="Replica title" /></li>
<li>Repeat the step above and create a second replica named database-1-replica-2. When you are done, you will have a primary instance and two replicas as below.
<img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/replica-list.png" alt="Replica list" /></li>
</ol>
<p>Each database instance (including replicas) will have a unique DNS connection string. However, if we were in an application, we wouldn’t want to manage connecting to the different strings. Also, if we add or remove a replica, we will need to update the connection strings in our application. A good practice would be to use Route 53 to distribute read requests across multiple Amazon RDS instances. Therefore, we will tackle that next.</p>
<h2 id="heading-use-route-53-to-load-balance-amazon-rds-read-replicas">Use Route 53 to load balance Amazon RDS read replicas</h2>
<p>We will use Amazon Route 53 weighted record sets to distribute requests across our read replicas. Weighted routing lets us associate multiple resources with a single domain name or subdomain. It allows us to choose how much traffic is routed to each resource.</p>
<h3 id="heading-create-route-53-hosted-zone">Create Route 53 hosted zone</h3>
<ol>
<li>Search for Route 53 in the AWS console.</li>
<li>Navigate to Hosted Zones and select <strong>Create hosted zone</strong>.</li>
<li>Enter any Domain name and select a <strong>Private hosted zone</strong> for the type. Our database instances are only accessible within the VPC. Any domain name works here because we are creating a private hosted zone.
<img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/route53-create-hosted-zone.png" alt="Create hosted zone" /></li>
<li>Select the same VPC that your database instances are launched in
<img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/route53-hosted-zone-private-type.png" alt="Create hosted zone" /></li>
<li>Click Create hosted zone</li>
</ol>
<h3 id="heading-create-hosted-zone-cname-records">Create hosted zone CNAME records</h3>
<p>Now that we have our hosted zone created, the next task is the creation of our zone CNAME records. Each database instance DNS endpoint will map to a specific CNAME record. We will still accept reads on our primary database instance, so we will add a record for the primary instance.</p>
<ol>
<li>Create the primary database instance CNAME record by clicking Create record. Fill in the form with the following fields:</li>
</ol>
<p><strong>Record name</strong> - db</p>
<p><strong>Record type</strong> - CNAME</p>
<p><strong>Value</strong> - YOUR_PRIMARY_DATABASE_DNS_ENDPOINT</p>
<p><strong>TTL</strong> - 60</p>
<p><strong>Routing policy</strong> - Weighted</p>
<p><strong>Weight</strong> - 100</p>
<p><strong>Record ID</strong> - ANY_UNIQUE_VALUE_WITHIN_RECORDS</p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/route53-primary-record.png" alt="Create hosted zone" /></p>
<ol>
<li>Repeat the above for the two replicas. Make sure to use DNS endpoints for the replicas in the <strong>Value</strong> field and add unique <strong>Record IDs</strong>. When done, your record list should look as below.</li>
</ol>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/route53-records-list.png" alt="Create hosted zone" /></p>
<p>We should now be able to connect to MySQL using the Record name.
For example, <code>mysql -h db.domain.local -u admin -p</code>. We should only use this record name for reads because database writes will fail when we get routed to replicas (by default, replicas are read-only).</p>
<h2 id="heading-run-mysqlslap-on-primary-instance-and-read-replicas">Run mysqlslap on primary instance and read replicas</h2>
<p>We will use the same mysqlslap command as before. The only change is our database host which is <strong>db.domain.local</strong> this time.</p>
<pre><code class="lang-bash">$ mysqlslap -h db.domain.local -u admin -p \
--concurrency=10 \
--iterations=15 \
--create-schema=employees \
--query=<span class="hljs-string">"SELECT * FROM employees;SELECT * FROM titles;SELECT * FROM dept_emp;SELECT * FROM dept_manager;SELECT * FROM departments;"</span> --delimiter=<span class="hljs-string">";"</span> \
--verbose
</code></pre>
<p>After the command is done, give Performance Insights a little time and you should see a difference in database load.</p>
<h4 id="heading-database-load-on-the-primary-instance-before-and-after-adding-read-replicas">Database load on the primary instance before and after adding read replicas.</h4>
<p><em>Database load sliced by SQL queries</em></p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/primary-load-sql-with-replicas.png" alt="sql load with replicas" /></p>
<p><em>Database load sliced by Waits</em></p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/primary-load-with-replicas.png" alt="sql load with replicas" /></p>
<p><img src="https://raw.githubusercontent.com/musonza/blog-images/master/2022-11/primary-counter.png" alt="sql load with replicas" /></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>As you can see, for the same queries and clients, the load is reduced on our primary database instance because we are offloading some of the reads to our read replicas. Our primary database instance can take care of writes without being swamped with reads. You can even go further and only use the primary database for writes only. You can achieve that by deleting the primary database CNAME record from Route 53 or by setting the weight value to a value of zero. We could also have created a CNAME record for writes and routed our write traffic via Route 53.</p>
]]></content:encoded></item><item><title><![CDATA[Implement the Commanding Pattern]]></title><description><![CDATA[What is the Command Pattern

In object oriented programming, the command pattern is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time.

The informatio...]]></description><link>https://musonza.dev/implement-the-commanding-pattern</link><guid isPermaLink="true">https://musonza.dev/implement-the-commanding-pattern</guid><category><![CDATA[PHP]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Wed, 19 Jul 2017 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/7JX0-bfiuxQ/upload/81a7891bef16188042a4231a944d74fa.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<h2 id="heading-what-is-the-command-pattern">What is the Command Pattern</h2>
<blockquote>
<p>In object oriented programming, the command pattern is a behavioral design pattern in which an object is used to encapsulate all information needed to perform an action or trigger an event at a later time.</p>
</blockquote>
<p>The information that is encapsulated in a commanding object includes the method name, the object that owns the method, and values for the method parameters. So, in other words, the commanding entity will have enough information to take action immediately or later.</p>
<h2 id="heading-example-usage">Example Usage</h2>
<p>Let’s take, for example, the method below that sends a message to other users in a conversation in a chat application.</p>
<pre><code class="lang-php"><span class="hljs-comment">/**
 * Sends a message
 *
 * <span class="hljs-doctag">@param</span> Conversation $conversation
 * <span class="hljs-doctag">@param</span> array $data contains message body and any other relevant information
 * <span class="hljs-doctag">@param</span> User $sender
 *
 */</span>
<span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">send</span>(<span class="hljs-params">$conversation, $data, $sender</span>)
</span>{
    <span class="hljs-comment">//Step 1. Send a message by adding the $sender message to the $conversation</span>

    <span class="hljs-comment">//Step 2. Maybe we are sending a huge file and would rather que that for processing and let the other part of an incoming file</span>

    <span class="hljs-comment">//Step 3. Send a push notification to each user in the $conversation</span>

    <span class="hljs-comment">//Step 4. Send an email notification to each user in the $conversation</span>

    <span class="hljs-comment">//Step 5. Store notifications in the database for each user in the $conversation</span>

    <span class="hljs-comment">//Step 6. Tell the sender that their message has been sent</span>
}
</code></pre>
<p>We could start coding our application and implement all the above steps in the send() function. However, by doing that, we are well on our way to writing code that is not efficient and may not be easy to maintain. For instance, the is no reason why Step 4 above should wait for items like sending notifications. So what if we can move all those steps somewhere else? That’s where the Commanding pattern can help us.</p>
<p>So let’s attempt to use the commanding pattern instead.</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">Musonza</span>\<span class="hljs-title">Chat</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Musonza</span>\<span class="hljs-title">Chat</span>\<span class="hljs-title">Commanding</span>\<span class="hljs-title">CommandHandler</span>;
<span class="hljs-keyword">use</span> <span class="hljs-title">Musonza</span>\<span class="hljs-title">Chat</span>\<span class="hljs-title">Messages</span>\<span class="hljs-title">SendMessageCommand</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Chat</span> </span>{

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">send</span>(<span class="hljs-params">$conversation, $data, $sender</span>)
    </span>{
        <span class="hljs-comment">//$this-&gt;message refers to Message model</span>
        $command = <span class="hljs-keyword">new</span> SendMessageCommand($conversation, <span class="hljs-keyword">$this</span>-&gt;message, $data, $sender);

        <span class="hljs-comment">//CommandHandler</span>
        <span class="hljs-keyword">$this</span>-&gt;commandHandler-&gt;handle($command);
    }

}
</code></pre>
<p>In the function above, we encapsulate all information needed to send a message in the SendMessageCommand object. Let’s take a look at the <code>SendMessageCommand</code> class:</p>
<h3 id="heading-sendmessagecommand">SendMessageCommand</h3>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">Musonza</span>\<span class="hljs-title">Chat</span>\<span class="hljs-title">Messages</span>;

<span class="hljs-keyword">use</span> <span class="hljs-title">Musonza</span>\<span class="hljs-title">Chat</span>\<span class="hljs-title">Commanding</span>\<span class="hljs-title">Command</span>;

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">SendMessageCommand</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">Command</span>
</span>{
    <span class="hljs-keyword">public</span> $sender;
    <span class="hljs-keyword">public</span> $body;
    <span class="hljs-keyword">public</span> $conversation;

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">__construct</span>(<span class="hljs-params">$conversation, $message, $body, $senderId</span>)
    </span>{
        <span class="hljs-keyword">$this</span>-&gt;conversation = $conversation;
        <span class="hljs-keyword">$this</span>-&gt;message      = $message;
        <span class="hljs-keyword">$this</span>-&gt;data         = $data;
        <span class="hljs-keyword">$this</span>-&gt;sender       = $sender;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">execute</span>(<span class="hljs-params"></span>)
    </span>{
        <span class="hljs-keyword">$this</span>-&gt;message-&gt;send(<span class="hljs-keyword">$this</span>-&gt;conversation, <span class="hljs-keyword">$this</span>-&gt;data, <span class="hljs-keyword">$this</span>-&gt;sender);
    }

}
</code></pre>
<p>As you can see from the command constructor, we are setting the values for parameters that we need to perform our action of sending a message. Below is the interface that all our commands will implement. That way, we are sure each command has an <code>execute()</code> method.</p>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">Musonza</span>\<span class="hljs-title">Chat</span>\<span class="hljs-title">Commanding</span>;

<span class="hljs-comment">/** The Command interface */</span>
<span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">Command</span> </span>{
   <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">execute</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<h3 id="heading-commandhandler">CommandHandler</h3>
<pre><code class="lang-php"><span class="hljs-meta">&lt;?php</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">Musonza</span>\<span class="hljs-title">Chat</span>\<span class="hljs-title">Commanding</span>;

<span class="hljs-comment">/** The Invoker class */</span>
<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">CommandHandler</span> </span>{
   <span class="hljs-keyword">public</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">handle</span>(<span class="hljs-params">$command</span>) </span>{
      <span class="hljs-comment">//here we can store the command or do anything else</span>
      $command.execute();
   }
}
</code></pre>
<h2 id="heading-summary">Summary</h2>
<p>These are the steps we took in sending our chat message using the commanding pattern.</p>
<ol>
<li><p>We made a call to the <code>send()</code> function with all the required information to send a message</p>
</li>
<li><p>We passed on that information to the Commanding object <code>SendMessageCommand.</code></p>
<ul>
<li><p>Now the commanding object knows the information needed to send a new message</p>
</li>
<li><p>We can push this commanding object to a que for later execution or we can execute right away</p>
</li>
</ul>
</li>
<li><p>We then made a call to <code>CommandHandler</code> method <code>handle()</code> which would cause the commanding object to call it’s execution method.</p>
</li>
</ol>
<p>In our case, when the execution method is called, we send the message by making this call:</p>
<p><code>$this-&gt;message-&gt;send($this-&gt;conversation, $this-&gt;data, $this-&gt;sender);</code></p>
<p>Note: The code presented here is shortened. Feel free to <a target="_blank" href="https://github.com/musonza/chat">checkout a Laravel Package</a> I created that implements the commanding pattern.</p>
]]></content:encoded></item><item><title><![CDATA[Picking the right AWS services for your application]]></title><description><![CDATA[I will discuss using Amazon Web Services (AWS) to develop applications in this post. We will go over which services make more sense and how to use the services cost-effectively and efficiently. AWS offers many services, so we will only be able to cov...]]></description><link>https://musonza.dev/picking-the-right-aws-services-for-your-application</link><guid isPermaLink="true">https://musonza.dev/picking-the-right-aws-services-for-your-application</guid><category><![CDATA[AWS]]></category><category><![CDATA[Amazon Web Services]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Wed, 17 Aug 2016 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/PEm_sLmJT-w/upload/1a030b88314709c3693abd644db32599.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>I will discuss using Amazon Web Services (AWS) to develop applications in this post. We will go over which services make more sense and how to use the services cost-effectively and efficiently. AWS offers many services, so we will only be able to cover some of them. Here are some you should know about.</p>
<h2 id="heading-security">Security</h2>
<p>While AWS has created a secure cloud infrastructure, it is essential to note that security is not Amazon's sole responsibility. Instead, Amazon uses the Shared Responsibility Model, which states that AWS manages the security of the cloud, and security in the cloud is the customer's responsibility.</p>
<h3 id="heading-iam-roles">IAM Roles</h3>
<p>When you have EC2 instances and your application needs to access other AWS services (like SNS, S3, etc.), there are two ways to grant permission to your EC2 instances. You can either manually assign credentials to the instance or use IAM Roles.
The best practice is always to use the latter. Manually assigned credentials need to be rotated frequently, which can be messy when you have a lot of instances. You also risk getting the credentials extracted; thus, your applications are more vulnerable.</p>
<p>So, unless you connect from outside AWS (like your computer), you always need to use IAM Roles to grant permission.</p>
<h2 id="heading-storage-and-content-delivery">Storage and Content delivery</h2>
<h3 id="heading-simple-storage-service">Simple Storage Service</h3>
<p>Data storage for your applications can be costly. There are a few factors to consider when storing data on AWS. These factors include; how often is the data accessed? How fast should be the data retrieval process? Can the data be reproduced easily? How long should the data be available?</p>
<p>A popular storage service on AWS is Simple Storage Service (S3). S3 can serve objects through a CDN to Cloudfront, can serve HTML files with Route 53, and allows managed access and versioning of objects. With S3, you can set lifecycle policies for your objects. For instance, you can specify a policy that deletes or archives your objects to Amazon Glacier after a certain period.</p>
<p>So if your application needs frequent access to the data, S3 is a service of your choice. You can further reduce your cost using S3 Reduced Redundancy Storage(RRS) instead of S3 standard storage. However, it would be best to use only RRS for easily reproducible data (thumbnails, etc.) or for that you can afford to lose.</p>
<p>If you have data that your application doesn't need to frequently access and when accessed, the retrieval time is not of importance; Amazon Glacier would be suitable. Amazon Glacier offers an archival storage type. Checking in and checking out items in Amazon Glacier can take several hours, hence the use for archival purposes only.</p>
<h2 id="heading-databases">Databases</h2>
<h3 id="heading-relational-databases">Relational databases</h3>
<p>If your application needs to use a relational database, AWS offers RDS, a fully managed database for relational databases. Being a fully managed database means Amazon will handle the underlying software updates and patches. RDS supports the following databases: PostgreSQL, MySQL, Oracle, SQL, and Aurora. Aurora is just a more efficient fork of MySQL, and Amazon recommends using Aurora in production environments.</p>
<p>Another recommendation in production is RDS Multi-AZ deployment. When a Multi-AZ DB Instance is provisioned, AWS automatically creates a primary DB instance and synchronously replicates the data to a standby instance in a different Availability Zone. In the event of a failure on the primary DB instance infrastructure, AWS will perform an automatic failover to the standby database. There will be minimal or no downtime at all experienced by your application. Multi-AZ deployment is also important when AWS updates and patches the underlying database software. AWS will update primary and standby database asynchronously meaning your application is not affected.</p>
<h3 id="heading-nosql">NoSQL</h3>
<blockquote>
<p>Update: AWS now has Amazon DocumentDB service. <a target="_blank" href="https://aws.amazon.com/documentdb/">Amazon DocumentDB</a> is a scalable, highly durable, and fully managed database service for operating mission-critical MongoDB workloads.</p>
</blockquote>
<p>A popular NoSQL database in the community is MongoDB. Usually, if they want to keep all the services on AWS, developers set up a MongoDB database on an EC2 instance. That means as a developer, you are responsible for any software updates to your database and ensuring the database is secure from the outside world. You also have to make sure the database is scalable. This sounds like a lot of work and responsibility already. An alternative would be DynamoDB, a fully managed NoSQL database service provided by AWS. DynamoDB is fully distributed and auto-scales which makes it fault-tolerant. AWS also manages the provisioning of all underlying hardware. You can specify the required throughput capacity as a developer, and DynamoDB will handle the rest.</p>
<h3 id="heading-caching">Caching</h3>
<p>You can further improve the performance of your application by implementing caching. For instance, you can cache database query results to avoid constantly hitting the database. You can also cache web sessions and any dynamically generated content. Amazon ElastiCache, a fully managed in-memory cache engine can be used with Redis or Memcached to achieve this.</p>
<h2 id="heading-deployment-services">Deployment Services</h2>
<h3 id="heading-elastic-beanstalk">Elastic Beanstalk</h3>
<p>If you want to get up and running quickly or don’t have the technical knowledge for building application environments, Elastic Beanstalk can be a deployment service of your choice. With Elastic Beanstalk, you can quickly deploy an entire application environment automatically. The service integrates with other AWS services, including Elastic Load Balancer, Auto Scaling, and EC2.</p>
<h3 id="heading-amazon-cloudformation">Amazon CloudFormation</h3>
<p>CloudFormation offers developers an easy way to create and manage a collection of related AWS resources. It is essentially Infrastructure as code as CloudFormation templates are merely JSON files. This can be useful if you are to scale your application; you can use a CloudFormation template to build EC2 instances that belong to an Elastic Load Balancer. You can also use the templates in disaster recovery, reducing the time required to spin up a new environment.
This was just an overview of the services that Amazon AWS has to offer. There are many essential services we didn’t cover, including Networking (Virtual Private Cloud, DNS etc.)</p>
]]></content:encoded></item><item><title><![CDATA[API Design Tips and Pitfalls]]></title><description><![CDATA[Most mobile and distributed applications have an API to plug into quickly, and almost every application uses at least one. Everyone is doing it! But only some people are doing it right. Creating a rich API that can be easily scaled requires planning....]]></description><link>https://musonza.dev/api-design-tips-and-pitfalls</link><guid isPermaLink="true">https://musonza.dev/api-design-tips-and-pitfalls</guid><category><![CDATA[APIs]]></category><category><![CDATA[REST API]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Tue, 05 Jul 2016 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/ehyV_XOZ4iA/upload/bba4c3778bc2114bb983c009bddbb69d.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Most mobile and distributed applications have an API to plug into quickly, and almost every application uses at least one. Everyone is doing it! But only some people are doing it right. Creating a rich API that can be easily scaled requires planning. Unfortunately, most APIs developed these days, once deployed, can't be changed. Doing so usually breaks the client's code that relies on the API. So while it's good to remain consistent, we should give our APIs room for extension.</p>
<p>We believe API design should follow an open/closed principle: "software entities should be open for extension but closed for modification." Applying this principle will help your API evolve as the industry changes. Here are some of the best practices and pitfalls we've discovered to help you build a great API yourself.</p>
<h2 id="heading-use-nouns-instead-of-verbs-restful">Use nouns instead of verbs  (RESTful)</h2>
<h3 id="heading-verb-resources-bad-practice">Verb resources (bad practice)</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Method</td><td>URI</td></tr>
</thead>
<tbody>
<tr>
<td>GET</td><td>/getAllPhotos</td></tr>
<tr>
<td>POST</td><td>/addPhoto</td></tr>
<tr>
<td>PUT</td><td>/updatePhoto</td></tr>
<tr>
<td>DELETE</td><td>/deletePhoto</td></tr>
<tr>
<td>PUT</td><td>/updateAllPhotos</td></tr>
<tr>
<td>DELETE</td><td>/deleteAllPhotos</td></tr>
<tr>
<td>GET</td><td>/getPhoto</td></tr>
</tbody>
</table>
</div><p>Developers may be tempted to be as descriptive as possible when structuring API resources. Take, for instance, the table above. Depending on your application's size, using verbs will result in a massive list of URLs. It's hard to keep track of such a list as a developer, but it's even harder for your API consumers as they will need to dig into the documentation for every task. An API should be designed so that users can guess or experiment successfully with the URLs.</p>
<h3 id="heading-noun-resources">Noun resources</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Resource</td><td>GET</td><td>POST</td><td>PUT</td><td>DELETE</td></tr>
</thead>
<tbody>
<tr>
<td>/photos</td><td>Return list of all photos</td><td>Add a new photo</td><td>Bulk update all photos</td><td>Delete all photos</td></tr>
<tr>
<td>/photos/3</td><td>Return a specific photo</td><td><strong>error</strong></td><td>Update a specific photo</td><td>Delete a specific photo by identifier</td></tr>
</tbody>
</table>
</div><p>Above is an example of how we can structure our resources better and make the API easier to use. For example, we only need two resources, <strong>/photos</strong> and <strong>/photos/:id</strong>, in conjunction with four HTTP verbs (GET, POST, PUT, DELETE) to be able to perform the operations in our previous colossal list.</p>
<h2 id="heading-use-transformers-for-data-presentation">Use Transformers for data presentation</h2>
<p>Another bad practice is querying the database and dumping everything as an API response. Instead, I recommend using transformers over dumping the database data to the world.</p>
<p>Transformers give you control over what data you output to your API consumers. With transformers, we are confident that sensitive information is not displayed by mistake. Not only is it a security measure, but transformers will also help prevent API consumers' code from breaking when your database schema changes.</p>
<p>While you can build your transformers easily, I recommend <a target="_blank" href="http://fractal.thephpleague.com/">Fractal</a> if you are in the PHP world. With transformers, you are afforded the benefit of serializing your data in a specific way and embedding related resources within each other.</p>
<h2 id="heading-error-handling">Error handling</h2>
<h3 id="heading-use-http-status-codes">Use HTTP status codes</h3>
<p>While there are more than a dozen status codes, we only need ten codes for REST. Your API consumers will know how to respond to the errors since the status codes are a standard. It would be best if you didn’t make your consumers rely on the error messages to determine how to proceed from an error. Below are the ten status codes you need to use:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>200</td><td>The request has succeeded</td></tr>
</thead>
<tbody>
<tr>
<td>201</td><td>Resource successfully created</td></tr>
<tr>
<td>204</td><td>Request fulfilled but no content returned</td></tr>
<tr>
<td>304</td><td>Request not modified</td></tr>
<tr>
<td>400</td><td>Bad request. Reqeuest can not be understood by the server due to malformed syntax</td></tr>
<tr>
<td>401</td><td>Unauthorized. The request requires user authentication</td></tr>
<tr>
<td>403</td><td>Forbidden</td></tr>
<tr>
<td>404</td><td>Not found. Server can not find requested resource</td></tr>
<tr>
<td>409</td><td>Conflict. Request can not be completed due to conflict with the current state</td></tr>
<tr>
<td>500</td><td>Internal Server Error</td></tr>
</tbody>
</table>
</div><p>So don’t just return HTTP status code 200 for every request.</p>
<h3 id="heading-error-codes-and-messages">Error Codes and Messages</h3>
<p>Apart from returning the correct HTTP status codes, it also helps to return custom error codes and verbose error messages for your API. These will go a long way if you have to offer support to your API consumers. Knowing the error code and message will make it easy to pinpoint the issue in your code.</p>
<h2 id="heading-documentation">Documentation</h2>
<p>Are you happy to use an API without documentation? I’m hoping you answered “no.” So while documentation may be painful, you have to do it. Good resource documentation should at least include the following:</p>
<ul>
<li>Resource URL (https://api.example.com/photo/:id)</li>
<li>Resource Information (Description, Response formats including - JSON and XML, Requires authentication?)</li>
<li>Parameters (specify required/optional)  and give examples</li>
<li>Example request</li>
<li>Example result</li>
</ul>
<p>Including usage examples and tutorials will be a plus.</p>
<p>Including usage examples and tutorials will be a plus.</p>
<h2 id="heading-authentication">Authentication</h2>
<p>Another critical aspect of API design is authenticating and protecting our applications. Below are some strategies you can use to authenticate clients using your API.</p>
<h3 id="heading-http-basic-authentication">HTTP Basic authentication</h3>
<p>This is a standard HTTP authentication mechanism whereby clients supply a username and password BASE64 encoded in the “Authorization” header.</p>
<h3 id="heading-oauth2">Oauth2</h3>
<p>Ouath2 comprise of the following two:</p>
<ol>
<li>user/client credentials to use in getting an access token</li>
<li>Use the access token to access the API resources</li>
</ol>
<p>However, since this involves transmitting access tokens and authentication credentials, Oauth2 is only secure if used with TLS/SSL to encrypt data during transmission. You also need to consider storing the client credentials on clients like mobile applications. There is a debate about this, as keeping the credentials for Oauth2 on a mobile or desktop app isn’t the most secure thing to do. If, for instance, our client credentials get compromised, then the Oauth2 provider has to revoke the entire application since we would have that information hard coded.</p>
<p>We have only scratched the surface here. There are a lot of techniques that we could talk about to make our APIs scalable and secure.</p>
]]></content:encoded></item><item><title><![CDATA[The Benefits of Test-Driven Development]]></title><description><![CDATA[Many developers distance themselves from Test-Driven Development (TDD). There is a notion that writing tests is a waste of time. In my experience, I have encountered and written code that I found hard to trust at some points. As a developer, you need...]]></description><link>https://musonza.dev/the-benefits-of-test-driven-development</link><guid isPermaLink="true">https://musonza.dev/the-benefits-of-test-driven-development</guid><category><![CDATA[TDD (Test-driven development)]]></category><category><![CDATA[Testing]]></category><category><![CDATA[General Programming]]></category><dc:creator><![CDATA[Tinashe Musonza]]></dc:creator><pubDate>Wed, 11 May 2016 16:00:00 GMT</pubDate><enclosure url="https://cdn.hashnode.com/res/hashnode/image/stock/unsplash/H9t723yPjYI/upload/aa588cbf7321311865e22ddaf7760550.jpeg" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Many developers distance themselves from Test-Driven Development (TDD). There is a notion that writing tests is a waste of time. In my experience, I have encountered and written code that I found hard to trust at some points. As a developer, you need to have faith in your code; otherwise, you have sleepless nights thinking about a failing code deployment. I have found Test-Driven Development to be of great value in software development, and here are some benefits that I found helpful:</p>
<h2 id="heading-decoupling">Decoupling</h2>
<p>Test-Driven Development forces you to write tests before implementation. This, in turn, causes you to be concise since you must define your input and expectations before writing any code. When your code is derived from tests, you inevitably separate the different pieces as much as possible. Decoupled code is easily maintainable.</p>
<h2 id="heading-up-to-date-documentation">Up to date documentation</h2>
<p>While it seems like a good idea to only rely on a living document, as time goes on and developers add more features or fix bugs, that document usually becomes neglected. However, enforcing TDD means developers must add new tests for new features or write regression tests for bugs. As a result, tests can act as documentation that must stay updated.</p>
<h2 id="heading-refactor-with-confidence">Refactor with confidence</h2>
<p>Have you ever been unable to refactor code because of the fear that something will break? I have seen code that cries out loud for refactoring (including some code I have written in the past). I have sat there and watched classes grow into monster objects with duplicates because refactoring would be like opening a pandora's box. With tests, you can refactor code confidently because you are always going to run tests after each refactor, and if the test fails, you can immediately revert it.</p>
<h2 id="heading-minimize-deployment-errors">Minimize deployment errors</h2>
<p>If you are often afraid to deploy to production because the result is unknown, TDD can help you allay those fears. Writing code without bugs doesn't mean that it works. Adding new features to a project will be a manageable task. I have worked on projects where I have come back a few months or years later to add features. Without written tests, I always had to keep my fingers crossed that nothing broke. Well-written tests will eliminate this headache as the tests will provide constant feedback that each component is still working.</p>
]]></content:encoded></item></channel></rss>