<?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" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Juan Matías de la Cámara Beovide on Medium]]></title>
        <description><![CDATA[Stories by Juan Matías de la Cámara Beovide on Medium]]></description>
        <link>https://medium.com/@juanmatias_25470?source=rss-29d82e4f478a------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*hBwygEu0DSPxQCxE.</url>
            <title>Stories by Juan Matías de la Cámara Beovide on Medium</title>
            <link>https://medium.com/@juanmatias_25470?source=rss-29d82e4f478a------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Mon, 25 May 2026 22:23:48 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@juanmatias_25470/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Do you want light? Left the fire, embrace a dynamo]]></title>
            <link>https://medium.com/binbash-inc/do-you-want-light-left-the-fire-embrace-a-dynamo-b1c232ac841f?source=rss-29d82e4f478a------2</link>
            <guid isPermaLink="false">https://medium.com/p/b1c232ac841f</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[firebase]]></category>
            <category><![CDATA[dynamodb]]></category>
            <category><![CDATA[aws-dynamodb]]></category>
            <dc:creator><![CDATA[Juan Matías de la Cámara Beovide]]></dc:creator>
            <pubDate>Tue, 20 Jan 2026 14:07:25 GMT</pubDate>
            <atom:updated>2026-01-20T14:07:25.844Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*K-udAQ4943pFjA4naalDJQ.png" /></figure><h3>TL;DR</h3><p>Moving from <strong>Firebase to AWS DynamoDB</strong> often hits a roadblock: replicating Firebase’s granular, per-user security rules.</p><p>At <a href="http://www.binbash.co"><strong>binbash</strong></a>, we’ve developed a research project, <strong>research-dynamodb-access-rules</strong>, which demonstrates how to implement fine-grained access control in <strong>DynamoDB</strong> using IAM policy variables to match the ease of Firebase’s security model.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZnCM4X1cI_uKrepoShlJAQ.png" /></figure><h3>The Story: From “It Just Works” to “How Do We Scale?”</h3><p>Meet Alex and Sam, two developers who started a small project on GCP using Firebase. For their MVP, <strong>Firebase</strong> was a dream; the <strong>declarative access rules</strong> allowed them to secure user data with just a few lines of code. It was the perfect environment for rapid prototyping.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TBniYNuhkUOpu3AEAUDWiQ.png" /></figure><p>However, as their project evolved into a full-scale application, their needs changed. They required the broader enterprise ecosystem, advanced networking, and cost-efficiency at scale that <strong>AWS</strong> provides. The decision was made: it was time to migrate to <strong>Amazon DynamoDB</strong>.</p><p>The transition seemed straightforward until they hit a wall. In Firebase, saying “only the owner can read this record” is simple. In AWS, managing individual permissions for thousands of users via IAM felt like a daunting architectural shift. They didn’t want to build a complex middleware proxy just to handle basic data security.</p><p>We, at <strong>binbash</strong>, partnered with them to find a solution. We didn’t want Alex and Sam — or any developer — to lose the simplicity of “rules-based” access just because they moved to a more robust cloud provider.</p><p>Our research focused on utilizing <strong>IAM Policy Variables</strong> and <strong>Condition Keys</strong> to mimic the Firebase experience directly within AWS. By mapping Cognito identities to DynamoDB partition keys, we proved that you can achieve the same “owner-only” or “group-based” access without the overhead.</p><h3>Explore the Research</h3><p>You can find the full implementation, Leverage (OpenTofu/Terraform) configurations, and access rule logic in our official repository:</p><ul><li><strong>Repository:</strong> <a href="https://github.com/binbashar/le-tf-infra-aws/tree/kungfoo/dynamodb-from-firebase-access-rules/apps-devstg/us-east-1/research-dynamodb-access-rules">binbashar/le-tf-infra-aws</a>.</li></ul><h3>Step-by-Step: Reproducing the Access Rules</h3><h4>1. Provisioning the Infrastructure</h4><p>Alex and Sam started by using <strong>binbash Leverage (OpenTofu/Terraform)</strong> to deploy the base environment. This included the DynamoDB table and the necessary Cognito Identity Pools.</p><h4>2. Setting up Cognito Identities</h4><p>To mimic Firebase Auth, they set up an <strong>Amazon Cognito Identity Pool</strong>. This allows users to sign in and receive temporary AWS credentials.</p><ul><li>Ensure users are assigned a unique Cognito Identity ID. This ID is the “Source of Truth” for their data ownership.</li><li>Since they already have a user base in FireBase, and it does not provide an &quot;export user&quot; method, we propose Alex and Sam to use <a href="https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-import-using-lambda.html">this</a> user migration solution.</li></ul><h4>3. Crafting the “Firebase-style” IAM Policy</h4><p>This is where the magic happened. Instead of writing a policy for every user, they wrote <strong>one dynamic policy</strong> using <strong>IAM Policy Variables</strong>.</p><ul><li>They applied a condition to the DynamoDB GetItem and PutItem actions:</li></ul><pre>&quot;dynamodb:LeadingKeys&quot;: [&quot;${cognito-identity.amazonaws.com:sub}&quot;]</pre><ul><li>This rule ensures the user can only access items where the <strong>Partition Key</strong> matches their own <strong>Cognito Sub ID</strong>.</li></ul><h4>4. Data Partitioning</h4><p>Sam adjusted the application logic to ensure that every time a record was created, the <strong>Partition Key (PK)</strong> was automatically set to the user’s unique Identity ID. This mirrored the way they used to structure collections in Firebase.</p><h4>5. Verification and Testing</h4><p>Finally, they used the AWS CLI and a small test script (included in the repo) to verify:</p><ul><li><strong>Success:</strong> User A can read/write their own data.</li><li><strong>Failure:</strong> User A receives an AccessDeniedException when trying to access User B’s Partition Key.</li></ul><h3>Conclusion</h3><p>Migrating from <strong>Firebase</strong> to our <strong>DynamoDB-based solution</strong> is a strategic move for teams looking to grow.</p><ol><li><strong>Granular Security at Scale:</strong> You maintain the fine-grained control of Firebase while leveraging AWS’s global infrastructure.</li><li><strong>Reduced Complexity:</strong> By using IAM policy variables, you eliminate the need for custom “security layers” in your application code.</li><li><strong>Enterprise Integration:</strong> It places your data security within the <strong>AWS IAM</strong> framework, making it easier to pass security audits and integrate with other AWS services.</li><li><strong>Cost Efficiency:</strong> DynamoDB’s pricing model, combined with direct client-to-database access patterns (secured by these rules), can significantly reduce operational costs for high-traffic apps.</li></ol><p>By bridging the gap between <strong>Firebase</strong>’s simplicity and <strong>AWS</strong>’s power, we’ve ensured that scaling your infrastructure doesn’t mean compromising on your development velocity.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b1c232ac841f" width="1" height="1" alt=""><hr><p><a href="https://medium.com/binbash-inc/do-you-want-light-left-the-fire-embrace-a-dynamo-b1c232ac841f">Do you want light? Left the fire, embrace a dynamo</a> was originally published in <a href="https://medium.com/binbash-inc">binbash</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Staff Augmentation vs Managed Services]]></title>
            <link>https://medium.com/binbash-inc/staff-augmentation-vs-managed-services-d4cf302220cb?source=rss-29d82e4f478a------2</link>
            <guid isPermaLink="false">https://medium.com/p/d4cf302220cb</guid>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[staff-augmentation]]></category>
            <category><![CDATA[cloud-services]]></category>
            <category><![CDATA[service-design]]></category>
            <dc:creator><![CDATA[Juan Matías de la Cámara Beovide]]></dc:creator>
            <pubDate>Fri, 02 Jan 2026 13:46:04 GMT</pubDate>
            <atom:updated>2026-01-02T13:46:04.514Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Bm18aDEt7jdVdPdfcLhlRg.jpeg" /></figure><h3>Beyond “Hands on Deck”: Why Managed Services Outperforms Staff Augmentation</h3><p><strong>Why outcomes don’t come from adding people</strong><br>You want to renovate your house.<br>Not because it’s falling apart.<br>Because it no longer fits the way you live.<br>Walls that once made sense now interrupt movement. Electrical decisions made years ago feel risky. The house still stands, but it’s clearly the product of assumptions that no longer hold.</p><p>At this point, you’re offered a choice.</p><p>You can rent excellent tools. Professional-grade. The same ones real builders use. They arrive on time, well maintained, ready to go. And the moment they’re dropped at your door, something subtle happens: the responsibility shifts. You’re now the architect, the foreman, the project manager, and — when things don’t go exactly as planned — the person explaining why.</p><p>If a wall ends up crooked, the tools won’t argue. They did exactly what they were asked to do.</p><p>Or you can hire a general contractor. Someone who brings tools, yes, but also plans, sequencing, experience, and accountability. Someone who understands that a renovation isn’t a collection of isolated tasks, but a system where early decisions quietly shape everything that follows. You explain what you want the space to become. They take responsibility for getting you there.</p><p>That difference is the cleanest way to understand Staff Augmentation versus Managed Services.</p><blockquote>Staff Augmentation is renting the tools.<br>Managed Services is entering a partnership.</blockquote><p>Staff Augmentation tends to be framed as speed. A fast way to fill a gap. A pragmatic response to pressure. “We just need another engineer.” The sentence sounds harmless. Almost obvious.<br>But what usually follows is less obvious.</p><p>That engineer doesn’t arrive into a vacuum. They arrive into a system that already has architecture, habits, blind spots, and unspoken assumptions. And suddenly, the client becomes responsible not only for <em>what</em> needs to be done, but for <em>how</em>, <em>in what order</em>, <em>with which trade-offs</em>, and <em>toward what long-term direction</em>.</p><p>The augmented resource executes. The burden of thinking, aligning, correcting, and absorbing risk stays on the client.<br>Managed Services starts from a different premise: that most technical problems aren’t caused by a lack of hands, but by a lack of shared responsibility.</p><p>In a Managed Services model, you don’t hire an individual. <strong>You form an alliance.</strong><br>An alliance means the provider doesn’t show up asking, “What ticket should I work on?”<br>They show up asking, “What outcome are we accountable for?”</p><p>Execution is still there — good execution, disciplined execution — but it’s supported by technical leadership, delivery ownership, and a roadmap that exists to be challenged, refined, and defended. Architecture is part of the conversation from day one, not something you circle back to once things hurt.</p><p>This is where the difference between a partner and a provider becomes impossible to ignore.</p><p>A provider wears their own jersey. Their incentive is clear: maximize utilization, log hours, stay busy. If priorities are unclear, if decisions are short-sighted, if technical debt piles up, that’s unfortunate — but it’s not their problem.<br>A partner wears the project’s jersey.<br>In a real partnership, success and failure are shared. If something isn’t working, it gets surfaced early. If a decision feels wrong, it gets challenged. If the roadmap needs to change, it changes — not because hours are being sold, but because outcomes matter.<br>That shared accountability changes how risk behaves.<br>With Staff Augmentation, risk is quietly transferred to the client. If the engineer struggles, the client manages it. If knowledge concentrates in one person, the client absorbs it. If the system degrades over time, the client owns the consequences.<br>With Managed Services, risk is designed into the relationship and actively managed. Delivery managers and tech leads exist for one reason: to make sure progress doesn’t depend on heroics, guesswork, or institutional memory living in one head.<br>This is why Managed Services often feels less noisy.</p><p>There are fewer daily clarifications. Fewer tactical interruptions. Fewer moments where progress stalls because no one is quite sure who should decide. Instead of micromanaging tasks, clients participate in planning. Instead of tracking activity, they review direction.</p><p>And despite appearances, this model tends to be more flexible.<br>Because Managed Services is built around evolving roadmaps rather than fixed roles, it adapts to change without renegotiating reality every month.</p><p>Capacity shifts. Focus changes. New constraints appear and are incorporated instead of resisted.<br>Staff Augmentation, for all its apparent simplicity, often locks organizations into rigidity: fixed hours, fixed individuals, fixed expectations — until the business inevitably moves somewhere else.</p><p>In the end, the distinction is not about talent. Great engineers exist everywhere.</p><p>The distinction is about intent.</p><p>Staff Augmentation is transactional.<br>Managed Services is relational.</p><p>One gives you people.<br>The other gives you a team that commits to where you’re going.</p><p>If what you need is temporary capacity, renting tools might be enough.<br>If what you need is a system that holds as you grow, partnerships tend to age better.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d4cf302220cb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/binbash-inc/staff-augmentation-vs-managed-services-d4cf302220cb">Staff Augmentation vs Managed Services</a> was originally published in <a href="https://medium.com/binbash-inc">binbash</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SOC2, ISO27001 and how to meet security]]></title>
            <link>https://medium.com/binbash-inc/soc2-iso27001-and-how-to-meet-security-05e3b1c28a8b?source=rss-29d82e4f478a------2</link>
            <guid isPermaLink="false">https://medium.com/p/05e3b1c28a8b</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[soc2]]></category>
            <category><![CDATA[iso-27001]]></category>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[security]]></category>
            <dc:creator><![CDATA[Juan Matías de la Cámara Beovide]]></dc:creator>
            <pubDate>Thu, 11 Sep 2025 14:57:42 GMT</pubDate>
            <atom:updated>2025-09-11T14:57:42.810Z</atom:updated>
            <content:encoded><![CDATA[<p>At <a href="http://www.binbash.co"><strong>binbash</strong></a><strong>, </strong>an <strong>Advanced AWS Partner</strong>, our mission is to empower organizations like yours to build secure, efficient, and compliant cloud infrastructures. Today, we’re going to dive into a critical topic for many of our clients: <strong>achieving and maintaining compliance </strong>with<strong> ISO 27001 </strong>and<strong> SOC 2</strong> in your existing <strong>AWS </strong>environments, and how <a href="http://www.leverage.binbash.co"><strong><em>binbash Leverage</em></strong></a> can be your accelerator on this journey.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LCYlQTwlUBlFcAMbirdt5w.png" /></figure><h3>TL;DR</h3><p><strong>Fintechs</strong> and <strong>Healthtechs</strong> must adhere to standards such as <a href="https://www.imperva.com/learn/data-security/soc-2-compliance/"><strong>SOC2</strong></a> and <a href="https://www.iso.org/standard/27001"><strong>ISO/IEC 27001</strong></a>. With the <a href="https://aws.amazon.com/architecture/well-architected/?ref=wellarchitected-wp&amp;wa-lens-whitepapers.sort-by=item.additionalFields.sortDate&amp;wa-lens-whitepapers.sort-order=desc&amp;wa-guidance-whitepapers.sort-by=item.additionalFields.sortDate&amp;wa-guidance-whitepapers.sort-order=desc"><strong>AWS Well-Architected</strong></a> and <a href="https://leverage.binbash.co/"><strong>binbash Leverage</strong></a> frameworks, tech teams can deploy well-architected, secure-by-design infrastructure that follows best practices and recommendations <strong><em>up to 10 times faster.</em></strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tZpZUJ6VtjweJEvalL9Wwg.jpeg" /></figure><h3>A Brief Overview</h3><p>Before we detail how to meet these standards, and just in case you are not aware, let’s quickly summarize what they entail:</p><ul><li><strong>ISO/IEC 27001:</strong> This is an <strong>international information security standard</strong> that specifies the requirements for establishing, implementing, maintaining, and continually improving an <strong>Information Security Management System</strong> (ISMS). Its core purpose is to help organizations systematically examine their information security risks — considering threats, vulnerabilities, and impacts — and then design and implement a coherent suite of information security controls or other risk treatments. It ensures that security efforts are not disjointed but are part of an overarching management process that continually meets the organization’s needs. Organizations with an ISMS that meets the standard’s requirements can choose to have it certified by an accredited certification body.</li><li><strong>SOC 2 (Service Organization Control 2):</strong> Developed by the American Institute of CPAs (AICPA), SOC 2 is an <strong>auditing procedure that ensures your service providers securely manage your data</strong> to protect your organization’s interests and the privacy of its clients. For security-conscious businesses, SOC 2 compliance is a minimal requirement when considering a SaaS provider. It defines criteria for managing customer data based on five “Trust Service Principles”: <strong>Security, Availability, Processing Integrity, Confidentiality, and Privacy</strong>. Unlike more rigid standards, SOC 2 reports are unique to each organization, as it designs its own controls to comply with one or more of these principles.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*1GNTIqkLjL2RTvum" /></figure><h3>Disclaimer</h3><blockquote>It is crucial to understand that merely implementing well-architected infrastructure and following good technical practices, while foundational, is not sufficient on its own to achieve full organizational compliance, such as with<strong> ISO/IEC 27001</strong> or <strong>SOC 2</strong>.</blockquote><p>Achieving comprehensive compliance is a <strong><em>broader organizational endeavor</em></strong> that mandates high involvement across the entire organization. This includes:</p><ul><li>Creating wide <strong>procedures</strong> and <strong>policies</strong> that govern information security across all aspects of the business.</li><li>Adopting an overarching <strong>management</strong> <strong>process</strong> to ensure that information security controls continually meet the organization’s evolving needs.</li><li>Promoting a <strong>culture</strong> that consistently honors these standards and practices.</li></ul><h3>Key Compliance Items for ISO 27001 &amp; SOC 2</h3><p>To achieve compliance with these standards, organizations must address several specific areas. Based on our understanding of the standards and AWS best practices, here are some critical items:</p><h4><strong>Systematic Risk Managemen</strong>t:</h4><p>- <strong>ISO 27001</strong> requires management to <strong><em>systematically</em></strong> <strong><em>examine information security risks</em></strong> by taking into account threats, vulnerabilities, and impacts, and then designing/implementing controls to address unacceptable risks.<br>- <strong>SOC </strong>2’s Security principle inherently demands robust <strong><em>risk assessment</em></strong> to protect system resources against unauthorized access and potential abuse.</p><h4><strong>Robust Access Control &amp; Identity Management</strong>:</h4><p>- Both standards emphasize <strong><em>restricting access</em></strong> to information and systems to authorized personnel and processes.<br>- Specifics include: Implementing minimum privilege (<strong><em>least privilege</em></strong>) for all users and systems, enforcing <strong><em>Multi-Factor Authentication</em></strong> (MFA), especially for administrators and privileged accounts, defining <strong><em>roles</em></strong> based on departments or functions, and establishing conditional policies for access based on factors like location, time, or device.</p><h4><strong>Comprehensive Data Protection</strong>:</h4><p>- <strong>ISO </strong>27001’s Security pillar focuses on protecting the <strong><em>confidentiality</em></strong> and <strong><em>integrity</em></strong> of data.<br>- <strong>SOC </strong>2’s <strong><em>Confidentiality</em></strong> and <strong><em>Privacy</em></strong> principles explicitly require restricting data access and disclosure to specified persons or organizations, as well as protecting Personal Identifiable Information (PII) from unauthorized access. <strong><em>Encryption</em></strong> is a crucial control for this.</p><h4><strong>Multi-Level Network and Application Security</strong>:</h4><p>- Protecting against <strong><em>external and internal threats</em></strong> is paramount.<br>- Specifics include: Deploying <strong><em>Web Application Firewalls</em></strong> (WAFs) with rules like <strong><em>OWASP</em></strong> to protect against common web attacks, implementing <strong><em>DDoS</em></strong> protection for critical services, utilizing <strong><em>VPC with private subnets</em></strong> for isolating critical resources, and configuring restrictive<strong><em> Security Groups</em></strong> to control traffic flow at the instance level.</p><h4><strong>Proactive Operational Monitoring &amp; Event Detection</strong>:</h4><p>- <strong>ISO 27001</strong> highlights running and <strong><em>monitoring</em></strong> systems and establishing controls to detect security events.<br>- <strong>SOC 2</strong>’s <strong><em>Security</em></strong> and <strong><em>Availability</em></strong> principles involve continuous <strong><em>monitoring</em></strong> of network performance and availability, as well as robust security incident handling.</p><h4><strong>System Reliability &amp; Availability</strong>:</h4><p>- <strong>ISO 27001</strong>’s <strong><em>Reliability</em></strong> pillar focuses on ensuring workloads perform their intended functions and can recover quickly from failures.<br>- <strong>SOC 2</strong>’s <strong><em>Availability</em></strong> principle directly addresses the accessibility of systems, products, or services as stipulated by contracts or <strong><em>Service Level Agreements </em></strong>(SLAs).</p><h4><strong>Commitment to Continual Improvement</strong>:</h4><p>- <strong>ISO 27001</strong> promotes a culture of continual improvement in information security practices, including regular monitoring, performance evaluation, and periodic reviews to adapt to evolving threats and enhance ISMS effectiveness. <strong><em>This is an ongoing management process</em></strong>.</p><h3>How AWS + binbash Leverage Address These Compliance Items</h3><p>We combine the power of <strong>AWS’s</strong> robust services with our Open Source <a href="https://leverage.binbash.co/"><strong>binbash Leverage framework</strong></a> to help you meet these stringent compliance requirements efficiently and effectively. Our approach is strongly based on and extends the <a href="https://aws.amazon.com/architecture/well-architected/?ref=wellarchitected-wp&amp;wa-lens-whitepapers.sort-by=item.additionalFields.sortDate&amp;wa-lens-whitepapers.sort-order=desc&amp;wa-guidance-whitepapers.sort-by=item.additionalFields.sortDate&amp;wa-guidance-whitepapers.sort-order=desc"><strong>AWS Well-Architected Framework</strong></a>, which provides best practices across its six pillars, including <strong><em>Security</em></strong> and <strong><em>Operational Excellence</em></strong>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*815QsgHCA1uRzX_X3NxM2g.png" /></figure><h3>Here’s how we tackle the aforementioned compliance items:</h3><h4><strong>Foundation: AWS Well-Architected Framework Integration:</strong></h4><p><strong>- </strong>Every solution we deploy using <strong><em>binbash Leverage</em></strong> is designed to be <strong><em>Well-Architected out-of-the-box</em></strong>, ensuring that your infrastructure is secure, reliable, efficient, and cost-effective from day one. <strong><em>This built-in adherence to best practices significantly reduces the effort required for compliance audits.</em></strong></p><h4><strong>Systematic Risk Management &amp; Controls:</strong></h4><p><strong>- <em>AWS Well-Architected Tool</em></strong>: AWS provides a tool to regularly evaluate workloads, identify high-risk issues, and record improvements, directly supporting ISO 27001’s risk assessment and continuous improvement needs.<br>- <strong><em>binbash Leverage Reference Architecture</em></strong>: Our architecture defines opinionated conventions for organizing files and managing configurations, incorporating optimal, secure configurations for modern applications. This proactive approach helps mitigate risks by embedding security into the design.</p><h4><strong>Robust Access Control &amp; Identity Management:</strong></h4><p><strong>- <em>AWS IAM and SSO with Leverage</em></strong>: We leverage AWS IAM and SSO (Identity Center) to implement fine-grained access controls, enabling the principle of <strong><em>minimum privilege</em></strong>. <strong><em>binbash Leverage</em></strong> automates the configuration of IAM and SSO with minimum privilege, implements <strong><em>mandatory MFA</em></strong>, and defines<strong><em> roles based on departments</em></strong> and conditional policies, directly addressing <strong>SOC 2 </strong>and <strong>ISO 27001</strong> access control requirements.<br>- <strong><em>Multi-Account Strategy</em></strong>: Our framework promotes a multi-account approach within <strong><em>AWS Organizations</em></strong>, which inherently enhances <strong><em>security isolation and resource separation</em></strong>, crucial for managing access and blast radius.</p><h4><strong>Comprehensive Data Protection:</strong></h4><p><strong>- <em>AWS Security Pillar</em></strong>: This pillar guides our approach to protecting the <strong><em>confidentiality</em></strong> and <strong><em>integrity</em></strong> of your data, ensuring robust data protection measures are in place.<br>- <strong><em>Leverage’s IaC Library &amp; Secret Management</em></strong>:<strong><em> binbash Leverage</em></strong> provides an Infrastructure as Code (IaC) Library of reusable, tested, production-ready solutions that include secure configurations for data storage and transmission. We also include features for secure<strong><em> secret management</em></strong> and handling <strong><em>security keys</em></strong>, facilitating encryption and protecting sensitive information.</p><h4><strong>Multi-Level Network and Application Security:</strong></h4><p><strong>- <em>Perimeter &amp; Network Security</em></strong> (Level 1): <strong><em>binbash Leverage</em></strong> deploys robust perimeter security measures, including <strong><em>AWS WAF</em></strong> with <strong><em>OWASP</em></strong> rules and <strong><em>CloudFront</em></strong> with <strong><em>DDoS</em></strong> protection, providing multi-layered defense against web attacks and ensuring secure content delivery. We utilize <strong><em>VPC with private subnets</em></strong> for effective resource isolation and configure restrictive <strong><em>Security Groups</em></strong> to precisely control network traffic, aligning with best practices for network segmentation.<br>- Our solutions align with the principles of the <a href="https://docs.aws.amazon.com/prescriptive-guidance/latest/security-reference-architecture/architecture.html"><strong><em>AWS Security Reference Architecture (SRA)</em></strong></a>, integrating various AWS security services for comprehensive protection of your workload.</p><h4><strong>Proactive Operational Monitoring &amp; Event Detection:</strong></h4><p><strong>- <em>Operational Excellence Pillar</em></strong>: This pillar, integral to our framework, focuses on running and monitoring systems effectively and establishing mechanisms to respond to events.<br>- <strong><em>Features: binbash Leverage</em></strong> includes built-in components for monitoring, metrics, logs, tracing, and APM (Application Performance Monitoring). These tools are essential for continuous visibility into your environment, enabling timely detection of security events and ensuring overall system health.</p><h4><strong>System Reliability &amp; Availability:</strong></h4><p><strong>- <em>Reliability Pillar</em></strong>: <strong><em>Leverage</em></strong> adheres to the <strong><em>AWS Reliability</em></strong> pillar, focusing on distributed system design, recovery planning, and adapting to changing requirements.<br>- <strong><em>Features:</em></strong> Our framework directly supports the implementation of <strong><em>highly available </em></strong>and <strong><em>disaster recovery</em></strong> solutions, ensuring your systems remain accessible and resilient, meeting <strong><em>SOC 2’s Availability </em></strong>principle.</p><h4><strong>Commitment to Continual Improvement:</strong></h4><p><strong>- <em>Infrastructure as Code (IaC):</em></strong> A cornerstone of <strong><em>binbash Leverage</em></strong> is its <strong><em>IaC Library</em></strong>, built with OpenTofu/Terraform, Ansible, Helm charts, Dockerfiles, and Makefiles. This enables consistent, repeatable deployments, easy version control, and rapid updates, directly facilitating the <strong><em>“continual improvement” cycle mandated by ISO 27001</em></strong>.<br>- <strong>“Dev First” Approach: </strong>Our recommended “Dev First” approach during migration fosters knowledge transfer within your team, building confidence and a deeper understanding of <strong><em>AWS best practices</em></strong>. This continuous learning and empowerment are vital for ongoing maintenance and improvement.<br>- <strong><em>binbash Leverage</em></strong> helps you to secure your cloud assets and production workloads and achieve compliance in AWS. The best part? <strong><em>We can get your project up and running on AWS up to 10 times faster than traditional consulting methods.</em></strong></p><h3>From Complexity to Compliance</h3><p>Achieving and maintaining compliance with stringent standards like <strong>SOC 2</strong> and <strong>ISO/IEC 27001</strong> can indeed feel like a monumental task. Embarking on this journey from scratch is often a long, complex path fraught with potential missteps and inefficiencies.</p><p>However, by building your project upon very well-known good practices and powerful frameworks, you can significantly accelerate and simplify this process. The <strong>AWS Well-Architected Framework</strong> provides a robust set of best practices and guiding principles for designing and running reliable, secure, efficient, cost-effective, and sustainable cloud systems, organized into six core pillars: <strong><em>Operational Excellence, Security, Reliability, Performance Efficiency, Cost Optimization, and Sustainability</em></strong>.</p><p>Extending these principles, <strong>binbash Leverage</strong> is our framework that condenses years of acquired knowledge and experience into an ecosystem of <strong><em>code</em></strong>, <strong><em>tools</em></strong>, and <strong><em>workflows</em></strong>. It’s specifically designed to help organizations build, provision, and manage their AWS infrastructure quickly and securely.</p><p><strong>binbash Leverage </strong>puts you on track to secure your cloud assets, optimize costs by design, and achieve a compliant baseline in AWS <strong><em>up to 10x faster</em></strong> than traditional methods.</p><p><strong><em>While binbash Leverage lays an incredibly strong and accelerated technical foundation for meeting these standards, it is essential to remember that full compliance with SOC 2 or ISO/IEC 27001 is a holistic organizational commitment.</em></strong> Our framework empowers you with the secure infrastructure and efficient practices, but the broader governance and continuous organizational adherence are mandatory for complete certification.</p><p><strong>Ready to move faster?</strong> <a href="https://www.binbash.co">Talk to our team</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=05e3b1c28a8b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/binbash-inc/soc2-iso27001-and-how-to-meet-security-05e3b1c28a8b">SOC2, ISO27001 and how to meet security</a> was originally published in <a href="https://medium.com/binbash-inc">binbash</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How a Fintech’s 30% Cost Optimization Redefined Its Future]]></title>
            <link>https://medium.com/binbash-inc/how-a-fintechs-30-cost-optimization-redefined-its-future-87394e3ca870?source=rss-29d82e4f478a------2</link>
            <guid isPermaLink="false">https://medium.com/p/87394e3ca870</guid>
            <category><![CDATA[cost-optimization]]></category>
            <category><![CDATA[fintech]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[infrastructure]]></category>
            <category><![CDATA[compliance]]></category>
            <dc:creator><![CDATA[Juan Matías de la Cámara Beovide]]></dc:creator>
            <pubDate>Wed, 08 Jan 2025 13:47:31 GMT</pubDate>
            <atom:updated>2025-01-24T15:03:02.627Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NmdFiJbh4DDKcPKSCydYsQ.png" /></figure><h3>When business met growth</h3><blockquote>Scaling a business is often celebrated as a sign of success.</blockquote><p>Yet, beneath the surface, growth brings its own set of challenges. Operational inefficiencies, rising costs, and the pressure to meet ever-changing customer expectations can quickly erode margins and stifle innovation.</p><p>For <a href="http://www.flexibility.com.ar">Flexibility</a>, a key player in fintech and digital banking solutions based in Argentina, these growing pains had reached a tipping point.</p><p>It was clear that their growth would become unsustainable without a radical shift in approach.</p><h4>Co-authored by Exequiel Barrirero and Juan Matias (KungFoo) De la Camara</h4><p>As the co-founder and CEO of binbash, an AWS Advanced Partner specializing in startups, I’m proud to share this transformation story. Together with <strong><em>KungFoo</em></strong>, we crafted this article to highlight the power of cloud technology and strategic partnerships in driving sustainable growth. This case study showcases the profound impact of leveraging AWS solutions to address real-world business challenges.</p><h3>Back to the Future</h3><p>This is the story of how <strong>flexibility</strong> transformed its operations, <strong>cutting costs by 30%</strong> and positioning itself for long-term success — all through the power of cloud technology and strategic partnership.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3ydaoCmd3yQpKrd4Jh9UOw.png" /><figcaption>This was Flexibility’s infrastructure at the start of the project.</figcaption></figure><h4>Standing on the Shoulders of Giants</h4><p>The company’s infrastructure was a patchwork of static systems designed for a simpler time. Fixed capacity meant that during peak demand, the system struggled, leading to service interruptions. Conversely, during quieter periods, resources sat idle, wasting money. The lack of flexibility not only hindered performance but also left the team constantly firefighting</p><h4>A New Hope</h4><p><strong>binbash</strong> entered the scene with a clear plan: transform <strong>flexibility</strong>’s infrastructure into a dynamic, cloud-native environment. The strategy focused on leveraging AWS tools to address the core issues at hand.</p><p><strong>Environment Consolidation &amp; Scaling</strong></p><p>The first step was implementing <strong>AWS Auto Scaling w/ K8s Cluster Autoscaler </strong>for<strong> AWS EKS</strong>, which enabled the infrastructure and containers to automatically adjust capacity based on <strong>real-time demand</strong>. This ensured optimal resource use, eliminating overprovisioning and costly downtime during peak periods. Complementing this, Amazon EC2 <strong>Spot Instances</strong> were introduced to further optimize costs by utilizing unused EC2 capacity.</p><p>Subsequently, we <strong>consolidated multiple lower-tier environment accounts</strong>, including Dev, QA, and Stg, into a single multi-tenant (multi-environment) Kubernetes EKS cluster. This approach significantly reduced resource duplication and operational costs while streamlining management and improving efficiency.</p><blockquote>Dev/Stg &amp; QA Consolidation: Streamlining development, staging, and quality assurance environments improved efficiency and resource utilization. Less clusters to administrate</blockquote><p><strong>Visibility</strong></p><p>Flexibility’s previous lack of system visibility was another critical issue. binbash deployed <strong>Amazon CloudWatch + Prometheus and Grafana</strong> to provide real-time monitoring and alerting. This tool gave the operations team comprehensive insights into system health, allowing them to <strong>proactively address potential problems before they affected users</strong>.</p><p><strong>Automation &amp; EKS Upgrades</strong></p><p>To reduce manual intervention, <strong>binbash</strong> introduced <a href="https://www.binbash.co/leverage"><strong>binbash Leverage™</strong></a> from the very beginning of the project . Tasks such as <strong>EKS infra deployment and upgrades</strong>, which once consumed valuable time, were now handled autonomously. Additionally, <strong>Infrastructure as Code (IaC)</strong> using Terraform through our <a href="https://github.com/binbashar/le-tf-infra-aws">Leverage Ref Architecture for AWS</a> was adopted, streamlining the deployment and management of AWS resources while ensuring consistency across environments.</p><blockquote>Kubernetes Clusters Upgrade: Completing upgrades for all clusters to version &gt;1.26 ensured the latest security patches and functionalities were in place.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*exE34pYfTllyWdmtmCgX7Q.png" /><figcaption>Optimization 1 | Architecture w/ Spot EKS Nodes for Dev &amp; QA</figcaption></figure><p><strong>Cost optimization</strong></p><p>Cost control was a central focus. By analyzing usage data through AWS Cost Explorer and implementing <strong>AWS Reserved Instances</strong>, Flexibility achieved significant <strong>savings</strong>. Also implemented AWS Budgets and Billing Alerts for cost monitoring. These tools provided detailed insights into spending patterns, allowing for smarter financial planning and resource allocation.</p><blockquote>Cost Optimization: Implementing Reserved Instances resulted in a significant reduction of 30% in overall cloud expenditure.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/744/1*bxT8Aov14NN8xbNwNwIhUw.png" /><figcaption>Optimization 2 | This is Flexibility’s Architecture w/ DevStg &amp; QA consolidated in a single account VPC + EKS + RDS engine</figcaption></figure><p><strong>Security &amp; Compliance</strong></p><p>Security, an essential aspect of any fintech and digital banking platform, was strengthened with AWS Identity Center (formerly SSO) and Access Management (IAM). <strong>binbash</strong> implemented <strong>granular access</strong> controls and <strong>multi-factor authentication</strong> to safeguard sensitive data, aligning with industry regulations and boosting customer trust.</p><h4>To the infinite and beyond</h4><p>The transformation didn’t stop at technology. <strong>binbash</strong> worked closely with <strong>Flexibility’s</strong> teams to ensure a smooth transition, providing training and support to embed new processes. This partnership approach fostered a culture of continuous improvement and innovation.</p><p>The results were transformative. <strong>Flexibility</strong> not only <strong>reduced operational costs by 30%</strong> but also enhanced service reliability and speed.</p><p>Customers noticed the difference, and the company solidified its market position.</p><p>Internally, the shift from reactive to proactive operations empowered teams to focus on strategic growth initiatives.</p><blockquote>Crucially, the project included a robust knowledge transfer component, empowering Flexibility’s team to maintain and operate the upgraded infrastructure autonomously.</blockquote><h4>A Walk in the Cloud</h4><p><em>Flexibility’s</em> journey is a testament to how embracing cloud technology and strategic partnerships can drive meaningful change. This transformation not only optimized costs and performance but also redefined the company’s trajectory toward sustainable growth.</p><p>For organizations navigating similar challenges, this case serves as a beacon: innovation and adaptability are not just options — they are necessities in today’s fast-paced digital landscape. With the right tools and a clear strategy, the future is not just scalable; it’s limitless.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=87394e3ca870" width="1" height="1" alt=""><hr><p><a href="https://medium.com/binbash-inc/how-a-fintechs-30-cost-optimization-redefined-its-future-87394e3ca870">How a Fintech’s 30% Cost Optimization Redefined Its Future</a> was originally published in <a href="https://medium.com/binbash-inc">binbash</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to update EKS node types?]]></title>
            <link>https://medium.com/binbash-inc/how-to-update-eks-node-types-a7f64e386d48?source=rss-29d82e4f478a------2</link>
            <guid isPermaLink="false">https://medium.com/p/a7f64e386d48</guid>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[node]]></category>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[ek]]></category>
            <dc:creator><![CDATA[Juan Matías de la Cámara Beovide]]></dc:creator>
            <pubDate>Mon, 11 Dec 2023 14:26:07 GMT</pubDate>
            <atom:updated>2023-12-11T14:26:07.603Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*B5JPjRX6iX3zGQgpjt9YMA.png" /></figure><p>While using <a href="https://leverage.binbash.co">Leverage</a>, creating an <strong>EKS cluster</strong> becomes a straightforward process. To guide you through this, please refer to <a href="https://leverage.binbash.co/user-guide/ref-architecture-eks/overview/">this link</a>. This scenario involves upgrading the node instance types.</p><h3>Workloads considerations</h3><h4>Ideal scenario</h4><p>In an optimal situation, all workloads should be scalable. This implies that all workloads managed through <strong>ArgoCD</strong> Application’s Rollouts, the default in <a href="https://leverage.binbash.co/">binbash Leverage</a>, should be capable of upscaling. This means creating multiple pods for each ArgoCD Application to handle increased demand or load.</p><h4>Non-ideal solution</h4><p>However, in instances where certain applications can only accommodate a single instance (i.e., one pod), scaling becomes challenging. In such cases, there may be downtime as the existing pod needs to be terminated, and a new one must be created on the new nodes. This limitation poses challenges in maintaining continuous availability during scaling activities for these specific applications.</p><h3>Steps</h3><h4>Create a new node group</h4><p>Go to the `cluster` sublayer under the EKS layer at `&lt;leverage-project-name&gt;/&lt;account-name&gt;/&lt;region&gt;/k8s-eks/cluster` . (e.g. <a href="https://github.com/binbashar/le-tf-infra-aws/tree/master/apps-devstg/us-east-1/k8s-eks">here</a>)</p><p>Edit the file `eks-managed-nodes.tf`. (e.g. <a href="https://github.com/binbashar/le-tf-infra-aws/blob/master/apps-devstg/us-east-1/k8s-eks/cluster/eks-managed-nodes.tf">here</a>)</p><p>Under the EKS module:</p><pre>module &quot;cluster&quot; {<br> source = &quot;github.com/binbashar/terraform-aws-eks.git?ref=v18.24.1&quot;</pre><p>there is a node group definition, e.g.</p><pre>eks_managed_node_groups = {<br> on-demand-t3 = {<br> min_size = 2<br> max_size = 10<br> desired_size = 6<br> capacity_type = &quot;ON_DEMAND&quot;<br> instance_types = [&quot;t3.large&quot;]<br> }<br> }</pre><p>(note this is an ON_DEMAND type, it also can be SPOT)<br> <br> Add a new node group, e.g.:</p><pre>eks_managed_node_groups = {<br> on-demand-t3 = {<br> min_size = 2<br> max_size = 10<br> desired_size = 6<br> capacity_type = &quot;ON_DEMAND&quot;<br> instance_types = [&quot;t3.large&quot;]<br> }<br> on-demand-t3xlarge = {<br> min_size = 1<br> max_size = 6<br> desired_size = 3<br> capacity_type = &quot;ON_DEMAND&quot;<br> instance_types = [&quot;t3.xlarge&quot;]<br> }<br> }</pre><p>(adjust the values as per your needs, here I’m considering the xlarge instance has the double of RAM and CPU than large)<br> <br> Apply the layer and wait for the group to be created.</p><h4>Cordon the old group</h4><p>Once the new group is created and the new nodes are in place, the old group has to be cordoned to avoid scheduling in those nodes.<br> <br> First, under the `cluster` layer, log into the EKS cluster:</p><pre>❯ leverage kubectl configure</pre><p>Get the node groups:</p><pre>❯ leverage aws - profile &lt;project-short-name&gt;-&lt;account-name&gt;-devops - region &lt;region&gt; eks list-nodegroups - cluster-name &lt;cluster-name&gt;<br>{<br> &quot;nodegroups&quot;: [<br> &quot;on-demand-t3–20220803130748876100000008&quot;,<br> &quot;on-demand-t3xlarge-20231130160430016700000001&quot;,<br> ]<br>}</pre><p>Note here there are two groups, the old one and the new one.</p><p>Now cordon the nodes in the old node group:</p><pre>❯ for n in $(leverage kubectl get nodes - selector eks.amazonaws.com/nodegroup=on-demand-t3–20220803130748876100000008 | awk &#39;FNR&gt;5 {print $1}&#39;); do leverage kubectl cordon $n; done</pre><p>It can be checked the old nodes are cordoned with this command:</p><pre>❯ leverage kubectl get nodes - selector eks.amazonaws.com/nodegroup=on-demand-t3–20220803130748876100000008<br>[16:58:55] INFO Attempting to get temporary credentials for apps-dev account.<br>[16:58:56] INFO Using already configured temporary credentials.<br>[16:58:56] INFO Attempting to get temporary credentials for shared account.<br>[16:58:57] INFO Using already configured temporary credentials.<br>NAME STATUS ROLES AGE VERSION<br>ip-10–0–13–118.ec2.internal Ready,SchedulingDisabled &lt;none&gt; 13d v1.24.17-eks-43840fb<br>ip-10–0–40–140.ec2.internal Ready,SchedulingDisabled &lt;none&gt; 20d v1.24.17-eks-43840fb<br>ip-10–0–52–96.ec2.internal Ready,SchedulingDisabled &lt;none&gt; 20d v1.24.17-eks-43840fb<br>ip-10–0–6–43.ec2.internal Ready,SchedulingDisabled &lt;none&gt; 13d v1.24.17-eks-43840fb</pre><p>Names can vary, but note the SchedulingDisable status, this means nodes are cordoned, i.e. no pod will be scheduled in these nodes.</p><h4>Avoid old group to scale up</h4><p>To prevent the old group from scaling-up, do the following.</p><p>Check the amount of old group nodes. It can be seen in the previous step (checking cordoned nodes) there are 4 nodes.</p><p>So, edit the file again and set the max and desired size to 4.</p><pre>eks_managed_node_groups = {<br> on-demand-t3 = {<br> min_size = 2<br> max_size = 4<br> desired_size = 4<br> capacity_type = &quot;ON_DEMAND&quot;<br> instance_types = [&quot;t3.large&quot;]<br> }<br> on-demand-t3xlarge = {<br> min_size = 1<br> max_size = 6<br> desired_size = 3<br> capacity_type = &quot;ON_DEMAND&quot;<br> instance_types = [&quot;t3.xlarge&quot;]<br> }<br> }</pre><p>Apply the layer.</p><h4>Migrate Applications</h4><p><strong>Escalable Apps</strong><br>If Applications can scale up (i.e. managing more than one pod), do the following for each app.</p><p>- Go to the ArgoCD web console<br>- Pick the Application<br>- Turn AutoSync off<br>- Scale up (set the double amount of pods, i.e. if there are 2 pods, set the new value to 4)<br> — if no HPA<br> — in the Rollout definition change the Replicas value<br> — if HPA<br> — in HPA set the min amount of replicas<br>- Wait until new pods are created</p><p>Pods being created in the new nodes can be checked with the following command:</p><pre>for n in $(leverage kubectl get nodes - selector &quot;eks.amazonaws.com/nodegroup!=on-demand-t3–20220803130748876100000008&quot; | awk &#39;FNR&gt;5 {print $1}&#39;); do leverage kubectl get pods - all-namespaces -o wide - field-selector spec.nodeName=$n; done</pre><p>- Once the new pods are created, old pods can be killed.<br>- Once all the pods for an Application are scheduled in the new nodes the Replicas values can be set back to the original value<br>- Turn on auto sync</p><p><strong>No escalable Apps</strong><br>If app can not be escalated:</p><p>- Set a Maintenance Window for the process<br>- During the MW do the following:<br> — Go to ArgoCD Web Console<br> — Pick the Application<br> — Kill the existing pod<br> — Wait until the new pod is created</p><p>Once all the non-escalabe-apps are done you can continue with the next step.</p><h4>Drain nodes</h4><p>It is recommended to do this node by node manually to keep control over the process.</p><p>For each node in the old node group run:</p><pre>❯ leverage kubectl drain node-name --ignore-daemonsets</pre><p>During this process, if this mesage is shown “cannot delete Pods with local storage”…. <br>This probably is due to “argocd/argocd-image-updater” or “kube-system/coredns” in the node using local (emptyDir) storage.<br>In this case it is safe to add the flag:</p><pre>--delete-emptydir-data</pre><h4>Delete the old node group</h4><p>Edit the file one more time, delete the old node group so it looks like this:</p><pre>on-demand-t3xlarge = {<br> min_size = 1<br> max_size = 6<br> desired_size = 3<br> capacity_type = &quot;ON_DEMAND&quot;<br> instance_types = [&quot;t3.xlarge&quot;]<br> }<br> }</pre><p>Apply the layer.</p><h3>Conclusion</h3><p>This process is aimed to update the EKS nodes type with no downtime (or minimal and controlled downtime).<br> <br>Note it is recommended to have a node group per AZ so in a given moment there is at least one node per AZ, this is to enforce HA.<br>So this can be set in the file:</p><pre>on-demand-t3xlarge-a = {<br> min_size = 2<br> max_size = 10<br> desired_size = 2<br> capacity_type = &quot;ON_DEMAND&quot;<br> instance_types = [&quot;t3.xlarge&quot;]<br> subnet_ids = [data.terraform_remote_state.eks-vpc.outputs.private_subnets[0]]<br> placement = {<br> availability_zone = data.terraform_remote_state.eks-vpc.outputs.availability_zones[0]<br> }<br> }<br> on-demand-t3xlarge-b = {<br> min_size = 2<br> max_size = 10<br> desired_size = 2<br> capacity_type = &quot;ON_DEMAND&quot;<br> instance_types = [&quot;t3.xlarge&quot;]<br> subnet_ids = [data.terraform_remote_state.eks-vpc.outputs.private_subnets[1]]<br> placement = {<br> availability_zone = data.terraform_remote_state.eks-vpc.outputs.availability_zones[1]<br> }<br> }</pre><p>Note here we are using Terraform remote states from the EKS `network` sublayer (e.g. <a href="https://github.com/binbashar/le-tf-infra-aws/tree/master/apps-devstg/us-east-1/k8s-eks/network">here</a>), so something like this is needed in the `config.tf` file:</p><pre>data &quot;terraform_remote_state&quot; &quot;eks-vpc&quot; {<br> backend = &quot;s3&quot;<br> config = {<br> region = var.region<br> profile = var.profile<br> bucket = var.bucket<br> key = &quot;&lt;account-name&gt;/k8s-eks/network/terraform.tfstate&quot;<br> }<br>}</pre><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a7f64e386d48" width="1" height="1" alt=""><hr><p><a href="https://medium.com/binbash-inc/how-to-update-eks-node-types-a7f64e386d48">How to update EKS node types?</a> was originally published in <a href="https://medium.com/binbash-inc">binbash</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AWS Lambda: the “two updating-points” problem]]></title>
            <link>https://medium.com/binbash-inc/aws-lambda-the-two-updating-points-problem-1556711fa20?source=rss-29d82e4f478a------2</link>
            <guid isPermaLink="false">https://medium.com/p/1556711fa20</guid>
            <category><![CDATA[leverage]]></category>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[well-architected]]></category>
            <category><![CDATA[lambda]]></category>
            <dc:creator><![CDATA[Juan Matías de la Cámara Beovide]]></dc:creator>
            <pubDate>Thu, 06 Jul 2023 14:36:18 GMT</pubDate>
            <atom:updated>2023-07-06T15:06:24.367Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a4NzWjP6UdbhWD68TLHzyQ.png" /></figure><h3>Overview</h3><p>In this article, we’ll discuss a solution for managing Lambda functions effectively using <strong>Terraform</strong> within the <strong>AWS Well-Architected Framework</strong>. It addresses the challenge of handling multiple sources for <strong>Lambda</strong> functions and ensures that updating the infrastructure doesn’t overwrite changes made by developer repositories. By leveraging lifecycle management and appropriate configuration, developers can update Lambda code independently while maintaining the integrity of the infrastructure.</p><p>In our architecture, we utilize an infrastructure repository powered by <a href="https://leverage.binbash.co/"><strong>binbash Leverage</strong></a>, which operates <strong>Terraform</strong> in the background. The objective is to create a Lambda function and grant it access to specific resources such as SQS, SNS, and buckets, all provisioned through the Leverage Infrastructure repository. Additionally, developers should have the capability to update the Lambda code from their own repositories.</p><h3>The problem</h3><p>The challenge arises from having two different sources for the Lambda function. One source is the <em>Leverage Infrastructure repository</em>, responsible for creating the Lambda function and applying policies. The other source is <em>the developers’ repository</em>, where code updates are made. To prevent overwriting the Lambda function during subsequent application of the Leverage Infrastructure repository, a solution is needed.</p><h3>Facts</h3><p>So, summing up, these are the facts:</p><ul><li>There is an Infrastructure repository (<a href="https://leverage.binbash.co/"><strong>binbash Leverage</strong></a>)</li><li>There is a Lambda code repository</li><li>The Lambda should be created during the infrastructure creation so the permissions can be easily applied</li><li>The Lambda code should be updated when new code is pushed into the Lamba code repository</li><li>The Lambda code should not be updated if the Leverage Infrastructure repository is applied again</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*JzuUYte9bPo30syk" /></figure><h3>The solution</h3><p>Here, <a href="https://developer.hashicorp.com/terraform/language/meta-arguments/lifecycle">life cycle management </a>for Terraform becomes handy.</p><p>The approach involves creating the Lambda function in a way that fetches the code from an S3 bucket. Additionally, we instruct Terraform to ignore certain values that can be modified by developers, such as environment variables, memory size, and timeout. By omitting these values during evaluation, Terraform can determine whether an update is necessary.</p><p>Here’s an example of the lifecycle block in Terraform:</p><pre>  lifecycle {<br>    ignore_changes = [<br>      environment,<br>      memory_size,<br>      timeout<br>    ]<br>  }</pre><p>Since we pull the code from a ZIP file, there is no need to instruct Terraform to omit any code, since it won’t be taken into account when evaluating the update. (Note for forcing Terraform to update the Lambda when ZIPped code changes, we should use source_code_hash , which we&#39;ll use later)</p><ul><li>update the lambda function from the dev repository</li><li>try to update from infra, it should show no changes to apply</li></ul><h3>Applying the solution</h3><p>The complete solution is shown in this <a href="https://github.com/binbashar/le-tf-infra-aws/tree/BASH-266-DR-update-lambda-at-two-dif-times"><strong>binbash Leverage library</strong> experimental branch</a>.</p><p>Here there are just the needed parts for the demo.</p><p>Under the layer apps-devstg/us-east-1/aws-lambda-poc (inside the <strong>binbash Leverage</strong> context, we call the leafs of this directory tree layers) and apps-devstg/us-east-1/aws-lambda-poc-lambda-update are all the files.</p><h4>Creating the Lambda</h4><p>For this, an S3 object is created, then the lambda should pull code from there.</p><p>Note the lambda has the lifecycle directive:</p><pre>resource &quot;aws_s3_object&quot; &quot;initial-lambda&quot; {<br><br>    bucket = aws_s3_bucket.lambda.bucket<br>    key    = &quot;bb-lambda-test-test&quot;<br>    source = &quot;initial-lambda.zip&quot;<br><br>}<br><br>resource &quot;aws_lambda_function&quot; &quot;func&quot; {<br><br>    depends_on = [<br><br>        aws_s3_object.initial-lambda,<br><br>    ]<br><br>    function_name = &quot;bb-lambda-test-test&quot;<br>    role          = aws_iam_role.lambda.arn<br>    handler       = &quot;lambda_function.lambda_handler&quot;<br>    runtime       = &quot;python3.10&quot;<br>    memory_size   = 256<br>    timeout       = 600<br><br>    s3_bucket = aws_s3_bucket.lambda.bucket<br>    s3_key    = &quot;bb-lambda-test-test&quot;<br><br><br>    environment {<br><br>      variables = local.lamba_environment_variables<br>    }<br><br>  lifecycle {<br>    ignore_changes = [<br>      environment,<br>      memory_size,<br>      timeout<br>    ]<br>  }<br><br>}</pre><p>initial-lambda.zip contains dummy code.</p><p>Apply this layer, Lambda with dummy code is created.</p><h4>Updating the lambda</h4><p>This update can be done by a few means, in this case Terraform is being used (AWS CLI and manual changes can be used as well). Note that by using Terraform for doing this, first the lambda function has to be imported into the current state. It is as easy as:</p><pre>leverage tf import aws_lambda_function.func &quot;bb-lambda-test-test&quot;</pre><p>And this is the actual Terraform code, file updated-lambda.zip contains the code updated by the developer:</p><pre>resource &quot;aws_s3_object&quot; &quot;initial-lambda&quot; {<br><br>    bucket = &quot;bb-lambda-test&quot;<br>    key    = &quot;bb-lambda-test-test-update/updated-lambda.zip&quot;<br>    source = &quot;updated-lambda.zip&quot;<br>    etag   = filebase64sha256(&quot;updated-lambda.zip&quot;)<br><br>}<br><br>resource &quot;aws_lambda_function&quot; &quot;func&quot; {<br><br>    depends_on = [ aws_s3_object.initial-lambda ]<br><br>    function_name = &quot;bb-lambda-test-test&quot;<br>    handler       = &quot;lambda_function.lambda_handler&quot;<br>    runtime       = &quot;python3.10&quot;<br><br>    role             = &quot;arn:aws:iam::523857393444:role/bb-lambda-test-sts&quot;<br>    source_code_hash = filebase64sha256(&quot;updated-lambda.zip&quot;)<br>    publish          = true<br>    timeout          = 60<br>    memory_size      = 128<br><br>    s3_bucket = &quot;bb-lambda-test&quot;<br>    s3_key    = &quot;bb-lambda-test-test-update/updated-lambda.zip&quot;<br><br><br>    environment {<br><br>      variables = local.lamba_environment_variables<br><br>    }<br><br>}</pre><p>Note in these Terraform resources the following elements are being used:</p><ul><li>etag for the S3 object</li><li>source_code_hash for the lambda function</li></ul><p>In this code, the etag and source_code_hash attributes ensure that the resources will be updated when the code changes. After applying this update, the Lambda code will be successfully updated.</p><blockquote>Note this step can be easily run in a pipeline in the Lambda code repository.</blockquote><h4>What can be changed?</h4><p>As per this directive:</p><pre>lifecycle {<br>    ignore_changes = [<br>      environment,<br>      memory_size,<br>      timeout<br>    ]<br>  }</pre><p>…the elements that can be changed safely (i.e. preventing the Leverage Infrastructure repository from updating the object) are:</p><ul><li>the lambda code itself (using the ZIP file method)</li><li>the environment variables</li><li>the memory size</li><li>the timeout</li></ul><p>By incorporating the lifecycle block mentioned earlier, these elements remain unchanged during the application of the Leverage Infrastructure repository. Therefore, subsequent re-application of the infrastructure layer will not impact the Lambda function.</p><p>Now you can re-apply the <strong>Leverage</strong> Infrastructure layer without panicking about the code!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/474/0*eirm9r7VLjJ5Y1FV" /></figure><h4>Conclusion</h4><p>By leveraging Terraform’s lifecycle management and appropriately configuring Lambda functions, developers can update Lambda code independently while ensuring the integrity of the infrastructure. This solution allows for efficient management of Lambda functions within the AWS Well-Architected Framework.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=1556711fa20" width="1" height="1" alt=""><hr><p><a href="https://medium.com/binbash-inc/aws-lambda-the-two-updating-points-problem-1556711fa20">AWS Lambda: the “two updating-points” problem</a> was originally published in <a href="https://medium.com/binbash-inc">binbash</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Someone changed your terraform!]]></title>
            <link>https://resources.tarmac.io/someone-changed-your-terraform-4a59b59281e0?source=rss-29d82e4f478a------2</link>
            <guid isPermaLink="false">https://medium.com/p/4a59b59281e0</guid>
            <category><![CDATA[devops]]></category>
            <category><![CDATA[terraform]]></category>
            <dc:creator><![CDATA[Juan Matías de la Cámara Beovide]]></dc:creator>
            <pubDate>Tue, 10 Nov 2020 19:17:58 GMT</pubDate>
            <atom:updated>2020-11-16T13:51:52.552Z</atom:updated>
            <content:encoded><![CDATA[<h3>What?</h3><p>So, someone deployed to production using a terraform file set. Then someone else modified something there and after a looooooong time, it’s your turn to fix some stuff.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-We9yJftx_tsHctMFgaZcA.jpeg" /></figure><h3>Specifically what?</h3><p>Ok, for this example, at first moment you had a Google Service (here we are working with Cloud Functions), activated in the main file of this terraform structure:</p><pre>. <br>├── env <br>│ └── main.tf<br>  └── function <br>      ├── http_trigger.js <br>      └── http_trigger.zip</pre><p>This means, the service address was: <strong>google_project_service.cloud-functions</strong></p><p>Then someone had the great idea: <strong><em>using modules! :)</em></strong></p><p>So the Google Service activation moved to the main.tf under modules:</p><pre>├── env <br>│ └── main.tf <br>├── function <br>│   ├── http_trigger.js <br>│   └── http_trigger.zip <br>└── modules <br>    └── main <br>    └── main.tf</pre><p>Here the service address is:<strong> module.main.google_project_service.cloud-functions</strong></p><p>And for a while (while you were in development) was ok. But then, one day, you went to production… where the tfstate still had the service under the old address… so terraform said: “<em>hey, dude, I will destroy your service resource (disable) and then I will create it again (enable)</em>”. To do this all resources dependent on this one needs to be destroyed as well.</p><p>So, what to do?</p><h3>The solution</h3><p>You have a real activated service. And in the tfstate you have a resource (<strong><em>google_project_service.cloud-functions</em></strong>) that is not in your tf files (so it will be destroyed) and in your tf files a new resource (<strong><em>module.main.google_project_service.cloud-functions</em></strong>) that needs to be created… but wait, that you already have in the Google Cloud infrastructure!</p><p>So, delete the old resource from the tfstate, import it again under the new address… and voilà, you can have a beer and a success!</p><p>First delete the old resource from the tfstate:</p><pre>terraform state rm google_project_service.cloud-functions</pre><p>Then import the actual service as resource into your tfstate:</p><pre>terraform import google_project_service.cloud-functions your-proyect-id/cloudfunctions.googleapis.com</pre><p>(change the project ID)</p><p>Ok, now you can run your terraform again a enjoy watching it not trying to delete your service!</p><h3>Conclusion</h3><p>Don’t panic and carry a towel…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/353/0*4py2xxwHHuYjavU0" /></figure><p><em>Originally published at </em><a href="https://juanmatiasdelacamara.wordpress.com/2020/11/10/someone-changed-your-terraform/"><em>http://juanmatiasdelacamara.wordpress.com</em></a><em> on November 10, 2020.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4a59b59281e0" width="1" height="1" alt=""><hr><p><a href="https://resources.tarmac.io/someone-changed-your-terraform-4a59b59281e0">Someone changed your terraform!</a> was originally published in <a href="https://resources.tarmac.io">tarmac</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Gitflow with Github and Cloud Build]]></title>
            <link>https://resources.tarmac.io/gitflow-with-github-and-cloud-build-89b1d87c0628?source=rss-29d82e4f478a------2</link>
            <guid isPermaLink="false">https://medium.com/p/89b1d87c0628</guid>
            <category><![CDATA[git]]></category>
            <category><![CDATA[github]]></category>
            <category><![CDATA[sre]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[devops]]></category>
            <dc:creator><![CDATA[Juan Matías de la Cámara Beovide]]></dc:creator>
            <pubDate>Mon, 05 Oct 2020 11:18:00 GMT</pubDate>
            <atom:updated>2020-10-08T19:48:58.425Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/440/0*KPa93-xsD935Orab" /></figure><h3>What?</h3><p>I want to implement <a href="https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow">Gitflow</a> using <a href="https://github.com/">Github</a> and <a href="https://cloud.google.com/cloud-build/">Cloud Build</a>.</p><h3>Why?</h3><p>When developing software in a team, it’s a good idea to set some sort of standard process. This keeps things clear, ordered and helps the team to avoid procedural mistakes.</p><p>Also, if a new dev/devops/lead (or whatever) is added to the team, to have a well defined procedure improves the on-boarding process.</p><p>Gitflow is not the only flow out there, and your choice will depend on your project’s nature. But if you are building software that is explicitly versioned, or if you need to support multiple versions of your software in the wild, then git-flow may be a good choice. (more on GitFlow <a href="https://nvie.com/posts/a-successful-git-branching-model/">here</a>)</p><p>I made this research when a client using Github+GCP (specifically GCP’s CloudBuild) needed to organize its repositories and processes. So this is the <em>How to implement GitFlow using GitHub and GCP</em> post.</p><h3>How?</h3><p>I will create a template repo with several pipeline files (cloudbuild.yaml files), for each part of the workflow. Then I’ll use triggers from Github to Cloud Build.</p><h3>What is needed?</h3><ul><li>A Github account</li><li>A GCP account</li><li>The will to do this 😉</li></ul><h3>Note</h3><p><strong># </strong>0</p><p>The pipelines here have dummy steps… meaning that some of them just print a string saying “Deploy steps”… but they are just templates, so you can then fill with your own actual test, check and deploy steps.</p><p><strong># </strong>1</p><p>This is a WIP post, since I’m researching. I’ll improve this doc with new findings, so keep track of this and feel free to drop a message with recommendations or comments.</p><h3>Steps</h3><p>First we’ll set the repo. Then we’ll define a procedure to work with.</p><h3>Setup the repo</h3><p><strong>Summary</strong></p><p>These are the main steps:</p><ul><li>Start the git-flow</li><li>Set Github repository (Settings)</li><li>Use as base the repo template or add files to the current repo</li><li>Create the triggers</li><li>Grant IAM permissions to CloudBuild SA</li><li>Take note on how to name your branches</li><li>Enforce branch naming with git hooks</li></ul><p><strong>Start the Gitflow</strong></p><p>Ensure you have downloaded (and added to you master branch) from <a href="https://gitlab.com/templates14/app-templates/-/tree/master/github-gitflow-cloudbuild">here</a> the following files:</p><ul><li>cloudbuild*yaml</li><li>.githooks/</li></ul><p>We’re starting with repos that have only a master branch. So we can start with the action stated in Extra Actions below to create the new develop branch:</p><pre>git checkout master &amp;&amp; git pull --rebase &amp;&amp; git checkout -b develop &amp;&amp; git push -u origin develop</pre><p><strong>Settings</strong></p><p>Things to do in your repo before start working.</p><ul><li>Set develop as the default branch.</li><li>Create an SSH key so pipelines can push, and add it to your secret manager. (as per <a href="https://cloud.google.com/cloud-build/docs/access-private-github-repos">this</a> doc)</li><li>Protect develop and master branch so nobody except the pipeline can push there.</li></ul><p><strong>Repo template</strong></p><p>We need to add the basic files to the current repo (done previously). Files can be found <a href="https://gitlab.com/templates14/app-templates/-/tree/master/github-gitflow-cloudbuild">here</a>.</p><p>In the template repo there are these Cloud Build basic pipelines:</p><ul><li>cloudbuild-feature.yaml</li><li>cloudbuild-pr.yaml</li><li>cloudbuild-develop.yaml</li><li>cloudbuild-master.yaml</li><li>cloudbuild-master-deploy.yaml</li><li>cloudbuild-release.yaml</li></ul><p>Each one performs a part of the whole Gitflow process.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/23f9500617a3d010eb35b00d413ab06c/href">https://medium.com/media/23f9500617a3d010eb35b00d413ab06c/href</a></iframe><p><strong>Triggers</strong></p><p>Also, in the repo, is a triggers.yaml. With it triggers can be created like this:</p><pre>gcloud beta builds triggers import --source=./triggers.yaml --project &lt;project-name&gt;</pre><p>Specs about CloudBuild triggers.</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/08ea41be874d1a7a267142e83a4b780b/href">https://medium.com/media/08ea41be874d1a7a267142e83a4b780b/href</a></iframe><p>* master tag must be defined, the proposed one fits <a href="https://semver.org/spec/v2.0.0.html">this</a> definition. Tagging must be a manual process since it triggers the deploy to prod. This kind of tagging allows us to more complex scenarios (e.g. v0.0.1 for prod, release/v0.0.1 for staging, etc)</p><p><strong>IAM Permissions</strong></p><p>Google Cloud Buid runs with a ServiceAccount named as: &lt;project-number&gt;@cloudbuild.gserviceaccount.com</p><p>This SA must have the following Roles:</p><p><strong><em>Base</em>: </strong>Cloud Build Service Account</p><p><strong><em>If you needto deploy Cloud Functions in the project</em>: </strong>Cloud Functions AdminService Account User</p><p><strong><em>Access Secret Manager</em>: </strong>Secret Manager Secret Accessor</p><p><strong>How to name your branches</strong></p><p>Prefix it with type, then a slash, ticket id and a brief description,(it’s important to follow these conventions since triggers rely on them) e.g.:</p><pre>feature/TICKET-212-Add_new_provider <br>fix/TICKET-312-Handle_None_case_in_var <br>hotfix/TICKET-444-Fix_broken_endpoint <br>release/v0.1</pre><p><strong>Enforce branch naming with git hooks</strong></p><p><strong><em>Option 1 — pre-commit</em></strong></p><p>If the project uses pre-commit.</p><p>From <a href="https://gitlab.com/templates14/app-templates/-/tree/master/github-gitflow-cloudbuild">repo</a> get file .pre-commit-config.yaml, if you already have one append these lines at the end:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/aa86e2c2c48baa2bcc79419355340bbb/href">https://medium.com/media/aa86e2c2c48baa2bcc79419355340bbb/href</a></iframe><p>This hook will prevent commits to branches that do not apply to the regex.</p><p>To activate pre-commit hooks:</p><p>pre-commit install</p><p><strong><em>Option 2 — plain git hooks</em></strong></p><p>We will use git hooks to enforce branch naming.</p><p>The problem is… we can’t set local git hooks in an automated way. So, this will be a manual step that each dev must perform when cloning the repo.</p><p>In the same repo from which we got the pipeline there is a directory called .githooks/, there we stored the branch-naming-enforcement-hook... so each dev must run this in the local repo after cloning it:</p><pre>git config core.hooksPath .githooks</pre><p>The hooks has this code of pre-commit and pre-push files:</p><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/64acd3849d07b3beac596fb7fe9cd18c/href">https://medium.com/media/64acd3849d07b3beac596fb7fe9cd18c/href</a></iframe><h3>The procedure</h3><p>Here are descriptions of the most common use cases:</p><ul><li>Clone a repo</li><li>Work in a new feature or fix</li><li>Release code to master</li><li>Work in a hotfix</li></ul><p><strong>Clone a repo</strong></p><p>After cloning a repo, un this command on the repo’s root dir:</p><pre>pre-commit install</pre><pre># If repo has no .pre-commit-config.yaml file, use plain hooks</pre><pre># git config core.hooksPath .githooks</pre><p>If you still do not have pre-commit installed read <a href="https://pre-commit.com/#installation">this</a>.</p><p><strong>Work in a new feature or fix</strong></p><p>Checkout latest develop version:</p><p>git checkout develop &amp;&amp; git pull –rebase</p><p>Create the feature/fix branch:</p><p>git checkout -b feature_branch_name<br>git push -u origin feature_branch_name</p><p>Create a WIP PR into develop branch to work on (maybe you won’t be able to create a PR until a change is submitted)</p><p>Work as usual (modify/add/commit/push) (on every push feature pipeline must succeed)</p><p>When done ask for approval and review (<strong>DO NOT MERGE</strong>)</p><p>When ready to merge add the following comment to the PR</p><p>/gcbrun</p><p>The develop-pr pipeline must succeed (it merges and deletes the feature branch)</p><p><strong>Release code to master</strong></p><p>Checkout latest develop version:<br> git checkout develop &amp;&amp; git pull –rebase</p><p>Create the release:</p><p>git checkout -b release/v0.1.0<br>git push -u origin release/v0.1.0</p><p>Create a WIP PR into master branch to work on</p><p>Test it, if needed work in a fix (modify/add/commit/push)</p><p>When done ask for approval and review (<strong>DO NOT MERGE</strong>)</p><p>When ready to merge add the following comment to the PR</p><p>/gcbrun</p><p>The master-pr pipeline must succeed (it merges and deletes the feature branch into master and develop)</p><p><strong>MANUAL STEP</strong>: Go to master and create a tag, it can be done in Github website or in the command line as follow:</p><p>git checkout master &amp;&amp; git pull –rebase &amp;&amp; git tag v0.1.0 &amp;&amp; git push origin v0.1.0</p><p>The master-deploy pipeline must succeed (it deploys to prod)</p><p><strong>Work in a hotfix</strong></p><p>Checkout latest master version:</p><p>git checkout master &amp;&amp; git pull –rebase</p><p>Create the hotfix branch:</p><p>git checkout -b hotfix_branch_name<br>git push -u origin hotfix_branch_name</p><p>Create a WIP PR into master branch to work on (maybe you won’t be able to create a PR until a change is submitted)</p><p>Work as usual (modify/add/commit/push) (on every push release-hotfix pipeline must succeed)</p><p>When done ask for approval and review (<strong>DO NOT MERGE</strong>)</p><p>When ready to merge add the following comment to the PR</p><p>/gcbrun</p><p>The master-pr pipeline must succeed (it merges and deletes the feature branch into master and develop)</p><p><strong>MANUAL STEP</strong>: Go to master and create a tag, it can be done in Github website or in the command line as follow:</p><p>git checkout master &amp;&amp; git pull –rebase &amp;&amp; git tag v0.1.1 &amp;&amp; git push origin v0.1.1</p><p>The master-deploy pipeline must succeed (it deploys to prod)</p><p><strong>Extra actions</strong></p><p><strong><em>Add git-flow to existent repo</em></strong></p><pre>git checkout master &amp;&amp; git pull --rebase &amp;&amp; git checkout -b develop &amp;&amp; git push -u origin develop</pre><h3>To Do</h3><p>My to do list:</p><ul><li>hide “Merge” button on Github’s PRs</li><li>protect branches</li></ul><h3>References</h3><p>GitFlow</p><p><a href="https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow">https://www.atlassian.com/git/tutorials/comparing-workflows/gitflow-workflow</a></p><p>Git — git-flow mapping</p><p><a href="https://gist.github.com/JamesMGreene/cdd0ac49f90c987e45ac">https://gist.github.com/JamesMGreene/cdd0ac49f90c987e45ac</a></p><p>Cloud Build envvars</p><p><a href="https://cloud.google.com/cloud-build/docs/configuring-builds/substitute-variable-values">https://cloud.google.com/cloud-build/docs/configuring-builds/substitute-variable-values</a></p><p>Cloud Build -Github authentication</p><p><a href="https://cloud.google.com/cloud-build/docs/access-private-github-repos">https://cloud.google.com/cloud-build/docs/access-private-github-repos</a></p><p>Git Hooks</p><p><a href="https://itnext.io/using-git-hooks-to-enforce-branch-naming-policy-ffd81fa01e5e">https://itnext.io/using-git-hooks-to-enforce-branch-naming-policy-ffd81fa01e5e</a></p><p><em>Originally published at </em><a href="https://juanmatiasdelacamara.wordpress.com/2020/10/05/gitflow-with-github-and-cloud-build/"><em>http://juanmatiasdelacamara.wordpress.com</em></a><em> on October 5, 2020.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=89b1d87c0628" width="1" height="1" alt=""><hr><p><a href="https://resources.tarmac.io/gitflow-with-github-and-cloud-build-89b1d87c0628">Gitflow with Github and Cloud Build</a> was originally published in <a href="https://resources.tarmac.io">tarmac</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[To mesh or not to mesh]]></title>
            <link>https://resources.tarmac.io/to-mesh-or-not-to-mesh-dc969394baae?source=rss-29d82e4f478a------2</link>
            <guid isPermaLink="false">https://medium.com/p/dc969394baae</guid>
            <category><![CDATA[linkerd]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[k8s]]></category>
            <category><![CDATA[mesh]]></category>
            <category><![CDATA[service-mesh]]></category>
            <dc:creator><![CDATA[Juan Matías de la Cámara Beovide]]></dc:creator>
            <pubDate>Wed, 09 Sep 2020 15:44:06 GMT</pubDate>
            <atom:updated>2020-09-09T15:47:25.576Z</atom:updated>
            <cc:license>https://creativecommons.org/licenses/by-sa/4.0/</cc:license>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BuAkJsyC2R0VF5tqR-9r6Q.jpeg" /></figure><h3>Service Mesh</h3><p>I was told that a Service Mesh such as Linkerd, Consul or Istio, adds a lot of overload in my cluster. Keeping this in mind, a Service Mesh is not suitable to a small deployment. Instead, you should consider a Service Mesh when you client is big enough to deserve it.</p><p>But, how big a client must be to deserve a Service Mesh?</p><p>And more important, how much overload a Service Mesh adds to my cluster?</p><p>The answer is: I don’t know.</p><p>Because of this, I’m starting this POC, to answer this question.</p><h4>Resources</h4><p>Files here: <a href="https://gitlab.com/post-repos/to-mesh-or-not-to-mesh">https://gitlab.com/post-repos/to-mesh-or-not-to-mesh</a></p><h4>Requirements</h4><p>To run this test you will need:</p><ul><li>a k8s cluster (we will use GCP)</li><li>kubectl</li><li>locust</li><li>docker (or any container engine)</li><li>git</li></ul><p>We will use Linkerd, so you will need to download the CLI.</p><h4>BFF</h4><p>A simple Python APP that exposes a simple API and hits <em>BACKEND</em>. Once it get the <em>BACKEND</em>‘s response, it enrich this response and sends it to the client.</p><h4>BACKEND</h4><p>The BACKEND just answers the request with its version number.</p><h4>Service Mesh</h4><p>I will use <a href="https://linkerd.io/">linker</a> for this test.</p><h4>What we will measure?</h4><p>We will measure two items:</p><ul><li>WEB response times with <a href="https://locust.io/">Locust</a></li><li>K8s resources usage</li></ul><p>Then compare these metrics on two scenarios:</p><ul><li>using the Service Mesh</li><li>using the <em>raw</em> k8s cluster.</li></ul><h3>Set up the environment</h3><h4>Cluster</h4><p>This terraform template can be used: <a href="https://gitlab.com/templates14/terraform-templates/-/tree/master/gke">https://gitlab.com/templates14/terraform-templates/-/tree/master/gke</a></p><p>Then login into your cluster, e.g. for this case:</p><pre>gcloud container clusters get-credentials kungfoo-test --region us-central1 --project speedy-league-274700</pre><h3>The tests</h3><p>We’ll have two tests: one with and one without the service mesh.</p><h4>No Service Mesh</h4><p><strong>Set env</strong></p><p>Create the namespace to deploy the app into:</p><pre>kubectl create ns kungfootest</pre><p><strong>Set the app and run tests</strong></p><p>Go to <em>Set up the app</em> and the to <em>Run the tests</em>. After this come back here.</p><p><strong>Clean up</strong></p><p>Delete deployments:</p><pre>kubectl delete -n kungfootest -f deploy-backend.yaml -f deploy-bff.yaml -f ingress.yaml</pre><p>Delete the namespace so we’re clean:</p><pre>kubectl delete ns kungfootest</pre><h4>Service Mesh</h4><p><strong>Linkerd</strong></p><p>First, cli must be installed in your system. (more <a href="https://linkerd.io/2/getting-started/">here</a> )</p><p>Download binary from <a href="https://github.com/linkerd/linkerd2/releases/">here</a> and add it to your PATH.</p><p>Since we will be using GKE, we need to run these extra steps: <a href="https://linkerd.io/2/reference/cluster-configuration/#private-clusters">https://linkerd.io/2/reference/cluster-configuration/#private-clusters</a></p><p>Check cluster is ready for linkerd:</p><pre>linkerd check --pre</pre><p>I got:</p><pre>pre-kubernetes-capability</pre><pre>-------------------------</pre><pre>!! has NET_ADMIN capability</pre><pre>found 1 PodSecurityPolicies, but none provide NET_ADMIN, proxy injection will fail if the PSP admission controller is running</pre><pre>see <a href="https://linkerd.io/checks/#pre-k8s-cluster-net-admin">https://linkerd.io/checks/#pre-k8s-cluster-net-admin</a> for hints</pre><pre>!! has NET_RAW capability</pre><pre>found 1 PodSecurityPolicies, but none provide NET_RAW, proxy injection will fail if the PSP admission controller is running</pre><pre>see <a href="https://linkerd.io/checks/#pre-k8s-cluster-net-raw">https://linkerd.io/checks/#pre-k8s-cluster-net-raw</a> for hints</pre><p>The cluster lacks these capabilities. But probably when Linkerd is installed these will be installed as well. (<a href="https://github.com/linkerd/linkerd2/issues/3494">https://github.com/linkerd/linkerd2/issues/3494</a>)</p><p>Then install it:</p><pre>linkerd install | kubectl apply -f -</pre><p>…and wait until it’s installed:</p><pre>linkerd check</pre><p><strong>Set env</strong></p><p>Create the namespace to deploy the app into, this time we’ll need an annotation for linkerd:</p><pre>kubectl create ns kungfootest</pre><pre>kubectl edit ns kungfootest</pre><p>and then add the annotation:</p><pre>  annotations:</pre><pre>    linkerd.io/inject: enabled</pre><p>This will allow Linkerd to automagically inject the proxy in namespace’s pods.</p><p><strong>Set the app and run tests</strong></p><p>Now, go to <em>Set up the app</em> and the to <em>Run the tests</em>. After this come back here.</p><p>Note this time the pods will have two containers, since Linkerd is injecting the proxy.</p><h3>Compare the test resuts</h3><p>For my tests:</p><h4>No Mesh</h4><p>Total average requests: 33% CPU, 8% memory.</p><p>Total average usage: 12% CPU, 26% memory.</p><p>Avg response time: 204ms</p><h4>Mesh</h4><p>Total average requests: 35% CPU, 9% memory.</p><p>Total average usage: 25% CPU, 38% memory.</p><p>Avg response time: 206ms</p><h4>Conclusion</h4><p>The mesh configuration we used is very basic, but it adds interesting services to our deploy with no need to modify code. (e.g. secure internal connections, metrics…)</p><p>From the client’s point of view the time was only 1% more in the meshed version.</p><p>From the server side, we’re using 100% more of CPU and 46% of memory.</p><p>Does it worth?</p><p>As usual, it will depend. Can you afford the CPU and memory usage increase? Then you can have all the service mesh pros at almost no cost on the client side. Anyway, it deserves more tests if you are thinking on it.</p><p>But let me read your opinions on this, drop here a message.</p><h3>Set up the app</h3><p>Under source directory there are two subdirs. One for the <em>BFF</em> and one for the <em>BACKEND</em> (inside the later you will have two more dirs, versions 1 and 2… a.k.a. stable and canary, for now we will use just the stable version).</p><h4>Build the app</h4><p><strong>Backend</strong></p><p>On both cases you must proceed the same way, varying only the version number.</p><p>Into source/backend directory you will see the <em>Dockerfile</em> and the two version directories.</p><p>CD into your source/backend directory and run:</p><pre>cd source/backend/1.0 &amp;&amp; \</pre><pre>GOOS=linux GOARCH=amd64 go build -tags netgo -o app &amp;&amp; \</pre><pre>docker build -t backendapp:1.0 . &amp;&amp; \</pre><pre>cd ..</pre><p>…and:</p><pre>cd source/backend/2.0 &amp;&amp; \</pre><pre>GOOS=linux GOARCH=amd64 go build -tags netgo -o app &amp;&amp; \</pre><pre>docker build -t backendapp:2.0 . &amp;&amp; \</pre><pre>cd ..</pre><p><strong>Bff</strong></p><p>Cd into sources/bff directory and run:</p><pre>docker build -t bffapp .</pre><p><strong>Push them all</strong></p><p>Ok, now you have the images… push them all to a reposiroty of your choice and keep their names so we can set them into the k8s manifiests.</p><p>Or use these already built images:</p><ul><li>docker.io/juanmatias/canary-app:1.0</li><li>docker.io/juanmatias/canary-app:2.0</li><li>docker.io/juanmatias/canary-app:bff-1.0</li></ul><h4>Deploy the app</h4><p>We will deploy all the elements into kungfootest namespace.</p><p>CD into the root project directory and then:</p><pre>cd manifests</pre><p>Deploy the backend apps:</p><pre>kubectl apply -f deploy-backend.yaml -n kungfootest</pre><p>Deploy the bff:</p><pre>kubectl apply -f deploy-bff.yaml -n kungfootest</pre><p>Deploy the ingress:</p><pre>kubectl apply -f ingress.yaml -n kungfootest</pre><h4>Test the app</h4><p>Get the public IP:</p><pre>kubectl get ing -n kungfootest</pre><p>You can test your app with this command:</p><pre>curl <a href="http://">http://</a>$PUBLICIP/kungfutest/mytest</pre><p>You should have an output like this one:</p><pre>{&quot;id&quot;: &quot;mytest&quot;, &quot;response&quot;: &quot;Congratulations! Version 1.0 of your application is running on Kubernetes.&quot;}</pre><h3>Run the tests</h3><p>We’ll run two tests, locust to know response times, and resources to know the used resources.</p><h4>Locust</h4><p>From the project root dir:</p><pre>cd locust</pre><p>If the first time, create a virtual env and install locust:</p><pre>pip install locust</pre><p>Now, run the locust server:</p><pre>locust -f kungfootest.py</pre><p>This will open Locust server listening on localhost:8089… open it with your browser.</p><p>There, you must add the host (e.g. <a href="http://%24PUBLICIP">http://$PUBLICIP</a>), the max number of users and the users spawn rate. Then begin your tests.</p><p>I’ll test it with 100 users and a rate of 10 and let the test run for 2 minutes.</p><h4>Resources</h4><p>While locust test is running run the script resources.sh. When finish, just type CTRL+C and it will show the AVG mem and cpu.</p><p>NOTE: It’s important to keep in mind that this script will get the resources requested for nodes, and the real use only under kungfootest namespace.</p><h3>References</h3><p><a href="https://www.jeffgeerling.com/blog/2019/monitoring-kubernetes-cluster-utilization-and-capacity-poor-mans-way">Monitoring Kubernetes cluster utilization and capacity (the poor man’s way) | Jeff Geerling</a></p><p>First version of this post was published in my blog <a href="https://juanmatiasdelacamara.wordpress.com/2020/09/09/to-mesh-or-not-to-mesh/">here</a>.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dc969394baae" width="1" height="1" alt=""><hr><p><a href="https://resources.tarmac.io/to-mesh-or-not-to-mesh-dc969394baae">To mesh or not to mesh</a> was originally published in <a href="https://resources.tarmac.io">tarmac</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>