<?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[TysonWorks - Medium]]></title>
        <description><![CDATA[Cloud Consulting | tysonworks.com - Medium]]></description>
        <link>https://medium.com/tysonworks?source=rss----1caf405c08f9---4</link>
        <image>
            <url>https://cdn-images-1.medium.com/proxy/1*TGH72Nnw24QL3iV9IOm4VA.png</url>
            <title>TysonWorks - Medium</title>
            <link>https://medium.com/tysonworks?source=rss----1caf405c08f9---4</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Thu, 12 Nov 2026 22:23:27 GMT</lastBuildDate>
        <atom:link href="https://medium.com/feed/tysonworks" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Hosting Container Workloads on AWS: Here Are Your Options]]></title>
            <link>https://medium.com/tysonworks/hosting-container-workloads-on-aws-here-are-your-options-59087c7072e7?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/59087c7072e7</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[ecs-fargate]]></category>
            <category><![CDATA[kubernetes]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[amazon-web-services]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Sun, 25 Feb 2024 23:25:57 GMT</pubDate>
            <atom:updated>2024-02-25T23:25:44.479Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*LRzJYg_1aCupb9OLzJmYJQ.jpeg" /></figure><p>In recent years, the adoption of containers has revolutionized the way applications are developed, deployed, and managed. This rise in popularity is attributed to significant advantages in terms of portability and isolation. Understanding the available options is crucial for making informed decisions aligned with specific workload requirements. While Kubernetes is a well-known solution for managing container workloads, it is not the only option. In this post, I will introduce other services that can be beneficial in choosing the right solution.</p><p>While Kubernetes is pretty robust and popular, it’s crucial to understand that it’s not the only option for managing container workloads. AWS provides a range of alternatives that can support your container workloads, potentially leading to optimized costs and efficiency. These alternatives include services like AWS Elastic Container Service (ECS), which offers easy integration with AWS infrastructure, and AWS Fargate, which allows for serverless container deployment. Additionally, AWS Elastic Kubernetes Service (EKS) can be an option for those who prefer Kubernetes but want deeper integration with AWS services. Each of these services offers unique features and benefits, making it important to evaluate them based on your specific requirements and objectives.</p><p><strong>Main Platforms</strong></p><p><strong>EKS</strong><br>EKS is AWS’s managed Kubernetes service, perfect for those who require the full functionality of Kubernetes without the overhead of managing the control plane. It’s particularly suited for environments with complex, multi-service architectures, offering the scalability and flexibility that Kubernetes is known for.</p><p><strong>ECS</strong><br>ECS is a fully managed container management service, ideal for users seeking a straightforward solution for running Docker containers. It excels in environments that value simplicity and seamless integration with AWS services, such as EC2 and Fargate. ECS offers a balance of control and ease of use, making it suitable for a wide range of applications, from simple web apps to more sophisticated microservices architectures. It is particularly appealing for those who prefer a less complex alternative to Kubernetes, without compromising on the essential features needed for effective container management.</p><p><strong>AppRunner</strong><br>AWS AppRunner is the simplest solution for running web applications and APIs, designed for users who prioritize ease of use and quick deployment over extensive customization. It’s a fully managed service, eliminating the need for infrastructure management, and is optimal for straightforward applications where default configurations suffice. AppRunner automatically scales resources to match demand, ensuring efficient operation with minimal manual intervention. This service is particularly suited for developers and businesses looking to rapidly deploy their applications without delving into the complexities of container orchestration or server management. While it offers less customization than services like ECS or EKS, AppRunner is an excellent choice for projects where speed and simplicity are the main requirements.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/801/1*lRJH5rWCZF4TXopkMQ2KyA.png" /></figure><p><strong>Computing Options</strong></p><p><strong>AWS Fargate:</strong></p><p>Fargate is a serverless compute engine offered by AWS, specifically designed for running containers. It abstracts the underlying infrastructure, removing the need to provision and manage servers or clusters. When you use Fargate with ECS (Elastic Container Service) or EKS (Elastic Kubernetes Service), you simply specify the CPU and memory requirements for your containers, and Fargate handles the rest. It automatically allocates the compute resources, runs the containers, and scales them as needed, making it an ideal choice for users who prefer a hands-off approach to infrastructure management.</p><p><strong>Amazon EC2:</strong><br>Amazon EC2 (Elastic Compute Cloud) is a service that provides resizable compute capacity in the cloud, using virtual machines known as instances. When running containers on EC2, you have full control over these instances, meaning you can choose the type of instance, configure the operating system, and have complete control over the network and security settings. This level of control is particularly beneficial for applications that require specific configurations or optimizations. Using EC2 with ECS or EKS allows you to manage the underlying infrastructure for your container workloads, offering flexibility and control for more complex deployment scenarios.</p><p><strong>Tooling</strong><br><strong>AWS Copilot</strong>: Designed for ECS: AWS Copilot is specifically built for Amazon ECS. It provides a command-line interface (CLI) that simplifies the process of deploying and managing containerized applications on ECS.<br>Copilot assists in setting up an entire ECS architecture, including the creation of ECS services, task definitions, and cluster configurations. It also aids in setting up CI/CD pipelines, load balancers, and logging.<br>It is designed to be user-friendly, making it easier for developers to start with ECS without needing to deeply understand all the underlying details of AWS services.</p><p><strong>Kubectl: </strong>Kubectl is the command-line tool for Kubernetes and is used with AWS EKS. It allows users to deploy and manage applications on Kubernetes, control cluster resources, and view logs.<br>Kubernetes Operations: With Kubectl, users can perform a wide range of Kubernetes operations such as deploying applications, inspecting and managing cluster resources, and viewing logs and statuses of resources in the cluster.</p><p>For <strong>AWS AppRunner,</strong> the tooling is more integrated and abstracted, as AppRunner is a fully managed service with a focus on simplicity. Users typically interact with AppRunner through the AWS Management Console or AWS CLI. The service automates deployments and infrastructure management, so there’s less need for specialized tooling like Copilot or Kubectl.</p><p><strong>So which one to use?</strong></p><p><strong>Choose EKS for:</strong></p><ul><li>Complex, large-scale applications.</li><li>Projects needing Kubernetes API support.</li><li>Migrating to a Kubernetes environment.</li><li>Cost-effective container deployment.</li><li>Deploying across multiple infrastructures.</li><li>Utilizing Kubernetes’ flexibility.</li></ul><p><strong>Choose ECS for:</strong></p><ul><li>Simple, easy application management.</li><li>Situations where advanced EKS features aren’t needed.</li><li>Exclusive AWS focus with limited Kubernetes know-how.</li><li>Deep AWS service integration.</li><li>Scenarios with limited resources for Kubernetes migration.</li><li>Quick, streamlined container management.</li></ul><p><strong>For Computing Options, Choose:</strong></p><p><strong>Fargate for:</strong></p><ul><li>Serverless container deployment.</li><li>Automated scaling and management.</li><li>Focusing on applications over infrastructure.</li><li>Variable workloads with a pay-as-you-go model.</li><li>Strong application isolation.</li></ul><p><strong>EC2 for:</strong></p><ul><li>Full control over the environment.</li><li>Customizable compute needs.</li><li>Long-running, steady workloads.</li><li>Detailed monitoring and configuration.</li><li>Stable workloads with cost-effectiveness.</li></ul><p><strong>For Tooling, Choose:</strong></p><p><strong>Copilot for:</strong></p><ul><li>Easy-to-use CLI for ECS and Fargate.</li><li>Streamlining application workflow.</li><li>Seamless AWS service integration.</li><li>Automated infrastructure management.</li><li>Simplified Docker management.</li></ul><p><strong>Kubectl for:</strong></p><ul><li>Managing Kubernetes clusters.</li><li>Detailed control over Kubernetes resources.</li><li>Versatile cluster operations.</li><li>Advanced Kubernetes management.</li><li>Access to a wide range of Kubernetes tools and plugins.</li></ul><p>There you have it. There are many ‘whens’ and ‘ifs’. Generally, if you don’t have existing Kubernetes workloads and your primary goal is to run container-based services on AWS, I would recommend ECS. ECS also supports external instances on-premises through ECS Anywhere. As for computing options, if you prefer less overhead, then Fargate is a good choice. Regarding tooling, Copilot would be your best bet with these selections.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=59087c7072e7" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/hosting-container-workloads-on-aws-here-are-your-options-59087c7072e7">Hosting Container Workloads on AWS: Here Are Your Options</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why Multi-Cloud is Not a Good Idea?]]></title>
            <link>https://medium.com/tysonworks/why-multi-cloud-is-not-a-good-idea-6bb65f294921?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/6bb65f294921</guid>
            <category><![CDATA[azure]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[cloud-computing]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Wed, 14 Feb 2024 00:05:16 GMT</pubDate>
            <atom:updated>2024-02-14T00:05:02.962Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-Iq5c95ZmaSGX4NnlcNudA.png" /></figure><p>The appeal of adopting a multi-cloud strategy in today’s dynamic and ever-evolving cloud landscape is quite significant. This strategic approach entails the deployment of various cloud computing services within a single, diverse architecture, aiming to provide enhanced reliability and flexibility, while also potentially reducing costs. Despite these apparent advantages, the practical execution of a multi-cloud strategy can be far more intricate and may not always yield the anticipated benefits. In this discussion, we will delve deeper into the reasons why a multi-cloud strategy, despite its initial attractiveness, might not always be the most advantageous path for a multitude of businesses</p><h3>The Hidden Costs of Data Egress</h3><p>One of the most significant, yet frequently underestimated, concerns in a multi-cloud setup is the cost associated with data egress. When data is transferred extensively between different cloud environments, the fees can accumulate swiftly. These costs are often overlooked during the planning phase but can result in a substantial financial burden as the data scales. For businesses, particularly those handling large datasets, this can translate into unpredictably high operational costs, negating one of the primary advantages of cloud computing — cost efficiency.</p><h3>The Widening Skill Gap</h3><p>Adopting a multi-cloud strategy introduces a notable challenge: the widening skill gap. Each cloud platform, such as AWS, Azure, or Google Cloud, comes with its own unique set of tools and services, requiring specific expertise. This diversity necessitates a broader skill set from the IT team. For businesses, this means investing in extensive training, or hiring new personnel with the requisite skills, which can be a costly and time-consuming endeavor. Furthermore, the diversity in skill requirements can slow down development and deployment processes, affecting the overall agility and responsiveness of the organization.</p><h3>Amplified Security Risks</h3><p>While multi-cloud environments can offer redundancy and thus potentially increase resilience to localized failures, they also amplify security risks. Each cloud provider implements its own security protocols and compliances. Ensuring a consistent and robust security posture across multiple platforms is a complex task, often leading to gaps in the security framework. These gaps can make the infrastructure more vulnerable to cyber threats, requiring additional resources to monitor and secure multiple environments effectively.</p><h3>The Comprehensive Nature of Single Cloud Providers</h3><p>A primary argument for adopting a multi-cloud strategy is to leverage the best-of-breed services from various providers. However, this perspective might not be as relevant today as it once was. Major cloud providers like AWS offer a comprehensive suite of services that cater to a wide array of business needs. These services are continually evolving, with providers regularly adding new features and capabilities. This ongoing development often diminishes the need to mix and match services from multiple clouds, as a single provider frequently offers a holistic solution.</p><h3>Conclusion</h3><p>While the concept of a multi-cloud approach is attractive for its promise of flexibility, redundancy, and choice, the reality involves considerable challenges in terms of costs, skills, and security. Moreover, the evolving nature of major cloud providers, like AWS, often makes them a one-stop solution for most business requirements. Therefore, before committing to a multi-cloud strategy, it is crucial for businesses, especially those looking to optimize operational efficiency and cost, to thoroughly evaluate these factors. As a cloud consultant, my recommendation is to assess your specific business needs meticulously and weigh the pros and cons of a multi-cloud approach against the streamlined, comprehensive solutions offered by single cloud providers.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6bb65f294921" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/why-multi-cloud-is-not-a-good-idea-6bb65f294921">Why Multi-Cloud is Not a Good Idea?</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Protect Your Lambda Functions with AWS GuardDuty]]></title>
            <link>https://medium.com/tysonworks/protect-your-lambda-functions-with-aws-guardduty-71051be9b350?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/71051be9b350</guid>
            <category><![CDATA[cloud]]></category>
            <category><![CDATA[cloud-security]]></category>
            <category><![CDATA[aws-lambda]]></category>
            <category><![CDATA[devsecops]]></category>
            <category><![CDATA[aws]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Thu, 04 May 2023 13:45:04 GMT</pubDate>
            <atom:updated>2023-05-02T14:31:51.004Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*Bl6AO7DZVRDesZ_3U9iiWw.jpeg" /></figure><p>AWS has recently announced <strong>AWS GuardDuty</strong> support for <strong>AWS Lambda Protection</strong>. This tool identifies potential security threats when an AWS Lambda function gets invoked in your AWS environment. In this tutorial, I will guide you through the steps to enable and how to remedy potential issues.</p><p>Lambda Protection provides a crucial security layer by monitoring Lambda network activity logs, starting with <strong>VPC Flow Logs</strong> from all Lambda functions for your account. This includes logs that don’t use VPC networking and logs generated when the Lambda function gets invoked.</p><p>When GuardDuty identifies suspicious network traffic, potentially indicating a malicious piece of code within your Lambda function, a finding is generated. This allows you to be proactive in safeguarding your environment.</p><p><strong>Getting Started</strong><br>By default, an existing GuardDuty account can enable Lambda Protection with a 30 day trial period. For a new GuardDuty account, Lambda Protection is already enabled and included in the 30 day trial period.</p><p>Let’s get started with enabling Lambda Protection:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IZTTHs0HIPDkwTfdR8nEtQ.png" /></figure><p><strong>Lambda Network Activity Monitoring</strong><br>GuardDuty monitors network activity logs generated by invoking the Lambda functions. This includes Amazon VPC flow logs from all Lambda functions for your account, even those logs that don’t use VPC networking.</p><p><strong>Cost Optimization</strong><br>GuardDuty only charges for the amount of Lambda network activity logs data processed (in GB) to generate a finding. This approach optimizes cost by applying smart filters and analyzing a subset of Lambda network activity logs relevant to threat detection.</p><p><strong>Understanding Log Management</strong><br>GuardDuty doesn’t manage your Lambda network activity logs (including VPC and non-VPC flow logs) or make them accessible in your account. Instead, it focuses on analyzing logs to identify potential threats.</p><p><strong>What happens if your Lambda Functions are compromised?</strong></p><p>In the event that GuardDuty generates a Lambda Protection finding and the activity is unexpected, indicating your Lambda function may be compromised, it is essential to take immediate steps to remediate the issue. Here are the three steps you can follow.</p><p><strong>Step 1: Identify the Affected Lambda Function Version</strong><br>A GuardDuty finding for Lambda Protection provides the name, Amazon Resource Name (ARN), function version, and revision ID associated with the Lambda function listed in the finding details. Save these details as they will be needed in the subsequent steps.</p><p><strong>Step 2: Identify the Source of the Suspicious Activity</strong><br>The next step is to identify the source of the suspicious activity:</p><ul><li><strong>Review the code</strong>: Examine the code associated with the Lambda function version involved in the finding. Look out for any unusual or unexpected code blocks.</li><li><strong>Review the imported libraries and layers</strong>: Inspect the libraries and layers of the Lambda function version involved in the finding. Ensure these libraries and layers are trusted and required for your function.</li><li><strong>Use Amazon Inspector</strong>: If you have enabled Scanning AWS Lambda functions with Amazon Inspector, review the Amazon Inspector findings associated with the Lambda function involved in the finding.</li><li><strong>Review AWS CloudTrail logs</strong>: AWS CloudTrail logs will help identify the principal that caused the function update. Ensure that the activity was authorized or expected.</li></ul><p><strong>Step 3: Remediate the Impacted Lambda Function</strong><br>After identifying the source of the suspicious activity, the next step is to remediate the compromised Lambda function:</p><ul><li><strong>Disable the execution triggers</strong>: Temporarily disable the execution triggers of the Lambda function involved in the finding to prevent any further potential damage. For more information, see DeleteFunctionEventInvokeConfig.</li><li><strong>Review and update the Lambda code</strong>: Go through the Lambda code and update the libraries imports and Lambda function layers to remove the potentially suspicious libraries and layers.</li><li><strong>Mitigate Amazon Inspector findings</strong>: If Amazon Inspector findings are associated with the compromised Lambda function, take appropriate steps to mitigate them.</li></ul><p>GuardDuty’s Lambda Protection feature helps you tackle security threats to your AWS Lambda functions proactively. It’s a new tool in your DevSecOps toolkit that alerts you about possible threats.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=71051be9b350" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/protect-your-lambda-functions-with-aws-guardduty-71051be9b350">Protect Your Lambda Functions with AWS GuardDuty</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Cross-Stack References in CDK]]></title>
            <link>https://medium.com/tysonworks/cross-stack-references-in-cdk-da60530f2bfa?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/da60530f2bfa</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[aws-cdk]]></category>
            <category><![CDATA[infrastructure-as-code]]></category>
            <category><![CDATA[cloudformation]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Mon, 01 May 2023 00:30:48 GMT</pubDate>
            <atom:updated>2023-05-01T00:30:21.297Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e5YMnDmcJHAtj1Zqh1plkQ.png" /></figure><p><strong>AWS Cloud Development Kit (CDK)</strong> is a powerful <strong>Infrastructure as Code (IaC)</strong> tool, it’s used by AWS internally and many people are favoring CDK’s simple and powerful capabilities. CDK has many options, as a someone who worked many years in TypeScript/JavaScript world, it feels natural to me.</p><p>In this tutorial I will show you a very simple solution for managing cross-stack references. If you are familiar with <strong>CloudFormation</strong>, here is how you would be solving that problem</p><p><em>Use the Export output field to flag the value of a resource output for export. Then, use the Fn::ImportValue intrinsic function to import the value.</em></p><p>Define the references as Outputs.</p><pre>…..<br> &quot;Outputs&quot; : {<br> &quot;VPCId&quot; : {<br> &quot;Description&quot; : &quot;VPC ID&quot;,<br> &quot;Value&quot; : { &quot;Ref&quot; : &quot;VPC&quot; },<br> &quot;Export&quot; : { &quot;Name&quot; : {&quot;Fn::Sub&quot;: &quot;${AWS::StackName}-VPCID&quot; }}<br> },<br> &quot;PublicSubnet&quot; : {<br> &quot;Description&quot; : &quot;The subnet ID to use for public web servers&quot;,<br> &quot;Value&quot; : { &quot;Ref&quot; : &quot;PublicSubnet&quot; },<br> &quot;Export&quot; : { &quot;Name&quot; : {&quot;Fn::Sub&quot;: &quot;${AWS::StackName}-SubnetID&quot; }}<br> },<br> &quot;WebServerSecurityGroup&quot; : {<br> &quot;Description&quot; : &quot;The security group ID to use for public web servers&quot;,<br> &quot;Value&quot; : { &quot;Fn::GetAtt&quot; : [&quot;WebServerSecurityGroup&quot;, &quot;GroupId&quot;] },<br> &quot;Export&quot; : { &quot;Name&quot; : {&quot;Fn::Sub&quot;: &quot;${AWS::StackName}-SecurityGroupID&quot; }}<br> }<br> }</pre><p>Then later referencing from another stack.</p><pre>….<br> &quot;Properties&quot;: {<br> &quot;InstanceType&quot; : &quot;t2.micro&quot;,<br> &quot;ImageId&quot;: { &quot;Fn::FindInMap&quot;: [ &quot;AWSRegionArch2AMI&quot;, { &quot;Ref&quot;: &quot;AWS::Region&quot; } , &quot;HVM64&quot; ] },<br> &quot;NetworkInterfaces&quot; : [{<br> &quot;GroupSet&quot; : [{ &quot;Fn::ImportValue&quot; : {&quot;Fn::Sub&quot;: &quot;${NetworkStackName}-SecurityGroupID&quot; } }],<br> &quot;AssociatePublicIpAddress&quot; : &quot;true&quot;,<br> &quot;DeviceIndex&quot; : &quot;0&quot;,<br> &quot;DeleteOnTermination&quot; : &quot;true&quot;,<br> &quot;SubnetId&quot; : { &quot;Fn::ImportValue&quot; : {&quot;Fn::Sub&quot;: &quot;${NetworkStackName}-SubnetID&quot; } }<br> }],</pre><p>Let’s try to replicate the same thing with two simple CDK stacks. In the first stack, we will be creating a DynamoDB table. In the second Stack, we will create a Lambda function and pass a reference to the DynamoDB table referenced in the first Stack.</p><p>Here is the DynamoDB Stack.</p><pre>class DynamoStack extends cdk.Stack {<br>  constructor(scope: Construct, id: string, props?: cdk.StackProps) {<br>    super(scope, id, props);<br><br>    const dynamoTable = new dynamodb.Table(this, &quot;dynamo-table&quot;, {<br>      partitionKey: {<br>        name: &quot;id&quot;,<br>        type: dynamodb.AttributeType.STRING<br>      },<br>      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST<br>    });<br><br>  }<br>}</pre><p>Just one DynamoDB table, Pay per Request billing option. Let’s define the Lambda Stack.</p><pre>interface LambdaStackProps extends cdk.StackProps  {<br>  DYNAMO_TABLE_NAME: string;<br>}<br><br>class LambdaStack extends cdk.Stack {<br>  constructor(scope: Construct, id: string, props: LambdaStackProps) {<br>    super(scope, id, props);<br><br>    const LambdaFunction = new lambda.Function(this, &quot;lambda-function&quot;, {<br>      code: lambda.InlineCode.fromInline(`exports.handler = function(event, ctx, cb) {<br>          console.log(process.env.DYNAMO_TABLE_NAME);<br>         return cb(null, &#39;hello world&#39;); <br>        }`),<br>      handler: &quot;index.handler&quot;,<br>      runtime: lambda.Runtime.NODEJS_18_X,<br>      environment: {<br>        DYNAMO_TABLE_NAME: props.DYNAMO_TABLE_NAME<br>      }<br>    });<br><br>  }<br>}</pre><p>Notice that we are using <strong>props.DYNAMO_TABLE_NAME</strong> variable. We need a way to pass this information.</p><pre>const app = new cdk.App();<br><br>const dynamoStack = new DynamoStack(app, &quot;DynamoStack&quot;, {<br>  env: {<br>    region: process.env.AWS_REGION,<br>    account: process.env.AWS_ACCOUNT_ID<br>  }<br>});<br><br>const lambdaStack = new LambdaStack(app, &quot;LambdaStack&quot;, {<br>  env: {<br>    region: process.env.AWS_REGION,<br>    account: process.env.AWS_ACCOUNT_ID<br>  },<br>  DYNAMO_TABLE_NAME: dynamoStack.stackName<br>})</pre><p>Very simple, yet effective. Now you might ask why we can’t have both resources in the same Stack. The answer is yes, you can. But when your Stacks get bigger, it’s a good idea to separate Stacks into Logical Units. For example, your database resources can be under Data Stack, your Lambda functions might be in Lambda Stack, whereas your Kubernetes cluster might be in EKS Stack. I will write another blog post on managing and designing Multi-Stack CDK projects, so stay tuned.</p><p>AWS SSM Parameter Store can also be used to manage Cross-Stack references. <a href="https://docs.aws.amazon.com/cdk/v2/guide/get_ssm_value.html">https://docs.aws.amazon.com/cdk/v2/guide/get_ssm_value.html</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=da60530f2bfa" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/cross-stack-references-in-cdk-da60530f2bfa">Cross-Stack References in CDK</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Monitor Your Internet-Facing Applications with AWS CloudWatch Internet Monitor]]></title>
            <link>https://medium.com/tysonworks/monitor-your-internet-facing-applications-with-aws-cloudwatch-internet-monitor-7f9cacb969ef?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/7f9cacb969ef</guid>
            <category><![CDATA[cloudwatch]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[devops]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Sun, 30 Apr 2023 20:32:12 GMT</pubDate>
            <atom:updated>2023-04-30T23:06:46.679Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1023/1*Kt9SAOjW1DgS8P7qr2hfvg.jpeg" /></figure><p><strong>AWS CloudWatch Internet Monitor</strong> is a service that helps you monitor the availability and performance of your internet-facing applications. It does this by sending probes to your application from different locations around the world, and then measuring the latency, and packet loss of the connections.</p><p>CloudWatch Internet Monitor uses a global network of probes to monitor the internet. These probes are located in different cities around the world, and they are connected to the internet through different networks. When you create an internet monitor, CloudWatch Internet Monitor will select a set of probes that are closest to your application. These probes will then send requests to your application, and CloudWatch Internet Monitor will measure the performance of the connections.</p><p>With CloudWatch Internet Monitor, we can monitor the following metrics.</p><p><strong>Availability</strong>: CloudWatch Internet Monitor can detect when your application is unavailable. It does this by sending probes to your application at regular intervals. If a probe fails to connect to your application, CloudWatch Internet Monitor will send you an alert.</p><p><strong>Performance</strong>: CloudWatch Internet Monitor can measure the performance of your application. It does this by measuring the latency, jitter, and packet loss of the connections between the probes and your application.</p><p><strong>Geolocation</strong>: CloudWatch Internet Monitor can track the location of your users. It does this by measuring the IP addresses of the users who connect to your application.</p><p><strong>ISPs</strong>: CloudWatch Internet Monitor can track the ISPs of your users. It does this by measuring the AS numbers of the networks that the users are connected to.</p><p><strong>Key Components:</strong></p><p><strong>Monitor</strong>: A monitor serves as the receptacle for your established parameters, designating which resources are subject to observation.</p><p><strong>Health Event:</strong> In instances where the Internet Monitor identifies noteworthy degradation in your network performance, it initiates a health event. Each such event provides detailed information about the affected client locations and the involved Internet Service Providers (ISPs).</p><p><strong>Performance and Availability Scores</strong> (Health Scores): These are statistical approximations of the fraction of traffic to your application that remains unaffected by any dips in performance or availability. These scores can also be accessed as metrics in CloudWatch.</p><p><strong>CloudWatch Logs</strong>: Catering to the locations and network providers that are particular to your clients, the Internet Monitor disseminates measurements to CloudWatch Logs. These measurements encompass performance and availability scores, the volume of data transferred, and the round-trip time (RTT).</p><p>Now that we know what Internet Monitor is, let’s create a simple monitor and experience the product.</p><p>Head over to CloudWatch Console, click on the Internet Monitors tab, then click Create Internet Monitor button.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FqPcHtvMD9rORXxPvLuAaQ.png" /><figcaption>Enter the details for the monitor, beware that you can only add resources associated with your account.</figcaption></figure><p>Wait for a while for data to be collected. The check the CloudWatch Console.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*O-Qqa_bCMbZj_N1gAMuVoA.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NHqvGBs_U9_Y7LLljWC7_A.png" /><figcaption>You need to wait for a long time to see some data here.</figcaption></figure><p>Internet Monitor also logs each event to CloudWatch Logs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*gnP_uQ_FlIClS6udrWbbVg.png" /></figure><p>Let’s check out the City one</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rnWpoqamaArXNafMash-wQ.png" /></figure><p>That’s neat, you see traffic coming from all over the globe.</p><p>Don’t forget to remove the resources created in this tutorial. Click Disable Internet Monitor, then Delete.</p><p>AWS CloudWatch Internet Monitor is a powerful tool that can help you monitor the availability and performance of your internet-facing applications. It is easy to use and configure, and it provides a wealth of metrics that you can use to track the performance of your applications.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7f9cacb969ef" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/monitor-your-internet-facing-applications-with-aws-cloudwatch-internet-monitor-7f9cacb969ef">Monitor Your Internet-Facing Applications with AWS CloudWatch Internet Monitor</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Exposing AWS Lambda Functions to Internet? Here’s your options]]></title>
            <link>https://medium.com/tysonworks/exposing-aws-lambda-functions-to-internet-heres-your-options-96f84705384a?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/96f84705384a</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[api-gateway]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[lambda]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Sat, 22 Apr 2023 13:46:46 GMT</pubDate>
            <atom:updated>2023-04-22T13:45:40.962Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*djBovuUveshzYa9_TqPJzg.png" /></figure><p><strong>AWS Lambda</strong> is an excellent solution for handling cloud workloads without the need of managing complex infrastructure. There will be times you may need to make your Lambda function accessible to external users or services. In this blog post, I’ll explain three distinct approaches to expose Lambda Functions to the internet: <strong>API Gateway,</strong> <strong>Application Load Balancer</strong>, and <strong>Function URLs</strong>.</p><blockquote>I always like to follow the “right tool for the right job” approach, which has served me well throughout my career.</blockquote><h3><strong>API Gateway</strong></h3><p>Amazon API Gateway is a fully managed service for creating, publishing, maintaining, monitoring, and securing REST, HTTP, and WebSocket APIs at any scale. It acts as a “front door” for applications to access data, business logic, or functionality from your backend services, such as workloads running on EC2, and Lambda.</p><p><strong>Features</strong></p><p>- API Mangement<br>- WebSocket Support<br>- Access Control via IAM, Cognito, OAuth2, Lambda Authorizer<br>- Deployment Strategies, including Canary releases<br>- Version Management<br>- OpenAPI Integration<br>- Web Application Framework(WAF) Integration<br>- Rate Limiting</p><p>In short, you would want to use API Gateway if you are looking for full-blown API framework where you will need rich features. Keep in mind, though, that the costs associated with API Gateway are higher compared to other options, but totally worth it in my opinion.</p><h3><strong>Application Load Balancer</strong></h3><p>AWS Application Load Balancer (ALB) is a fully managed service that provides Layer-7 load balancing for HTTP/HTTPS traffic to targets such as EC2 instances, Lambda Functions, ECS, and EKS based on request attributes like headers, HTTP methods, query string parameters, and source IP address CIDR.</p><p>Feaetures<br>- Advanced Routing Capabilities<br>- TLS Offloading<br>- Web Application Firewall (WAF) Integration<br>- Sticky Sessions<br>- HTTP/2 and gRPC support<br>- Access Control via Cognito and IAM</p><p>Consider using ALB if you want to use a Load Balancer to manage requests for your Lambda Functions without the need for a comprehensive API framework like API Gateway. ALB is also a suitable choice when performance is a factor if you have a high traffic workload.</p><h3><strong>Functions URLs</strong></h3><p>AWS Lambda Function URLs are built-in HTTPS endpoints that can be associated with a single Lambda function or function alias. They provide a simplified way to configure an HTTPS endpoint in front of your function without needing to learn, configure, and operate additional services like API Gateway or ALB.</p><p>Features<br>- Simple setup process<br>- Version support via mapping to function alias<br>- Authentication via IAM<br>- CORS Support</p><p>Function URLs are ideal for scenarios in which you need to deploy a single-function microservice with a public endpoint that doesn’t need features offered by API Gateway or ALB. Lambda Function URLs enable you to attach HTTPS endpoints to any Lambda function. Functions URLs are easy to set up, have no dependency on other cloud resources.</p><p>Now that we’ve explored each option, let’s discuss potential use cases for each one.</p><p><strong>Backend for a SaaS business</strong>:</p><p><strong>API Gateway</strong>: Ideal for situations where support for multiple versions of APIs, user authentication, rate limiting for bad actors, OpenAPI compatibility, and Canary deployments for gradual rollout of changes are necessary.</p><p><strong>Microservices</strong></p><p><strong>Application Load Balancer:</strong> Best suited for a Microservice responsible for sending notifications to recipients. This microservice may be called by other applications, leading to high load. In such a scenario, it is essential to manage the load effectively, ensure performance, handle authentication, and have the ability for advanced routing and support for multiple targets.</p><p><strong>Webhooks</strong></p><p><strong>Function URLs</strong>: The perfect choice for a webhook for external services when the goal is to minimize resource usage and overhead, or for form handlers that forward user-submitted form data. In both cases, Function URLs offer a simplified solution with reduced overhead.</p><p>In this short article I’ve discussed the options for exposing your Lambda functions to internet. Hopefully this can guide you choosing the right option for your use case.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=96f84705384a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/exposing-aws-lambda-functions-to-internet-heres-your-options-96f84705384a">Exposing AWS Lambda Functions to Internet? Here’s your options</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[I asked ChatGPT to Generate AWS Templates. Results are Shocking.]]></title>
            <link>https://medium.com/tysonworks/i-asked-chatgpt-to-generate-aws-templates-results-are-shocking-f12e4a13ea64?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/f12e4a13ea64</guid>
            <category><![CDATA[cdk]]></category>
            <category><![CDATA[chatgpt]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[openai]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Mon, 03 Apr 2023 23:19:16 GMT</pubDate>
            <atom:updated>2023-04-03T23:15:08.973Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3KtWm0CWOmfk-lRYfSj02g.jpeg" /></figure><p>The rise of ChatGPT and other generative AI technologies has started a significant amount of discussion around their potential to replace jobs. In this tutorial, I will explore the capabilities of ChatGPT by asking to generate common workloads on AWS. I will keep things fairly simple for this one, which could be expected from a Junior Cloud Solutions Architect.</p><p><em>Sorry for the clickbait title, the results are not shocking 🤷‍♂️</em></p><p>Let’s start with the first task. I will ask ChatGPT to use AWS CDK instead of CloudFormation, we don’t want to go over thousand lines of YAML/JSON (no thanks). CDK version 2.63.0 was used in the examples.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ELLHO7io8aiGWDYZ9GO15Q.png" /></figure><pre>import * as cdk from &#39;aws-cdk-lib&#39;;<br>import * as s3 from &#39;aws-cdk-lib/aws-s3&#39;;<br>import * as cloudfront from &#39;aws-cdk-lib/aws-cloudfront&#39;;<br>import * as origins from &#39;aws-cdk-lib/aws-cloudfront-origins&#39;;<br><br>export class YourProjectNameStack extends cdk.Stack {<br>  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {<br>    super(scope, id, props);<br><br>    // Create an S3 bucket for static website hosting<br>    const websiteBucket = new s3.Bucket(this, &#39;WebsiteBucket&#39;, {<br>      websiteIndexDocument: &#39;index.html&#39;,<br>      websiteErrorDocument: &#39;error.html&#39;,<br>      publicReadAccess: true,<br>      removalPolicy: cdk.RemovalPolicy.DESTROY, // NOT recommended for production<br>    });<br><br>    // Create a CloudFront distribution to serve the static website<br>    const distribution = new cloudfront.Distribution(this, &#39;Distribution&#39;, {<br>      defaultBehavior: { origin: new origins.S3Origin(websiteBucket) },<br>      defaultRootObject: &#39;index.html&#39;,<br>    });<br><br>    // Output the S3 bucket and CloudFront distribution domain names<br>    new cdk.CfnOutput(this, &#39;BucketDomainName&#39;, {<br>      value: websiteBucket.bucketWebsiteDomainName,<br>    });<br>    new cdk.CfnOutput(this, &#39;DistributionDomainName&#39;, {<br>      value: distribution.distributionDomainName,<br>    });<br>  }<br>}</pre><p>Construct base class was moved to separate module called ‘<strong>constructs</strong>’ in v2 version of the CDK. Although ChatGPT is importing v2 modules, it tried to use v1 <strong>‘cdk.Construct</strong>’ class instead.</p><pre>import * as cdk from &#39;aws-cdk-lib&#39;;<br>import * as s3 from &#39;aws-cdk-lib/aws-s3&#39;;<br>import * as cloudfront from &#39;aws-cdk-lib/aws-cloudfront&#39;;<br>import * as origins from &#39;aws-cdk-lib/aws-cloudfront-origins&#39;;<br>import { Construct } from &#39;constructs&#39;<br><br>export class YourProjectNameStack extends cdk.Stack {<br>  constructor(scope: Construct, id: string, props?: cdk.StackProps) {</pre><p>Overall I give ChatGPT 8/10 here. It’s a quick fix if you know what you are looking for, but it can confuse beginners.</p><p>Let’s continue with the second task.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*J5Y6QEhR6kfbnwZSA4demA.png" /></figure><pre>import * as cdk from &#39;aws-cdk-lib&#39;;<br>import * as cognito from &#39;aws-cdk-lib/aws-cognito&#39;;<br>import * as lambda from &#39;aws-cdk-lib/aws-lambda&#39;;<br>import * as apigatewayv2 from &#39;aws-cdk-lib/aws-apigatewayv2&#39;;<br>import * as authorizers from &#39;aws-cdk-lib/aws-apigatewayv2-authorizers&#39;;<br><br>export class YourProjectNameStack extends cdk.Stack {<br>  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {<br>    super(scope, id, props);<br><br>    // Create a Cognito User Pool<br>    const userPool = new cognito.UserPool(this, &#39;UserPool&#39;, {<br>      selfSignUpEnabled: true,<br>      signInAliases: {<br>        email: true,<br>      },<br>      autoVerify: {<br>        email: true,<br>      },<br>    });<br><br>    // Create a Lambda Function<br>    const lambdaFunction = new lambda.Function(this, &#39;MyFunction&#39;, {<br>      runtime: lambda.Runtime.NODEJS_14_X,<br>      handler: &#39;index.handler&#39;,<br>      code: lambda.Code.fromInline(`<br>        exports.handler = async (event) =&gt; {<br>          console.log(&#39;Event:&#39;, JSON.stringify(event, null, 2));<br>          return {<br>            statusCode: 200,<br>            body: JSON.stringify({ message: &#39;Success&#39; }),<br>          };<br>        };<br>      `),<br>    });<br><br>    // Create a REST API using API Gateway<br>    const httpApi = new apigatewayv2.HttpApi(this, &#39;MyApi&#39;, {<br>      apiName: &#39;my-api&#39;,<br>      corsPreflight: {<br>        allowOrigins: apigatewayv2.Cors.ALL_ORIGINS,<br>        allowMethods: apigatewayv2.Cors.ALL_METHODS,<br>      },<br>      defaultAuthorizer: new authorizers.HttpUserPoolAuthorizer({<br>        userPool,<br>      }),<br>    });<br><br>    // Add a route for the Lambda function<br>    httpApi.addRoutes({<br>      path: &#39;/my-function&#39;,<br>      methods: [apigatewayv2.HttpMethod.ANY],<br>      integration: new apigatewayv2_integrations.HttpLambdaIntegration({<br>        handler: lambdaFunction,<br>      }),<br>    });<br><br>    // Output the User Pool ID, REST API endpoint, and Lambda function ARN<br>    new cdk.CfnOutput(this, &#39;UserPoolId&#39;, {<br>      value: userPool.userPoolId,<br>    });<br>    new cdk.CfnOutput(this, &#39;ApiEndpoint&#39;, {<br>      value: httpApi.url!,<br>    });<br>    new cdk.CfnOutput(this, &#39;LambdaFunctionArn&#39;, {<br>      value: lambdaFunction.functionArn,<br>    });<br>  }<br>}</pre><p>ChatGPT is making the same mistakes here, but this time with multiple modules. Outside of the Construct issue I’ve mentioned above, we have now issues with the ‘<strong>apigatewayv2</strong>’ and ‘<strong>authorizers</strong>’ modules. It tries to use experimental features that don’t exist in the modules we are importing.</p><p>Here’s how I would do it, without using the experimental L2 Construct Library.</p><pre>import * as cdk from &#39;aws-cdk-lib&#39;;<br>import * as cognito from &#39;aws-cdk-lib/aws-cognito&#39;;<br>import * as lambda from &#39;aws-cdk-lib/aws-lambda&#39;;<br>import * as apigw from &#39;aws-cdk-lib/aws-apigateway&#39;;<br><br>import { Construct } from &quot;constructs&quot;<br><br>export class YourProjectNameStack extends cdk.Stack {<br>  constructor(scope: Construct, id: string, props?: cdk.StackProps) {<br>    super(scope, id, props);<br><br>    // Create a Cognito User Pool<br>    const userPool = new cognito.UserPool(this, &#39;MyUserPool&#39;, {<br>      userPoolName: &#39;my-user-pool&#39;,<br>      selfSignUpEnabled: true,<br>      signInAliases: {<br>        email: true,<br>        phone: false,<br>        username: true,<br>      },<br>      autoVerify: {<br>        email: true,<br>      },<br>    });<br><br>    // Create a Lambda function that logs incoming events and returns a &quot;Success&quot; message<br>    const logEventsFunction = new lambda.Function(this, &#39;LogEventsFunction&#39;, {<br>      runtime: lambda.Runtime.NODEJS_14_X,<br>      handler: &#39;index.handler&#39;,<br>      code: lambda.Code.fromInline(`<br>        exports.handler = async (event) =&gt; {<br>          console.log(&#39;Event:&#39;, JSON.stringify(event, null, 2));<br>          return {<br>            statusCode: 200,<br>            body: JSON.stringify({ message: &#39;Success&#39; }),<br>          };<br>        };<br>      `),<br>    });<br><br>    // Create a REST API using API Gateway<br>    const api = new apigw.RestApi(this, &#39;MyApi&#39;, {<br>      restApiName: &#39;My API&#39;,<br>      defaultCorsPreflightOptions: {<br>        allowOrigins: apigw.Cors.ALL_ORIGINS,<br>        allowMethods: apigw.Cors.ALL_METHODS,<br>        allowHeaders: [&#39;*&#39;],<br>      },<br>    });<br><br>    // Use Cognito User Pool for REST API Authorizer<br>    const authorizer = new apigw.CfnAuthorizer(this, &#39;MyApiAuthorizer&#39;, {<br>      restApiId: api.restApiId,<br>      name: &#39;MyAuthorizer&#39;,<br>      type: apigw.AuthorizationType.COGNITO,<br>      identitySource: &#39;method.request.header.Authorization&#39;,<br>      providerArns: [userPool.userPoolArn],<br>    });<br><br>    // Serve HTTP requests for the Lambda function<br>    const lambdaIntegration = new apigw.LambdaIntegration(logEventsFunction);<br>    const logEventsResource = api.root.addResource(&#39;logEvents&#39;);<br>    logEventsResource.addMethod(&#39;POST&#39;, lambdaIntegration, {<br>      authorizationType: apigw.AuthorizationType.COGNITO,<br>      authorizer: { authorizerId: authorizer.ref },<br>    });<br><br>    // Output the User Pool ID, REST API endpoint, and Lambda function ARN<br>    new cdk.CfnOutput(this, &#39;UserPoolId&#39;, {<br>      value: userPool.userPoolId,<br>    });<br>    new cdk.CfnOutput(this, &#39;ApiEndpoint&#39;, {<br>      value: api.url,<br>    });<br>    new cdk.CfnOutput(this, &#39;LambdaFunctionArn&#39;, {<br>      value: logEventsFunction.functionArn,<br>    });<br>  }<br>}</pre><p>I give ChatGPT 6/10 for this one, if you are not comfortable with CDK, you could spend hours fixing the template.</p><p>Let’s move on the final task.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*myuKYw77Eqo5pLvVmE8kow.png" /></figure><pre>import * as cdk from &#39;aws-cdk-lib&#39;;<br>import * as appsync from &#39;aws-cdk-lib/aws-appsync&#39;;<br>import * as cognito from &#39;aws-cdk-lib/aws-cognito&#39;;<br>import * as dynamodb from &#39;aws-cdk-lib/aws-dynamodb&#39;;<br><br>export class YourProjectNameStack extends cdk.Stack {<br>  constructor(scope: cdk.Construct, id: string, props?: cdk.StackProps) {<br>    super(scope, id, props);<br><br>    // Create a Cognito User Pool<br>    const userPool = new cognito.UserPool(this, &#39;MyUserPool&#39;, {<br>      userPoolName: &#39;my-user-pool&#39;,<br>      selfSignUpEnabled: true,<br>      signInAliases: {<br>        email: true,<br>        phone: false,<br>        username: true,<br>      },<br>      autoVerify: {<br>        email: true,<br>      },<br>    });<br><br>    // Create an AppSync API<br>    const api = new appsync.GraphqlApi(this, &#39;MyApi&#39;, {<br>      name: &#39;my-api&#39;,<br>      schema: appsync.Schema.fromAsset(&#39;graphql/schema.graphql&#39;),<br>      authorizationConfig: {<br>        defaultAuthorization: {<br>          authorizationType: appsync.AuthorizationType.USER_POOL,<br>          userPoolConfig: {<br>            userPool,<br>          },<br>        },<br>      },<br>      xrayEnabled: true,<br>    });<br><br>    // Create a DynamoDB table<br>    const table = new dynamodb.Table(this, &#39;MyTable&#39;, {<br>      partitionKey: { name: &#39;id&#39;, type: dynamodb.AttributeType.STRING },<br>    });<br><br>    // Create a data source for the AppSync API<br>    const dataSource = api.addDynamoDbDataSource(&#39;MyDataSource&#39;, table);<br><br>    // Add a GraphQL resolver for the data source<br>    dataSource.createResolver({<br>      typeName: &#39;Query&#39;,<br>      fieldName: &#39;getItems&#39;,<br>      requestMappingTemplate: appsync.MappingTemplate.dynamoDbScanTable(),<br>      responseMappingTemplate: appsync.MappingTemplate.dynamoDbResultList(),<br>    });<br><br>    // Output the AppSync API URL and Cognito User Pool ID<br>    new cdk.CfnOutput(this, &#39;GraphqlApiUrl&#39;, {<br>      value: api.graphqlUrl,<br>    });<br><br>    new cdk.CfnOutput(this, &#39;UserPoolId&#39;, {<br>      value: userPool.userPoolId,<br>    });<br>  }<br>}</pre><p>ChatGPT is off again, this time by a large margin. Here’s you would accomplish the same task without using the experimental L2 Construct Library</p><pre>import * as cdk from &#39;aws-cdk-lib&#39;;<br>import * as cognito from &#39;aws-cdk-lib/aws-cognito&#39;;<br>import * as appsync from &#39;aws-cdk-lib/aws-appsync&#39;;<br>import * as dynamodb from &#39;aws-cdk-lib/aws-dynamodb&#39;;<br>import * as iam from &quot;aws-cdk-lib/aws-iam&quot;;<br>import { readFileSync } from &quot;fs&quot;;<br>import { Construct } from &quot;constructs&quot;;<br><br>export class YourProjectNameStack extends cdk.Stack {<br>  constructor(scope: Construct, id: string, props?: cdk.StackProps) {<br>    super(scope, id, props);<br><br>    // Create a Cognito User Pool<br>    const userPool = new cognito.UserPool(this, &#39;MyUserPool&#39;, {<br>      userPoolName: &#39;my-user-pool&#39;,<br>      selfSignUpEnabled: true,<br>      signInAliases: {<br>        email: true,<br>        phone: false,<br>        username: true,<br>      },<br>      autoVerify: {<br>        email: true,<br>      },<br>    });<br><br>    // Create a DynamoDB table<br>    const table = new dynamodb.Table(this, &#39;MyTable&#39;, {<br>      tableName: &#39;my-table&#39;,<br>      partitionKey: { name: &#39;id&#39;, type: dynamodb.AttributeType.STRING },<br>      billingMode: dynamodb.BillingMode.PAY_PER_REQUEST,<br>      removalPolicy: cdk.RemovalPolicy.DESTROY,<br>    });<br><br>    // Create AppSync GraphQL API with Cognito User Pool as the authorizer<br>    const api = new appsync.CfnGraphQLApi(this, &#39;MyApi&#39;, {<br>      name: &#39;my-api&#39;,<br>      authenticationType: &quot;AMAZON_COGNITO_USER_POOLS&quot;,<br>      userPoolConfig: {<br>        userPoolId: userPool.userPoolId,<br>        awsRegion: this.region<br>      },<br>    });<br><br>    const schema = new appsync.CfnGraphQLSchema(this, &quot;graphql-api-schema&quot;, {<br>      apiId: api.attrApiId,<br>      definition: readFileSync(&quot;./schema.graphql&quot;).toString(),<br>    });<br>    schema.addDependsOn(api);<br><br>    const tableRole = new iam.Role(this, &#39;dynamo-role&#39;, {<br>      assumedBy: new iam.ServicePrincipal(&#39;appsync.amazonaws.com&#39;)<br>    });<br>    tableRole.addManagedPolicy(iam.ManagedPolicy.fromAwsManagedPolicyName(&#39;AmazonDynamoDBFullAccess&#39;));<br><br>    const dataSource = new appsync.CfnDataSource(this, &#39;ItemsDataSource&#39;, {<br>      apiId: api.attrApiId,<br>      name: &#39;table-source&#39;,<br>      type: &#39;AMAZON_DYNAMODB&#39;,<br>      dynamoDbConfig: {<br>        tableName: table.tableName,<br>        awsRegion: this.region<br>      },<br>      serviceRoleArn: tableRole.roleArn<br>    });<br><br>    const getAllResolver = new appsync.CfnResolver(this, &#39;GetAllQueryResolver&#39;, {<br>      apiId: api.attrApiId,<br>      typeName: &#39;Query&#39;,<br>      fieldName: &#39;all&#39;,<br>      dataSourceName: dataSource.name,<br>      requestMappingTemplate: `{<br>        &quot;version&quot;: &quot;2017-02-28&quot;,<br>        &quot;operation&quot;: &quot;Scan&quot;,<br>        &quot;limit&quot;: $util.defaultIfNull($ctx.args.limit, 20),<br>        &quot;nextToken&quot;: $util.toJson($util.defaultIfNullOrEmpty($ctx.args.nextToken, null))<br>      }`,<br>      responseMappingTemplate: `$util.toJson($ctx.result)`<br>    });<br>    getAllResolver.addDependsOn(schema);<br><br>    // Add the rest of the resolvers<br><br>    new cdk.CfnOutput(this, &#39;GraphqlApiUrl&#39;, {<br>      value: api.attrGraphQlUrl as string,<br>    });<br><br>    new cdk.CfnOutput(this, &#39;UserPoolId&#39;, {<br>      value: userPool.userPoolId,<br>    });<br>  }<br>}</pre><p>I give it 5/10 here. It will take some time to fix and will confuse you again. I would say you are better off starting from scratch for this one.</p><p>Overall ChatGPT can be helpful guiding you through implementing different workloads. In our case we had to manually intervene and fix the issues. I would advise against beginners relying on ChatGPT or other AI tools to complete their tasks without first grasping the fundamentals.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f12e4a13ea64" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/i-asked-chatgpt-to-generate-aws-templates-results-are-shocking-f12e4a13ea64">I asked ChatGPT to Generate AWS Templates. Results are Shocking.</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[TLS 1.3 Support for Application Load Balancer]]></title>
            <link>https://medium.com/tysonworks/tls-1-3-support-for-application-load-balancer-22a480b428cb?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/22a480b428cb</guid>
            <category><![CDATA[ec2]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[tls]]></category>
            <category><![CDATA[ssl]]></category>
            <category><![CDATA[application-load-balancer]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Sun, 02 Apr 2023 10:01:11 GMT</pubDate>
            <atom:updated>2023-04-02T10:01:11.656Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dZvjJ-9NrvvaETLba9ao3A.png" /></figure><p>Transport Layer Security (<strong>TLS</strong>) is a cryptographic protocol designed to provide communications security over a computer network. The protocol is widely used in applications such as email, instant messaging, and voice over IP, but its use in securing HTTPS remains the most publicly visible.</p><p>TLS is a proposed Internet Engineering Task Force (IETF) standard, first defined in 1999, and the current version is TLS 1.3, defined in August 2018.</p><p>AWS Application Load Balancer (<strong>ALB</strong>) now supports version 1.3 of the Transport Layer Security (TLS) protocol, enabling you to optimize the performance of your backend application servers while helping to keep your workloads secure. TLS 1.3 on ALB works by offloading encryption and decryption of TLS traffic from your application servers to the load balancer. TLS 1.3 is optimized for performance and security by using one round trip (1-RTT) TLS handshakes, and only supporting ciphers that provide perfect forward secrecy.</p><p>Using TLS with ALB provides you with the tools to more easily manage your application security, enabling you to improve the security posture of your applications. ALB allows you to centralize the deployment of SSL certificates using ALB’s integration with AWS Certificate Manager (ACM) and AWS Identity and Access Management (IAM). You can also analyze TLS traffic patterns and troubleshoot issues using ALB TLS metrics and access logs. ALB also allows you to use predefined security polices, which control the ciphers and protocols that your ALB presents to your clients.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZQFEKfz0rm18BDcxre4muQ.png" /></figure><p>To update your security policy to TLS 1.3, you can modify existing listeners through the EC2 console or by using the AWS CLI, call the ‘modify-listener’ command.</p><p><em>Are you ready to enhance your AWS Cloud journey? Head over to our </em><a href="http://tysonworks.com/"><em>website</em></a><em> and book a free consultation call.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=22a480b428cb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/tls-1-3-support-for-application-load-balancer-22a480b428cb">TLS 1.3 Support for Application Load Balancer</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[AWS SES vs AWS Pinpoint]]></title>
            <link>https://medium.com/tysonworks/aws-ses-vs-aws-pinpoint-14c4099ef9d6?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/14c4099ef9d6</guid>
            <category><![CDATA[serverless]]></category>
            <category><![CDATA[email-marketing]]></category>
            <category><![CDATA[aws]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Wed, 22 Mar 2023 23:55:47 GMT</pubDate>
            <atom:updated>2023-03-22T23:52:20.996Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/822/1*Gho5k4rSlB3Bhgoy4DNvrA.png" /></figure><p>Amazon Web Services (AWS) offers two services for sending emails: Simple Email Service (SES) and Pinpoint. While both services allow you to send emails, they cater to slightly different use cases and offer different features. Here is a comparison of AWS SES and AWS Pinpoint:</p><p><strong>Purpose and focus:</strong></p><ul><li>AWS SES is primarily focused on providing a simple, cost-effective, and reliable email sending service for both transactional and marketing emails. It is best suited for developers and businesses who need a straightforward way to send emails programmatically from their applications or systems.</li><li>AWS Pinpoint, on the other hand, is a multi-channel marketing communication service that supports email, SMS, push notifications, and in-app messaging. Its primary focus is on targeted and personalized customer engagement, making it a better choice for businesses that require more sophisticated customer communication strategies.</li></ul><p><strong>Features:</strong></p><ul><li>AWS SES provides features such as content filtering, dedicated IP addresses, feedback loops, and integration with AWS services like Lambda and S3. It also offers email templates, sending authorization, and reputation management.</li><li>AWS Pinpoint offers additional features such as customer segmentation, campaign management, A/B testing, analytics, and event tracking. These features make it more suitable for advanced marketing campaigns and customer engagement efforts.</li></ul><p><strong>Pricing:</strong></p><ul><li>AWS SES has a simple pricing model that is mainly based on the number of emails sent and the amount of data transferred. It offers a free tier with 62,000 emails per month for customers using Amazon EC2.</li><li>AWS Pinpoint pricing is slightly more complex, as it depends on the channels used (email, SMS, push notifications) and the number of messages sent. For email, it has a pay-as-you-go model based on the number of emails sent and data transferred. There is a free tier with 62,000 emails per month for customers using Amazon EC2.</li></ul><p><strong>Ease of use:</strong></p><ul><li>AWS SES is developer-focused and requires some programming skills to integrate it into applications, though it provides APIs and SDKs for popular programming languages.</li><li>AWS Pinpoint provides a user-friendly interface and a RESTful API, making it easier for marketing teams to create and manage campaigns without the need for extensive technical knowledge.</li></ul><p>In summary, if your primary need is a reliable and cost-effective email sending service for transactional or marketing emails, AWS SES is the better choice. However, if you require advanced features like customer segmentation, campaign management, and multi-channel support for more sophisticated customer engagement, AWS Pinpoint would be a better fit.</p><p><em>Are you ready to enhance your AWS Cloud journey? Head over to our </em><a href="http://tysonworks.com/"><em>website</em></a><em> and book a free consultation call.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=14c4099ef9d6" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/aws-ses-vs-aws-pinpoint-14c4099ef9d6">AWS SES vs AWS Pinpoint</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[SQS Pitfalls & Best Practices]]></title>
            <link>https://medium.com/tysonworks/sqs-pitfalls-best-practices-e8eb8f099ead?source=rss----1caf405c08f9---4</link>
            <guid isPermaLink="false">https://medium.com/p/e8eb8f099ead</guid>
            <category><![CDATA[serverless]]></category>
            <category><![CDATA[microservices]]></category>
            <category><![CDATA[amazon-web-services]]></category>
            <category><![CDATA[sqs]]></category>
            <category><![CDATA[aws]]></category>
            <dc:creator><![CDATA[Cagdas Ozbey]]></dc:creator>
            <pubDate>Sun, 19 Mar 2023 15:24:37 GMT</pubDate>
            <atom:updated>2023-03-19T15:17:56.223Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/711/1*k6jOhwwVu3Kb9W-BZ7obPg.png" /></figure><p>Amazon Simple Queue Service (<strong>SQS</strong>) is a fully managed, scalable, and reliable message queue service designed to help decouple and scale microservices, distributed systems, and Serverless applications. While it offers various benefits, it’s essential to be aware of the common pitfalls and best practices to make the most out of SQS. In this article I will discuss common SQS mistakes and how to fix them.</p><p><strong>Pitfalls and Best Practices</strong></p><p><strong>Inappropriate use of visibility timeout:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vGy81IUtjV14BCU-1lSHyw.png" /></figure><p><strong>Pitfall</strong>: The visibility timeout is the time during which a message is invisible to other consumers after being consumed. Setting an inadequate visibility timeout can lead to either message duplication or message loss.</p><p><strong>Best Practice</strong>: Determine the appropriate visibility timeout based on the expected processing time of your application. Consider using Amazon CloudWatch to monitor your message processing time and adjust the visibility timeout accordingly.</p><p><strong>Over-relying on the default configuration:</strong></p><p><strong>Pitfall</strong>: Relying solely on default settings may not meet your application’s specific requirements, which can lead to inefficiencies and bottlenecks.</p><p><strong>Best Practice</strong>: Customize the settings, such as message retention period, visibility timeout, and delivery delay, according to your application’s needs. This helps ensure that the queue operates efficiently and effectively.</p><p><strong>Inefficient long polling:</strong></p><p><strong>Pitfall</strong>: Short polling can lead to increased costs and high CPU utilization due to frequent, empty receive requests.</p><p><strong>Best Practice</strong>: Utilize long polling to reduce the number of empty responses and minimize costs. Adjust the ReceiveMessageWaitTimeSeconds parameter to an optimal value based on your application’s requirements.</p><p><strong>Ignoring dead-letter queues:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AiJYtskr4FNlvBf9tY3yCQ.png" /></figure><p><strong>Pitfall</strong>: Continuously retrying to process faulty messages without a proper dead-letter queue (DLQ) can lead to an infinite loop, wasting resources and time.</p><p><strong>Best Practice</strong>: Implement DLQs to handle failed message processing, allowing your application to focus on processing new messages. Monitor the DLQ to identify problematic messages and address any underlying issues.</p><p><strong>Not monitoring and scaling queues:</strong></p><p><strong>Pitfall</strong>: Failing to monitor the health and performance of your SQS queues can lead to bottlenecks and decreased throughput.</p><p><strong>Best Practice:</strong> Use Amazon CloudWatch to monitor your queues and set up alarms for important metrics like ApproximateNumberOfMessagesVisible and ApproximateNumberOfMessagesNotVisible. Use AWS Auto Scaling or AWS Lambda to scale your application based on the monitored metrics.</p><p><strong>Insecure IAM policies:</strong></p><p><strong>Pitfall</strong>: Overly permissive IAM policies can expose your queues to unauthorized access or manipulation.</p><p><strong>Best Practice:</strong> Implement the principle of least privilege and grant only necessary permissions to your IAM roles and policies. Use service-linked roles for AWS services that interact with your SQS queues.</p><p><strong>Not handling message ordering:</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Lc4tx8RYuzUzMu2BsoLRBg.png" /></figure><p><strong>Pitfall:</strong> Standard SQS queues do not guarantee the order of messages, which may lead to unexpected processing results.</p><p><strong>Best Practice:</strong> Use FIFO (First-In-First-Out) queues if your application relies on message ordering. Keep in mind that FIFO queues come with additional limitations, such as a lower throughput compared to standard queues.</p><p>AWS SQS is an essential service for decoupling and scaling distributed systems, but its effective use requires understanding and avoiding common pitfalls. Implementing the best practices outlined in this article can help optimize your SQS implementation and avoid potential issues, enabling your application to run smoothly and efficiently.</p><p><em>Are you ready to enhance your AWS Cloud journey? Head over to our </em><a href="http://tysonworks.com/"><em>website</em></a><em> and book a free consultation call.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e8eb8f099ead" width="1" height="1" alt=""><hr><p><a href="https://medium.com/tysonworks/sqs-pitfalls-best-practices-e8eb8f099ead">SQS Pitfalls &amp; Best Practices</a> was originally published in <a href="https://medium.com/tysonworks">TysonWorks</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>