<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: John Preston</title>
    <description>The latest articles on Forem by John Preston (@johnpreston).</description>
    <link>https://forem.com/johnpreston</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F715442%2Fed830908-5e67-498f-9453-3449107ad66d.png</url>
      <title>Forem: John Preston</title>
      <link>https://forem.com/johnpreston</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/johnpreston"/>
    <language>en</language>
    <item>
      <title>Kafka Connect Watcher - actively monitor your clusters</title>
      <dc:creator>John Preston</dc:creator>
      <pubDate>Fri, 23 Jun 2023 10:59:15 +0000</pubDate>
      <link>https://forem.com/aws-builders/kafka-connect-watcher-actively-monitor-your-clusters-35ib</link>
      <guid>https://forem.com/aws-builders/kafka-connect-watcher-actively-monitor-your-clusters-35ib</guid>
      <description>&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://github.com/JohnPreston/kafka-connect-watcher"&gt;Kafka Connect Watcher&lt;/a&gt; is a service that will actively monitor your connect clusters &amp;amp; its connectors, allow you to define automated actions to take and notify you when problems occur&lt;/p&gt;

&lt;h2&gt;
  
  
  Intro
&lt;/h2&gt;

&lt;p&gt;Running Kafka connect clusters, is not particularly difficult, because it's been very well designed. It is orders of magnitude harder to manage the Kafka cluster(s). Furthermore, in 2023, there are several ways to deploy the workers &amp;amp; connectors: VMs, containers, and even managed services such as MSK Connect.&lt;/p&gt;

&lt;p&gt;I love managed services, so I eventually looked into MSK Connect. However, at the time of writing, MSK Connect is A) very expensive B) is very limited in connection options.&lt;/p&gt;

&lt;p&gt;"But mate, if it's easy to run a cluster, what's the issue?" I hear you ask. Well, let's dive into it, shall we?&lt;/p&gt;

&lt;h2&gt;
  
  
  The why
&lt;/h2&gt;

&lt;p&gt;Let's start with a little bit of background: over the past few years, I have had the responsibility to deploy and maintain several connect clusters, and implemented CICD pipelines for developers to deploy their connectors.&lt;/p&gt;

&lt;p&gt;Running the connect cluster has an infrastructure cost: run a few containers on ECS + Fargate (not going to get into Kafka costs, that's another issue on its own), and really that's where the complications can stop on the cluster. A connect cluster will run without any maintenance required.&lt;/p&gt;

&lt;p&gt;Connectors however, that's a different story. Especially if, like me, to reduce cost and avoid having to re-invent the wheel, you come up with the idea to host a connect cluster and offer "connectors as a service" to your application teams.&lt;/p&gt;

&lt;p&gt;The connect framework on its own offers, to my knowledge, only one way to extract monitoring metrics on the health of the connectors: JVM exporter. If you refer to &lt;a href=""&gt;this blog post&lt;/a&gt; which details how I achieved this, you will see that there is, technically, an easy way to collect data points on the health of your connectors.&lt;/p&gt;

&lt;p&gt;However, this won't give you information such as, why it failed. And unless you go down the rabbit hole of a rather evolved logic, getting this information can be time consuming.&lt;/p&gt;

&lt;p&gt;And sometimes, all a connector will take to work again, is to pause, restart the tasks, and resume it.&lt;/p&gt;

&lt;p&gt;So to solve these things, I decided to write Kafka Connect Watcher&lt;/p&gt;

&lt;h2&gt;
  
  
  The How
&lt;/h2&gt;

&lt;p&gt;Originally, I thought as a savy AWS engineer, I would use my existing CloudWatch metrics, notify a Lambda function, parse the alarm payload, and from there attempt connecting to the connect cluster. But then again, there are lots of information you'd need that the alarm in CloudWatch does not give you.&lt;/p&gt;

&lt;p&gt;Some Kafka vendors, will tie you into their ecosystem tooling (yes, that includes AWS into that one). It's great if you are buying into it, or their supported partners, but the options of actions are limited and up to you to implement.&lt;/p&gt;

&lt;p&gt;Ans so, that was the important thing to me, Kafka Connect is an open source framework, that works wherever you want it to run. So in that spirit, I decided instead to write a simple micro-service, in Python, for anyone to use and contribute to.&lt;/p&gt;

&lt;p&gt;Now, you guessed it already, this service is AWS integrated and as it currently stands, will send notifications to SNS, report metrics to CloudWatch, but there will definitely be room for other integrations (webhooks are very versatile!).&lt;/p&gt;

&lt;h3&gt;
  
  
  How does it work?
&lt;/h3&gt;

&lt;p&gt;Why in Python I hear you ask? Well, I had to write &lt;a href="https://pypi.org/project/kafka-connect-api/"&gt;a python client library for Kafka connect&lt;/a&gt; to enable automation. So I decided to re-use that.&lt;/p&gt;

&lt;p&gt;The service takes a configuration file that details&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the connect clusters to monitor

&lt;ul&gt;
&lt;li&gt;the connectors to monitor, using regular expressions to include/exclude specific connectors&lt;/li&gt;
&lt;li&gt;the actions to perform when a connector is not &lt;code&gt;RUNNING&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;the notifications to send when a connector activity occurs&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;The monitoring to enable and its respective settings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The connect watcher can monitor more than one connect cluster at a time, as to save on deployments if your architecture and configuration allows for it.&lt;/p&gt;

&lt;p&gt;The configuration file uses a JSON schema for both input validation and help with documentation of the required fields, which I hope will help users.&lt;/p&gt;

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

&lt;p&gt;This is a fun project which I enjoy doing and will happily work on implementing new features, so please feel free to open a &lt;a href="https://github.com/JohnPreston/kafka-connect-watcher/issues"&gt;Feature Request&lt;/a&gt; or submit your code changes.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>kafka</category>
      <category>opensource</category>
    </item>
    <item>
      <title>Reduce costs &amp; Improve peak performance with AWS Application Autoscaling scheduled actions</title>
      <dc:creator>John Preston</dc:creator>
      <pubDate>Wed, 21 Jun 2023 09:48:07 +0000</pubDate>
      <link>https://forem.com/aws-builders/reduce-costs-improve-peak-performance-with-aws-application-autoscaling-scheduled-actions-11p6</link>
      <guid>https://forem.com/aws-builders/reduce-costs-improve-peak-performance-with-aws-application-autoscaling-scheduled-actions-11p6</guid>
      <description>&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;Using AWS Application Autoscaling Scheduled Actions, you can prepare your resource compute capacity based on your needs, in combination to normal scaling rules.&lt;/p&gt;

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

&lt;p&gt;The cloud, a mystical place where you can pay for what you need and no more. One of my favorite principle with AWS is that, they give you all the tools, in the form of APIs and Services to be smart about spending your money.&lt;/p&gt;

&lt;p&gt;You have probably seen many times already, customer demos showing how they handle peak time with fleets of machines when they are needed and scale-in to a minimum when usage is at its lowest.&lt;/p&gt;

&lt;p&gt;Over the years, the features to enable customers to do these things have continuously gotten better. And many customers take great advantages of features such as SpotFleet and so on, as the majority of use-cases still require to run EC2 instances.&lt;/p&gt;

&lt;p&gt;But what about what's &lt;strong&gt;not&lt;/strong&gt; running on EC2?&lt;/p&gt;

&lt;h2&gt;
  
  
  Use-case
&lt;/h2&gt;

&lt;p&gt;In the environments I work on, applications are deployed using AWS ECS on top of AWS Fargate. No more EC2 to manage, great, right? What about scaling DynamoDB? ElastiCache? Aurora?&lt;/p&gt;

&lt;p&gt;Many of these (expensive) have a capability/feature to define scaling rules on one (or more) dimensions. For example, with AWS ECS, it's the service &lt;code&gt;DesiredCount&lt;/code&gt; that will change (changes the number of containers). For DynamoDB tables, it's the table Read &amp;amp; Write capacity units, but that can also apply to all of the indexes of the table.&lt;/p&gt;

&lt;p&gt;Each combination of resource and dimension constitute a &lt;strong&gt;Scaling Target&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;How does it all work? It uses a service that is a lot less known: AWS Application Autoscaling. This service is responsible for monitoring Alarms &amp;amp; Metrics, and evaluate the value(s) against different rules you might have set in place.&lt;/p&gt;

&lt;p&gt;Usually, the rules that are created will scale the dimension(s) in/out (or up/down depending on the resource) based on the current usage. Think of your usual CPU average across your EC2 Containers for example. You want the average to be maintained below 70%, and you gave a range of containers to have in the service (min and max).&lt;/p&gt;

&lt;p&gt;And on a daily basis these rules are applied very accurately by the ever watching Application Autoscaling service.&lt;/p&gt;

&lt;p&gt;But what about predictable workloads?&lt;/p&gt;

&lt;h2&gt;
  
  
  Scheduled Actions - the cron scheduler of autoscaling
&lt;/h2&gt;

&lt;p&gt;All the resources dimensions will allow you to define a Min and a Max capacity. For example, min=1,max=10 Write Capacity Unit (WCU) &amp;amp; min=10,max=20 Read Capacity Unit (RCU)for a dynamo db table.&lt;/p&gt;

&lt;p&gt;What scheduled actions allow you to do is to define a rule (your usual cron, a rate, i.e. every 2h, or at a specific point in time, but more on that one later) that will allow you to change &lt;strong&gt;the min/max dimensions of your resource&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Yes, you read that right, it is not actually changing the value of say, the number of ECS containers. But changing the min and maximum range for that Scaling Target.&lt;/p&gt;

&lt;p&gt;Now of course, if you change the minimum (say our RCU min = 15) where the current value might be at 10, then the RCU will now be 15 as the current value has to be in the range.&lt;/p&gt;

&lt;p&gt;It works the other way around of course with the maximum. If you had 700 RCUs, and the scaling rule changes the range to max=100, the current value will get to 100.&lt;/p&gt;

&lt;p&gt;If you have a website (news, shopping etc.) and you have put in place the analytics to understand when your user base connects to your site, you can then create scheduled actions which can predictably set your infrastructure up when you need it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where Application Autoscaling is very smart.
&lt;/h2&gt;

&lt;p&gt;Your resource already has a scaling rule, say based on site usage, say average latency, in milliseconds. The way to maintain latency to a low value is by adding more ECS containers.&lt;/p&gt;

&lt;p&gt;What's going to happen in the real world with scheduled rules?&lt;/p&gt;

&lt;p&gt;Let's take the example of the news website that every day at 6AM starts to see its traffic go up (via the metric above). Say that metric reports 50ms at 5.45. There is a rule that says, above 100ms, double the capacity. That rule works regardless of the number of containers. We have defined we can have between 10 and 100 containers.&lt;/p&gt;

&lt;p&gt;Without scheduled rules, we would have to wait for the latency to go above 100ms to trigger the scaling-out rule. The latency will then go down for a while. We have 20 containers now. Let's assume it goes up again, we now have 40 containers.&lt;/p&gt;

&lt;p&gt;This will go on so long as the latency always goes up. When the latency goes down, we would remove containers, of course.&lt;/p&gt;

&lt;p&gt;But customer satisfaction these days rely on a large part on having quite and responsive websites. So it is worth for the business, and they decide, that at a minimum, there should be 30 containers from 5.45 to 7AM.&lt;/p&gt;

&lt;p&gt;We create a first scheduled action to change min = 30 at 5.45.&lt;br&gt;
Then a second one, restoring the min = 10 at 7AM.&lt;/p&gt;

&lt;p&gt;From 5.45AM to 7AM we are guaranteed that 30 containers are running. However, that doesn't mean that latency won't go up.&lt;/p&gt;

&lt;p&gt;Let's assume it does, at 6.45AM, and so we now get 60 containers running.&lt;/p&gt;

&lt;p&gt;Comes 7AM, the rule &lt;strong&gt;will only change the minimum&lt;/strong&gt;, not the count. So at 7AM, we still have 60 containers, and possibly afterwards more, if the latency continues to increase.&lt;/p&gt;

&lt;p&gt;What this guarantees us is, whenever after 7AM the latency goes down (say below 30ms) we don't need as many containers anymore. Before 7AM, we would have as little as 30 containers, no matter the value of the latency. After 7AM, if the latency allows for it, autoscaling will change the count down to the minimum, eventually 10.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;For many services, the console will offer you to define scaling rules, based on a given input metric. However, there is no UI to configure scheduled rules, which in turn, makes this feature not a very well known one, yet one that is great to take advantage of. Equally, until recently (see &lt;a href="https://dev.to/aws-builders/journey-of-creating-a-new-aws-cloudformation-resource-3483"&gt;my previous post&lt;/a&gt;), there was no way to create these rules via AWS CloudFormation.&lt;/p&gt;

&lt;p&gt;But this is a feature available and you should definitely use it as soon as you can identify patterns that will allow you to save money ("I don't need these over night"), improve performance (repetitive/predictable behaviour), or both!&lt;/p&gt;

&lt;p&gt;Head over to the &lt;a href="https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-scheduled-scaling.html"&gt;API reference&lt;/a&gt; for more information.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>costsaving</category>
      <category>infrastructureascode</category>
    </item>
    <item>
      <title>Journey of creating a new AWS CloudFormation resource</title>
      <dc:creator>John Preston</dc:creator>
      <pubDate>Fri, 09 Jun 2023 06:56:24 +0000</pubDate>
      <link>https://forem.com/aws-builders/journey-of-creating-a-new-aws-cloudformation-resource-3483</link>
      <guid>https://forem.com/aws-builders/journey-of-creating-a-new-aws-cloudformation-resource-3483</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;I created a new CloudFormation resource in the &lt;code&gt;AwsCommunity&lt;/code&gt; organization with Python, created a new &lt;a href="https://github.com/cloudtools/troposphere"&gt;Troposphere&lt;/a&gt; resource for it, and now can use it in production.&lt;/p&gt;

&lt;h2&gt;
  
  
  The why
&lt;/h2&gt;

&lt;p&gt;AWS CloudFormation (CFN) is my favorite Infrastructure as Code (IaC) service to use with AWS. However, some resources might not have a CloudFormation equivalent created by the respective product team, for various possible reasons.&lt;/p&gt;

&lt;p&gt;So then, you have to either use another IaC tool (i.e. Ansible), create a CustomResource (lambda function invoked by CFN), or you could create your own AWS Resource and publish it for everyone else on AWS to use, with the &lt;a href="https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/registry.html"&gt;AWS CloudFormation Registry&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I wanted the ability to create &lt;a href="https://docs.aws.amazon.com/autoscaling/application/userguide/application-auto-scaling-scheduled-scaling.html"&gt;ScheduledActions&lt;/a&gt;, resources managed by the &lt;a href="https://docs.aws.amazon.com/autoscaling/application/userguide/what-is-application-auto-scaling.html"&gt;ApplicationAutoscaling&lt;/a&gt; service, but there wasn't a resource for that. So I created it.&lt;/p&gt;

&lt;h1&gt;
  
  
  The how
&lt;/h1&gt;

&lt;p&gt;The CFN team has created a set of tools and libraries in different languages to allow people to author their own resources.&lt;/p&gt;

&lt;p&gt;I created a few myself before, and published these out of my own AWS Accounts. But this time instead of doing this all on my own, I had the opportunity to contribute to the &lt;a href="https://github.com/aws-cloudformation/community-registry-extensions"&gt;Open Source community driven repository&lt;/a&gt; on GitHub. Great place to see what already existed, and have other people actually help and review my code.&lt;/p&gt;

&lt;p&gt;If you are used the workflows of CloudFormation resources provisioning and the different stages it goes through, this is a very painless process. And to make the whole process even less so painful, you can (and definitely should) run contract testing locally using the &lt;code&gt;sam cli&lt;/code&gt; which will validate that your code passes all the different use-cases it should.&lt;/p&gt;

&lt;h2&gt;
  
  
  Publishing your resource
&lt;/h2&gt;

&lt;p&gt;As mentioned, being a seasoned CloudFormation user, creating a CFN template to publish my resource and create a StackSet to publish it in all AWS regions isn't difficult, but it can be very daunting.&lt;/p&gt;

&lt;p&gt;Joining the AWS Community driven repository will remove that concern away from you as the friendly &amp;amp; helpful team at AWS have automated the whole process for you, and will be publishing your resource as part of the &lt;code&gt;AwsCommunity&lt;/code&gt; "Organization".&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the resource
&lt;/h2&gt;

&lt;p&gt;Once the resource is published on AWS, you need only to activate it in your account. This will require you to create an IAM role to allow the resource to perform actions on your behalf. You can also, optionally, have logging output sent to your AWS Account, which can help with your audits and security posture.&lt;/p&gt;

&lt;p&gt;After you have activated the resource, you can start using it in your CloudFormation templates, like any other resource. The resource will return attributes, so you can use functions like Fn::GetAtt, Fn::Ref or Fn::Sub and so on.&lt;/p&gt;

&lt;p&gt;Here is a snippet of how the resource would be used in a CloudFormation template&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;AWSTemplateFormatVersion&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;2010-09-09"&lt;/span&gt;
&lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Template to test AwsCommunity::ApplicationAutoscaling::ScheduledAction&lt;/span&gt;

&lt;span class="na"&gt;Parameters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ScheduledActionName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;cfn-testing-resource&lt;/span&gt;

  &lt;span class="na"&gt;ServiceNamespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;AllowedValues&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ecs"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elasticmapreduce"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ec2"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;appstream"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dynamodb"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rds"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sagemaker"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;custom-resource"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;comprehend"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lambda"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cassandra"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kafka"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elasticache"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;neptune"&lt;/span&gt;
    &lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="na"&gt;ScalableDimension&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;AllowedValues&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ecs:service:DesiredCount"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;ec2:spot-fleet-request:TargetCapacity"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elasticmapreduce:instancegroup:InstanceCount"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;appstream:fleet:DesiredCapacity"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dynamodb:table:ReadCapacityUnits"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dynamodb:table:WriteCapacityUnits"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dynamodb:index:ReadCapacityUnits"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dynamodb:index:WriteCapacityUnits"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;rds:cluster:ReadReplicaCount"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;sagemaker:variant:DesiredInstanceCount"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;custom-resource:ResourceType:Property"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;comprehend:document-classifier-endpoint:DesiredInferenceUnits"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;comprehend:entity-recognizer-endpoint:DesiredInferenceUnits"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;lambda:function:ProvisionedConcurrency"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cassandra:table:ReadCapacityUnits"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;cassandra:table:WriteCapacityUnits"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;kafka:broker-storage:VolumeSize"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elasticache:replication-group:NodeGroups"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;elasticache:replication-group:Replicas"&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;
      &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;neptune:cluster:ReadReplicaCount"&lt;/span&gt;
    &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;MinCapacity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Number&lt;/span&gt;
    &lt;span class="na"&gt;MinValue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

  &lt;span class="na"&gt;MaxCapacity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Number&lt;/span&gt;
    &lt;span class="na"&gt;MinValue&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;

  &lt;span class="na"&gt;ScheduleExpression&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;the cron(), rate() or at() expression.&lt;/span&gt;

  &lt;span class="na"&gt;EndTime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;When using cron() or rate(), timestamp of when the rule expires.&lt;/span&gt;

  &lt;span class="na"&gt;StartTime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;When using cron() or rate(), timestamp of when the rule starts.&lt;/span&gt;

  &lt;span class="na"&gt;TimeZone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;UTC"&lt;/span&gt;

  &lt;span class="na"&gt;ResourceId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;String&lt;/span&gt;
    &lt;span class="na"&gt;Description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;The Scalable Target ID.&lt;/span&gt;

&lt;span class="na"&gt;Conditions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;NoEndTime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="kt"&gt;!Equals&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="nv"&gt;EndTime&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;none"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;NoStartTime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="kt"&gt;!Equals&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="nv"&gt;StartTime&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;none"&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;

&lt;span class="na"&gt;Resources&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;ScheduledActionForScalableTarget&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;AwsCommunity::ApplicationAutoscaling::ScheduledAction&lt;/span&gt;
    &lt;span class="na"&gt;Properties&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;ScheduledActionName&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;ScheduledActionName&lt;/span&gt;
      &lt;span class="na"&gt;ServiceNamespace&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;ServiceNamespace&lt;/span&gt;
      &lt;span class="na"&gt;ScalableDimension&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;ScalableDimension&lt;/span&gt;
      &lt;span class="na"&gt;Schedule&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;ScheduleExpression&lt;/span&gt;
      &lt;span class="na"&gt;ScalableTargetAction&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;MinCapacity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;MinCapacity&lt;/span&gt;
        &lt;span class="na"&gt;MaxCapacity&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;MaxCapacity&lt;/span&gt;
      &lt;span class="na"&gt;StartTime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!If&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NoStartTime&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;AWS::NoValue&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;StartTime&lt;/span&gt;
      &lt;span class="na"&gt;EndTime&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!If&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NoEndTime&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;AWS::NoValue&lt;/span&gt;
        &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;StartTime&lt;/span&gt;
      &lt;span class="na"&gt;Timezone&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;TimeZone&lt;/span&gt;
      &lt;span class="na"&gt;ResourceId&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="kt"&gt;!Ref&lt;/span&gt; &lt;span class="s"&gt;ResourceId&lt;/span&gt;

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

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a troposphere resource and integration to ECS Compose-X
&lt;/h2&gt;

&lt;p&gt;If you have read my earlier posts or heard me talk with &lt;a href="https://twitter.com/QuinnyPig"&gt;Corey&lt;/a&gt; on &lt;a href="https://www.lastweekinaws.com/podcast/screaming-in-the-cloud/clouddev-for-retail-companies-with-john-mille/"&gt;Screaming in the Cloud&lt;/a&gt;, I am the author of a tool called &lt;a href="https://github.com/compose-x/ecs_composex"&gt;ECS Compose-X&lt;/a&gt;. It's designed to support all the docker compose features, and allow for extensions that make it easier to deploy to AWS.&lt;/p&gt;

&lt;p&gt;Because ECS Compose-X uses &lt;a href="https://github.com/cloudtools/troposphere"&gt;Troposphere&lt;/a&gt;, I was able to create a very light and simple python library(&lt;a href="https://github.com/JohnPreston/troposphere-awscommunity-applicationautoscaling-scheduledaction"&gt;https://github.com/JohnPreston/troposphere-awscommunity-applicationautoscaling-scheduledaction&lt;/a&gt;) to distribute the resource for other Troposphere users to re-use.&lt;/p&gt;

&lt;p&gt;Naturally, as autoscaling was already implemented in the project, this was a natural addition to the &lt;a href="https://docs.compose-x.io/syntax/compose_x/ecs.details/scaling.html"&gt;x-scaling&lt;/a&gt; services feature. This particular resource allows to plan for scaling your ECS service when you need to, and scale back down accordingly.&lt;/p&gt;

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

&lt;p&gt;Creating AWS Resource for CloudFormation might seem like something like you shouldn't have to do, but I see it as a great way to contribute back to the community and to a service I love. And doing so, I hope, will help people who might trying to achieve the same thing.&lt;/p&gt;

&lt;p&gt;But it is not limited to AWS resources: MongoDB, NewRelic, DataDog and other AWS partners have taken advantage of this capability to publish their own resources, allowing AWS customers to rely on AWS CloudFormation to provision their resources.&lt;/p&gt;

&lt;p&gt;I am not a CDK user, but one could also now create a CDK extension to provision that resource in their code.&lt;/p&gt;

&lt;p&gt;Big shoutout to the AWS CloudFormation team (@ericzbeard, @kddejong) &amp;amp; contributors for having helped me out and look forward to seeing more exciting resources and projects coming up!&lt;/p&gt;

</description>
      <category>aws</category>
    </item>
    <item>
      <title>Deploy Conduktor &amp; a MSK Cluster in 3 commands</title>
      <dc:creator>John Preston</dc:creator>
      <pubDate>Wed, 25 Jan 2023 09:42:08 +0000</pubDate>
      <link>https://forem.com/aws-builders/deploy-conduktor-a-msk-cluster-in-3-commands-2fhl</link>
      <guid>https://forem.com/aws-builders/deploy-conduktor-a-msk-cluster-in-3-commands-2fhl</guid>
      <description>&lt;p&gt;Full blog post available at the &lt;a href="https://labs.compose-x.io/kafka/conduktor_msk_demo.html" rel="noopener noreferrer"&gt;Compose-X Labs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Use ECS Compose-X and the new &lt;code&gt;x-msk_cluster&lt;/code&gt; extension to create new cluster/use existing ones, and connect your ECS services to it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Run the demo in 3 commands
&lt;/h3&gt;

&lt;p&gt;Install compose-x &amp;amp; the MSK extension&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; ecs-composex-msk-cluster
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Download the compose file for the demo&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget https://raw.githubusercontent.com/compose-x/ecs_composex-msk_cluster/main/use-cases/conduktor.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Deploy to AWS with ecs-compose-x&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ecs-compose-x init &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
ecs-compose-x up &lt;span class="nt"&gt;-d&lt;/span&gt; templates &lt;span class="nt"&gt;-p&lt;/span&gt; msk-conduktor &lt;span class="nt"&gt;-f&lt;/span&gt; conduktor.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This blog post uses &lt;a href="https://conduktor.io" rel="noopener noreferrer"&gt;Conduktor Platform&lt;/a&gt; as the example service given it has native IAM integration to AWS MSK and allows for testing connectivity &amp;amp; access to the Kafka Cluster.&lt;/p&gt;

&lt;p&gt;You can log into the Conduktor platform using the defined username and passwords (defined in &lt;code&gt;conduktor.yaml&lt;/code&gt;) and connect to &lt;code&gt;http://&amp;lt;ecs_task_public_ip&amp;gt;:8080/&lt;/code&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>security</category>
    </item>
    <item>
      <title>AWS MSK, Confluent Cloud, Aiven. How to chose your managed Kafka service provider?</title>
      <dc:creator>John Preston</dc:creator>
      <pubDate>Tue, 22 Nov 2022 16:28:47 +0000</pubDate>
      <link>https://forem.com/aws-builders/aws-msk-confluent-cloud-aiven-how-to-chose-your-managed-kafka-service-provider-15m0</link>
      <guid>https://forem.com/aws-builders/aws-msk-confluent-cloud-aiven-how-to-chose-your-managed-kafka-service-provider-15m0</guid>
      <description>&lt;h3&gt;
  
  
  TL;DR
&lt;/h3&gt;

&lt;p&gt;This blog post provides an overview of different managed Kafka service providers, including AWS MSK, Confluent Cloud, and Aiven. It compares their features, including cost, operational capabilities, and security, to help you decide which provider is best suited to your needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  A little background.
&lt;/h2&gt;

&lt;p&gt;I am by no means, a Kafka Guru: I haven't contributed to it, and I haven't any sort of certification or affiliation to it. All I am is a "power user" who has been using AWS for years and spent the past few years working with a managed Kafka service provider, giving me now plenty to compare practically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Solutions/Offering comparison
&lt;/h2&gt;

&lt;p&gt;In today's comparison, I am going to use &lt;a href="https://aws.amazon.com/msk/"&gt;AWS MSK&lt;/a&gt; and Confluent Cloud.&lt;/p&gt;

&lt;p&gt;At times, I will also mention &lt;a href="https://aiven.io/"&gt;Aiven&lt;/a&gt;, but my credits ran out before I could explore all its features of it, so I recommend you explore that option yourselves too.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/msk/features/msk-serverless/"&gt;MSK serverless&lt;/a&gt; being new and of limited use-cases, due to its limitations by nature, I am leaving out of this comparison. Equally not considering Confluent "Platform" out of this comparison, given it's not a managed service.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security
&lt;/h2&gt;

&lt;p&gt;This is to me the first and most important criteria. Kafka becoming more and more popular, it is crucial to ensure that the information is secured, and access is restricted.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;AWS MSK&lt;/th&gt;
&lt;th&gt;Confluent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Encryption at rest&lt;/td&gt;
&lt;td&gt;* Default AWS encryption key&lt;br&gt;&lt;br&gt;* Use Customer encryption key (CMK)&lt;/td&gt;
&lt;td&gt;* Can use KMS key, at premium cost&lt;br&gt;&lt;br&gt;* No details on default encryption&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Authentication Methods&lt;/td&gt;
&lt;td&gt;* SASL with PLAIN/SCRAM/IAM&lt;br&gt;&lt;br&gt;* TLS/SSL&lt;/td&gt;
&lt;td&gt;SASL PLAIN&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Audits &amp;amp; Broker logs&lt;/td&gt;
&lt;td&gt;* Full audits with IAM&lt;br&gt;&lt;br&gt;&lt;br&gt;* No audits without IAM, rely on broker logs&lt;br&gt;* Broker logs available, long term persistence&lt;/td&gt;
&lt;td&gt;* Audit logs for Kafka actions. Requires efforts to query&lt;br&gt;&lt;br&gt;* No access to broker logs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Encryption at-rest
&lt;/h3&gt;

&lt;p&gt;AWS MSK, Aiven, and Confluent Cloud all support encryption on the fly and at rest. AWS MSK allows you to use your own AWS KMS Key (or CMK) to encrypt the cluster data at rest, with no restriction in computing size (however, MSK Serverless does not allow you to set that up).&lt;/p&gt;

&lt;p&gt;Aiven does not seem to have an option (at least, not as per their console/wizard) to import your encryption key, regardless of the compute tier you select.&lt;/p&gt;

&lt;p&gt;Confluent offers this option, but only at a premium cost: you must choose the most expensive compute option to support importing an encryption key. At the time of writing this article, that's an option only available to AWS customers.&lt;/p&gt;

&lt;p&gt;But, the permissions that Confluent require you to grant to your CMK, are so wide open that technically they could be using it for anything they would like. When asked to list the services leveraging the key, no answer was provided.&lt;/p&gt;

&lt;h3&gt;
  
  
  Kafka authentication methods
&lt;/h3&gt;

&lt;p&gt;Kafka allows for different authentication methods, each of them having pros &amp;amp; cons, but we won't get into that, but there is lots of material out there that would better explain it in detail than I could.&lt;/p&gt;

&lt;p&gt;In a nutshell, you have the following Apache Kafka native with &lt;a href="https://docs.confluent.io/platform/current/kafka/overview-authentication-methods.html#sasl"&gt;SASL&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PLAIN (username/password)&lt;/li&gt;
&lt;li&gt;SCRAM (username/password)&lt;/li&gt;
&lt;li&gt;OAUTH (OAuth2)&lt;/li&gt;
&lt;li&gt;GSSAPI (Kerberos)&lt;/li&gt;
&lt;li&gt;LDAP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Apache Kafka also supports &lt;a href="https://docs.confluent.io/platform/current/kafka/overview-authentication-methods.html#mtls"&gt;mutual TLS&lt;/a&gt; (or mTLS), which uses certificate-based authentication.&lt;/p&gt;

&lt;p&gt;With regards to authorization (what a given client can/can't do), Apache Kafka supports setting ACLs to grant selective permissions for each user. You have to use tools such as JulieOps or &lt;a href="https://github.com/compose-x/cfn-kafka-admin"&gt;CFN Kafka Admin&lt;/a&gt;, or just the Kafka CLI/Admin API, to set these permissions.&lt;/p&gt;

&lt;p&gt;Confluent Cloud only supports SASL_SSL with PLAIN (username/password) authentication.&lt;br&gt;
Their concept of service accounts makes access management easy across multiple clusters.&lt;br&gt;
But in the past year, the information provided to you via API/CLI &lt;strong&gt;breaks native Apache Kafka&lt;/strong&gt; compatibility: the principal given for ACLs is not a valid one. You must therefore request or query the correct Kafka user principal to get things working.&lt;/p&gt;

&lt;p&gt;Confluent also has its own "Roles"/RBAC driven access control layer, which is an attempt at making user-friendly the management of said ACLs.&lt;/p&gt;

&lt;p&gt;AWS MSK supports more authentication methods than Confluent Cloud. It also implemented an IAM Native SASL mechanism, allowing you to use IAM credentials (Access/Secret Keys &amp;amp; IAM role-based tokens, etc.) to authenticate.&lt;/p&gt;

&lt;p&gt;MSK goes even further, as you can also define ACLs via setting IAM policies that grant the users access to resources (topics, groups, etc.).&lt;br&gt;
You do not need any additional tooling to provide your clients access to Kafka. AWS MSK with IAM provides you with fine-grain auditability as you can log these calls into AWS Cloud Trail.&lt;/p&gt;




&lt;p&gt;Making a note that MSK with IAM is very useful and powerful, but, AWS needs to keep in mind that they must support Apache Kafka native authentication methods in their other services offering.&lt;/p&gt;




&lt;h3&gt;
  
  
  Audits
&lt;/h3&gt;

&lt;p&gt;I haven't been able to evaluate that capacity with Aiven, but yet again I could not find any options in their "UI" provisioning to configure such an option.&lt;/p&gt;

&lt;p&gt;Confluent Cloud has some audits, but these are provided to you in the form of a Kafka topic that they publish Kafka action events for you. You cannot specify where this audit topic is located. Because the logs are in a topic, you have to retrieve/export the data yourself into a data store to intelligently query these events. I have a &lt;a href="https://docs.aws.amazon.com/msk/latest/developerguide/mkc-S3sink-connector-example.html"&gt;S3 Sink&lt;/a&gt; connector which stores the data in S3 and use Athena to query the logs.&lt;br&gt;
Confluent does not provide you with a Schema of the data, so I had to figure that out myself to make intelligent queries possible on fields.&lt;/p&gt;

&lt;p&gt;As mentioned above, MSK provides that audit capability natively when using IAM to authenticate, but for other authentication methods, you will have to rely on the broker logs.&lt;/p&gt;

&lt;p&gt;Speaking of broker logs, Confluent simply does not share these or make them available to you, period. That makes troubleshooting very frustrating. But I also see it as a means for them to do all sorts of operations and changes without you having any visibility over these.&lt;/p&gt;

&lt;p&gt;AWS MSK offers to have Broker logs stored in 3 different destinations: CloudWatch logs, Kinesis Firehose, and S3. All these have pros and cons, but ultimately, the option is there.&lt;/p&gt;




&lt;h2&gt;
  
  
  Operational Capabilities
&lt;/h2&gt;

&lt;p&gt;On security alone, I already have my preference. But let's look at another aspect that these days you simply cannot do without: operability - at least that's what I call it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;AWS MSK&lt;/th&gt;
&lt;th&gt;Confluent&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Kafka Version&lt;/td&gt;
&lt;td&gt;Can be selected by user&lt;/td&gt;
&lt;td&gt;Selected by Confluent, no options.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Infrastructure as Code &amp;amp; API.&lt;/td&gt;
&lt;td&gt;* Full AWS API to CRUD resources&lt;br&gt;* SDK support for multiple languages&lt;/td&gt;
&lt;td&gt;* API without OpenAPI spec&lt;br&gt;* No Confluent maintained SDK&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Monitoring&lt;/td&gt;
&lt;td&gt;* Full monitoring of brokers&lt;br&gt;* Auto-generated clients metrics&lt;br&gt;* Open Monitoring with Prometheus &amp;amp; JMX&lt;/td&gt;
&lt;td&gt;* High level cluster metrics&lt;br&gt;* Heavily rate limited (80 calls/h)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Network availability&lt;/td&gt;
&lt;td&gt;* Private &amp;amp; Public access&lt;/td&gt;
&lt;td&gt;* Private &amp;amp; Public access&lt;br&gt;&lt;br&gt;Limitations on options when using private networking&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Kafka version
&lt;/h3&gt;

&lt;p&gt;With Confluent Cloud, you cannot choose. They pick the version, run it for you, and all you get to know is the compatibility level.&lt;br&gt;
According to their website, they run the same version as what's available in "Confluent Platform".&lt;/p&gt;

&lt;p&gt;With AWS MSK, you get to choose which version you can use. In a way, it makes you responsible for choosing said version and knowing the difference from others. But equally, if you were in the process of migrating from a self-hosted cluster for example, that allows you to ensure that compatibility will be the same for your clients, limiting risks.&lt;/p&gt;

&lt;p&gt;Some versions give you access to additional features, such as "2.8.2_tiered" version which allows you to configure &lt;a href="https://aws.amazon.com/blogs/big-data/retain-more-for-less-with-tiered-storage-for-amazon-msk/"&gt;tiered storage&lt;/a&gt;, for additional cost savings.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure as Code &amp;amp; API.
&lt;/h3&gt;

&lt;p&gt;As most vendors do these days, they have and maintain a Terraform provider for these. AWS MSK also has CloudFormation support (and therefore CDK/&lt;a href="https://github.com/cloudtools/troposphere"&gt;Troposphere&lt;/a&gt; support).&lt;/p&gt;

&lt;p&gt;All three vendors also have a CLI that allows them to provision resources.&lt;/p&gt;

&lt;p&gt;And all three vendors have an API, although AWS has a clear lead in maturity and security for it. And AWS maintains an SDK for nearly every language relevant to this century.&lt;/p&gt;

&lt;p&gt;AWS never creates a service without an API for it. Confluent, however, had an API but only recently got into a "mature" state. They have a Go "library", but that's the extent of it.&lt;/p&gt;

&lt;p&gt;I created a CloudFormation resource for Confluent Cloud, to manage my service accounts that way. I also have a Lambda function that is used to perform Confluent SASL credentials rotation.&lt;br&gt;
Both these things, lead me into creating a &lt;a href="https://github.com/compose-x/confluent-cloud-sdk"&gt;Python SDK&lt;/a&gt; to manage Confluent Cloud, which mostly catered to my immediate needs. But the development of said API was slowed down by the state of the API before it went "GA".&lt;/p&gt;

&lt;h3&gt;
  
  
  Monitoring
&lt;/h3&gt;

&lt;p&gt;We have already gone over logs &amp;amp; audits, so we are going to focus on "metrics".&lt;/p&gt;

&lt;p&gt;Confluent Cloud being very secretive, you cannot access the JVM of the Kafka clusters, sadly, that results in very limited capabilities for monitoring. Confluent Cloud does offer a telemetry API, that you can use to request exporting data in a &lt;a href="https://prometheus.io/"&gt;Prometheus&lt;/a&gt; format, but the API itself is very heavily rate-limited. So you have to make sure you are not going to make too many queries.&lt;br&gt;
This further limits some operational abilities, such as getting a close-to-real-time set of metrics, such as your consumer groups' lag.&lt;/p&gt;

&lt;p&gt;Overall, I found the monitoring capabilities of Confluent Cloud to be too limited, and I had to deploy other services, such as the excellent &lt;a href="https://github.com/seglo/kafka-lag-exporter"&gt;kafka-lag-exporter&lt;/a&gt; to get operationally relevant metrics.&lt;/p&gt;

&lt;p&gt;AWS MSK is getting metrics all around(cluster metrics, consumer metrics, etc.), stored for &lt;strong&gt;free&lt;/strong&gt; in AWS CloudWatch. That allows you to implement alarms using the native tools of the AWS eco-system, and trigger all sorts of actions (autoscaling your services, alarms, and so on).&lt;/p&gt;

&lt;p&gt;It also supports to export of your metrics from the JMX in the Prometheus format, allowing you to scrape the brokers/nodes for additional information or export it to another metrics storage system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cluster evolution &amp;amp; operations
&lt;/h3&gt;

&lt;p&gt;The Confluent Cloud offering gives you a level of granularity on the compute size and storage capacity of the cluster. With their "Dedicated" offering, you can choose the amount of "Confluent Kafka Unit", or CKU, to match your business needs. But there is a catch: if you want a multi-AZ cluster (redundant within a region), you must use at least 2 CKUs. That brings the costs to a significant amount, regardless of whether you do need that capacity or not. Combining that with the security encryption requirement, forces you to use their Dedicated offering.&lt;/p&gt;

&lt;p&gt;As it is a managed service, you do not get to perform any operations such as rebalancing partition leaders and so on. &lt;br&gt;
You have to trust that Confluent will be on top of infrastructure issues to perform these operations reliably for you. Also because it is a managed service, and the computing unit offuscates things for you, you don't get to know how much actual computing the cluster uses. Confluent provides you with an "average load" metric, and that's all.&lt;/p&gt;

&lt;p&gt;You can also not make any settings changes, such as changing the number of in-sync acknowledges, and generally speaking, any default or cluster-level settings.&lt;/p&gt;

&lt;p&gt;With AWS MSK, the number of brokers is driven by the number of subnets you deploy your cluster into the number of brokers must be a factor of that number. I assume that it is to guarantee that you get 1 broker per zone - if you decided to place all your brokers in subnets using the same zone. You can choose the compute size of your brokers, but you must be wary that some features are not supported on all broker sizes.&lt;/p&gt;

&lt;p&gt;You can create MSK Configurations that allow you to define cluster level settings, fine-tune these for your use-cases, and associate these with your MSK Cluster.&lt;/p&gt;

&lt;p&gt;In terms of storage, Confluent Cloud will read an "unlimited" amount of storage, whereas AWS MSK can auto-scale the storage capacity of each broker, from 1GB to 16TB. Both allow adding more brokers, although technically with Confluent, you are changing the number of CKUs.&lt;/p&gt;

&lt;h3&gt;
  
  
  Network availability
&lt;/h3&gt;

&lt;p&gt;Both Confluent &amp;amp; AWS MSK allow having clusters hosted publicly or privately. But not both.&lt;/p&gt;

&lt;p&gt;It is important to note that Confluent Cloud requires extremely large CIDR ranges - at the time of writing - if you are looking at connecting to these via AWS Transit Gateway or VPC Peering, making the legacy integrations of existing large IT networks near impossible.&lt;/p&gt;

&lt;p&gt;This leaves you, for AWS users, with either VPC Private Link or public access. Considering latency and costs (public traffic being 48 times more expensive per GB via a NAT Gateway). Private Link only works one way, so if you were planning to use Confluent-managed connectors, a lot of these are off the table right away.&lt;br&gt;
The way Confluent implemented network ingress on their end also will deny you multipathing: to get from your client to a broker, you must use the endpoint in the same AZ. Any attempt at using an alternative endpoint will be dropped.&lt;/p&gt;




&lt;h2&gt;
  
  
  Ecosystem
&lt;/h2&gt;

&lt;p&gt;Confluent Cloud offers some features only available in Confluent Cloud and only possible among clusters hosted by Confluent cloud (although these are very specific and somewhat limited).&lt;br&gt;
They have KSQL as a Service and some connectors. But these are yet again limited in number and/or security options. Not all options supported in the S3 sink connector for example are available in the Confluent cloud.&lt;/p&gt;

&lt;p&gt;But for the customers out there not on AWS, Confluent &amp;amp; Aiven can make a very compelling offer.&lt;/p&gt;

&lt;p&gt;AWS MSK integrates natively, thanks to its IAM authentication method, to a lot of various other AWS Services. The number of services that you will be able to integrate with MSK is only going to go up.&lt;/p&gt;

&lt;p&gt;If you wanted KSQL-like capabilities, you can use a service such as Kinesis Data Applications, which is a managed Apache Flink cluster and has similar semantics and capabilities as KSQL.&lt;/p&gt;

&lt;p&gt;They both have a managed Schema Registry service which will allow your application teams to store data schemas, which will help tremendously on your data-as-a-product journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  Pricing
&lt;/h2&gt;

&lt;p&gt;With both Confluent &amp;amp; AWS MSK, you have a model of pay-as-you-go which makes it very easy to get started with and scale as your needs do.&lt;/p&gt;

&lt;p&gt;If you get in touch with the Sales team of Confluent, you might be able to get a discount based on volume and length of contractual engagement, classic IT style.&lt;/p&gt;

&lt;p&gt;It is worth noting that having a paid subscription to Confluent Cloud can also get you a License key that will allow you to use some of the Confluent services which are under Confluent licensing. Although often there is a truly open source alternative to the Confluent "purchased" feature, worth considering.&lt;/p&gt;

&lt;p&gt;Technically, you can get a smaller &amp;amp; cheaper MSK cluster with all the bells and whistles for security (encryption, audits, etc.), whereas to get all the options available with Confluent cloud, your costs will be higher by quite a factor.&lt;/p&gt;

&lt;p&gt;Because AWS API &amp;amp; Kafka's API are both so rich, one could imagine implementing further logic such as binding consumers to partitions for which the leader is in the same zone as the broker, reducing cross-az traffic costs. Enabling tiered storage with MSK can also lead to further reduce the storage requirements.&lt;/p&gt;

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

&lt;p&gt;In the Kafka world, competition on getting the best offering is fierce, with each vendor contributing to Kafka in their very own way. On different aspects, I sincerely wish for MSK &amp;amp; Confluent, as well as anyone involved in improving the Kafka ecosystem, to work together, progress KIPs along, and not forget the root of Apache Kafka is with the Open Source community. Implementing features that work within their ecosystem is a fair and logical business decision. And so long as the Kafka users come first, choosing your Kafka vendor should only be a question of features that meet your business requirements.&lt;/p&gt;

&lt;p&gt;As a long-term AWS user, I think that MSK is only going to add more and more features that directly serve customers with their operational capabilities, as their features focus is always on the customer &amp;amp; security, first.&lt;/p&gt;

&lt;p&gt;If you are an AWS user today and are heading towards micro-services architectures, where each application has its own set of permissions, using AWS MSK with IAM authentication is a no brainer and will get you up and running extremely fast.&lt;/p&gt;

&lt;p&gt;In contrast, to do this with Confluent, who has very limited automation around creation of Service Account, SASL credentials, and operational capabilities, you will end up creating a few credentials, likely shared among different applications. To stay secure, this requires a lot of discipline and a very good company-wide strategy &amp;amp; maturity.&lt;/p&gt;

&lt;p&gt;With the creation of MSK Serverless, MSK Connect, and integration with AWS Glue Schema Registry, the wealth of ETL services that AWS has not only makes Kafka a part of it, it empowers it and gets you into a future proof position. There is only so much other vendors will do that will get you further than having a managed hosted Kafka cluster: you will still have to do everything else yourselves.&lt;/p&gt;

&lt;p&gt;So if you were undecided as you started reading, I hope this guide has guided you to a decision.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>kafka</category>
      <category>confluent</category>
    </item>
    <item>
      <title>ECS Anywhere &amp; Traefik Proxy with ECS Compose-X</title>
      <dc:creator>John Preston</dc:creator>
      <pubDate>Mon, 14 Nov 2022 17:58:14 +0000</pubDate>
      <link>https://forem.com/aws-builders/ecs-anywhere-traefik-proxy-with-ecs-compose-x-2k58</link>
      <guid>https://forem.com/aws-builders/ecs-anywhere-traefik-proxy-with-ecs-compose-x-2k58</guid>
      <description>&lt;p&gt;&lt;a href="https://labs.compose-x.io/apps/traefik_ecs_part2.html"&gt;Original post can be found here&lt;/a&gt; along with &lt;a href="https://github.com/compose-x/compose-x-labs/tree/main/traefik/part_2"&gt;the technical resources&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Using &lt;a href="https://docs.compose-x.io"&gt;ECS Compose-X&lt;/a&gt;, deploy &lt;a href="https://github.com/traefik/traefik"&gt;Traefik Proxy&lt;/a&gt; on-premise with &lt;a href="https://aws.amazon.com/ecs/anywhere/"&gt;AWS ECS Anywhere&lt;/a&gt; with only a few changes from running on AWS EC2 or AWS Fargate.&lt;/p&gt;




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

&lt;h3&gt;
  
  
  Our tools for today's lab
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://docs.compose-x.io"&gt;ECS Compose-X&lt;/a&gt; is an open-source project that allows you to use docker-compose services definitions, and render CFN templates (just like with AWS CDK, but without having to write code) to deploy your application service stacks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/traefik/traefik"&gt;Traefik Proxy&lt;/a&gt; is an open source project that will allow you to define ingress rules for your applications and will automatically route traffic to your backend services based on various rules. It is also capable of doing Service Discovery, and today we are going to look at the ECS &amp;amp; ECS Anywhere discovery providers.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://aws.amazon.com/ecs/anywhere/"&gt;AWS ECS Anywhere&lt;/a&gt; is an extension to &lt;a href=""&gt;AWS ECS&lt;/a&gt;, which is a managed container orchestration service, that now allows you to run your workloads in your datacenter/on-premise, and really just, anywhere!&lt;/p&gt;

&lt;h3&gt;
  
  
  The objective
&lt;/h3&gt;

&lt;p&gt;When running on AWS, we have access to services such as AWS Certificates Manager (ACM), AWS Load Balancing (manages ELB, ALB, NLB and more), which can offload a lot of complexity and is very feature rich.&lt;/p&gt;

&lt;p&gt;However, coming to on-premise environments, the costs for hardware that would give us the same functionalities (think F5 load-balancers, your expensive licensed VXLAN resources), are only affordable by a few. And typically for a "home-labber" such as myself, way out of my budget.&lt;/p&gt;

&lt;p&gt;So I needed an alternative solution that would allow me to use AWS ECS services, route traffic to my services based on service discovery. It should also be able to deal with managing SSL certificates for me. And finally, I must be able to deal with non-persistent storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Welcome Traefik Proxy
&lt;/h2&gt;

&lt;p&gt;For years, I have been an NGINX and/or HA Proxy user. They are very lightweight, very popular, great documentation and community support in general.&lt;/p&gt;

&lt;p&gt;But, they aren't quite capable of doing Service discovery all by themselves.&lt;/p&gt;

&lt;p&gt;I came across Traefik Proxy, and a whole new world of capabilities was now wide open. With service discovery providers, Traefik can scrape your services and based on labels/tags, identify instructions to perform. And AWS ECS is one of such providers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Just a tiny little problem
&lt;/h3&gt;

&lt;p&gt;When I first tried Traefik a little over a year ago for ECS Anywhere, it wouldn't work. That's because until then, Traefik only considered using Fargate or EC2 instances to run the containers. There was no implementation of discovering AWS ECS Anywhere on-prem instances.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;This has been since addressed, and one can specifically enable the ECS Anywhere discovery in Traefik.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Traefik and Let's Encrypt SSL management
&lt;/h3&gt;

&lt;p&gt;When you define routers with Let's Encrypt, you can define whether or not you want Traefik to provision certificates.&lt;/p&gt;

&lt;p&gt;With Traefik, you can automatically get new certificates for yourself when you need them. There are different validation methods, my chosen one being with DNS validation.&lt;/p&gt;

&lt;p&gt;For validation, given my DNS domain is managed in Route53, I simply indicate to Traefik to use that DNS method / zone for validation.&lt;/p&gt;

&lt;h4&gt;
  
  
  Why DNS validation works for me?
&lt;/h4&gt;

&lt;p&gt;If I have internally exposed services (not available on the internet), but I still want to have SSL certificates provisioned for them, DNS is the only option for that. It will generally come down to your preference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Prerequisites
&lt;/h3&gt;

&lt;p&gt;You will need&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An AWS Account&lt;/li&gt;
&lt;li&gt;Configured a local user with IAM permissions to deploy resources&lt;/li&gt;
&lt;li&gt;Have an existing ECS Cluster with a registered ECS Instance that runs on-premise.&lt;/li&gt;
&lt;li&gt;Installed ECS Compose-X (version 0.22 and above). See below.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Compose-X install
&lt;/h4&gt;

&lt;p&gt;You can install it locally for your user&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;pip &lt;span class="nt"&gt;-U&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
pip &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--user&lt;/span&gt; ecs-composex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or install it in a python virtual/isolated enviroment&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python3 &lt;span class="nt"&gt;-m&lt;/span&gt; venv compose-x
&lt;span class="nb"&gt;source &lt;/span&gt;compose-x/bin/activate
pip &lt;span class="nb"&gt;install &lt;/span&gt;pip &lt;span class="nt"&gt;-U&lt;/span&gt;
pip &lt;span class="nb"&gt;install &lt;/span&gt;ecs-composex
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once you have installed it, run the following command that will ensure we have the necessary settings and resources to get started.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ecs-compose-x init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Clone the labs repo
&lt;/h3&gt;

&lt;p&gt;Clone the repo, and head to the configuration files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/compose-x/compose-x-labs.git
&lt;span class="nb"&gt;cd &lt;/span&gt;traefik/part_2/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the current files, you will have to edit to change the domain name in-use.&lt;/p&gt;

&lt;p&gt;You can either edit it with your preferred IDE, or simply run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s1"&gt;'s/bdd-testing.compose-x.io/&amp;lt;your_domain_name.tld&amp;gt;/g'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If your domain is not maintained in AWS Route53, you will need to head over to &lt;a href="https://doc.traefik.io/traefik/https/acme/"&gt;the Let's Encrypt ACME documentation&lt;/a&gt; in order to use a different validation method.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting ready to deploy
&lt;/h3&gt;

&lt;p&gt;The deployment to ECS Anywhere is only a command away&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CLUSTER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;MyExistingECSCLuster ecs-compose-x up &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; traefik-anywhere &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; templates &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yaml &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-f&lt;/span&gt; ecs-anywhere.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compose-X will render all of the CFN templates and store them in your local folder (under &lt;code&gt;templates&lt;/code&gt;), as well as in AWS S3. It is required to be in S3 for CFN nested stacks.&lt;/p&gt;

&lt;p&gt;After a few minutes, you should have running on your ECS Anywhere instances, Traefik.&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding SSL Certificates backup.
&lt;/h3&gt;

&lt;p&gt;Let's Encrypt "production" endpoint, has a rate limit in place for the number of certificates requested per domain.&lt;/p&gt;

&lt;p&gt;So if you are new to this, we recommend to &lt;a href="https://github.com/compose-x/compose-x-labs/blob/main/traefik/part_2/ecs-anywhere.yaml#L36-L37"&gt;use the Let's Encrypt staging environment&lt;/a&gt;, which will allow not to hit the rate limit.&lt;/p&gt;

&lt;p&gt;Sadly, it seems that the persistent storage of the file that holds the SSL certificates requested by Traefik to Let's Encrypt is not a feature that we might see coming in any time soon.&lt;/p&gt;

&lt;p&gt;So instead, we are going to implement the backup-and restore ourselves.&lt;/p&gt;

&lt;p&gt;Using 2 sidecars, one to restore the files prior to traefik starting, and another constantly watching for a change to automatically backup the file to AWS S3, we will ensure that we don't request certificates we already did provision before.&lt;/p&gt;

&lt;p&gt;To deploy the solution, we added the &lt;a href="https://github.com/compose-x/compose-x-labs/blob/main/traefik/part_2/backup.yaml"&gt;backup.yaml&lt;/a&gt; file to our deployment command.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: the S3 bucket already exists for us, and if you want to use an existing one, you will need to adopt the &lt;code&gt;Lookup&lt;/code&gt; &lt;a href="https://github.com/compose-x/compose-x-labs/blob/main/traefik/part_2/backup.yaml#L77-L79"&gt;Tags&lt;/a&gt; in order to use your own/the right bucket.&lt;/p&gt;

&lt;p&gt;So now, we deploy our updated definition to AWS&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;CLUSTER_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;MyExistingECSCLuster ecs-compose-x up &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-n&lt;/span&gt; traefik-anywhere &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-d&lt;/span&gt; templates &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-f&lt;/span&gt; docker-compose.yaml &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="nt"&gt;-f&lt;/span&gt; ecs-anywhere.yaml
&lt;span class="nt"&gt;-f&lt;/span&gt; backup.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Hint&lt;/strong&gt;: the order of the files &lt;strong&gt;does matter&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;And that's it! You now have successfully deployed Traefik to ECS Anywhere, with automated backup &amp;amp; restore for your certificates.&lt;/p&gt;

&lt;p&gt;To add additional services you wish Traefik to route to, simply deploy them with the appropriate labels, just like we used in the demo for the &lt;a href="https://github.com/compose-x/compose-x-labs/blob/main/traefik/part_2/ecs-anywhere.yaml#L140-L154"&gt;whoami service&lt;/a&gt;&lt;/p&gt;

</description>
      <category>aws</category>
      <category>traefik</category>
      <category>ecs</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>AWS ECS Anywhere - Is it worth it?</title>
      <dc:creator>John Preston</dc:creator>
      <pubDate>Tue, 25 Oct 2022 13:02:55 +0000</pubDate>
      <link>https://forem.com/aws-builders/aws-ecs-anywhere-is-it-worth-it-93k</link>
      <guid>https://forem.com/aws-builders/aws-ecs-anywhere-is-it-worth-it-93k</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;AWS ECS Anywhere is a very powerful extension of AWS ECS, which makes a very competitive argument in many aspects for hybrid-cloud, and even multi-cloud. It is very cost competitive to other alternatives such as Virtual Private Servers (VPS) and alternative AWS services.&lt;/p&gt;




&lt;p&gt;Recently I spent a lot of time working on ECS Compose-X, &lt;a href="https://github.com/traefik/traefik"&gt;Traefik&lt;/a&gt;, and &lt;a href="https://aws.amazon.com/ecs/anywhere/"&gt;AWS ECS Anywhere&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Whilst most of the work I have been doing with these, has been in the context of a Home Lab, a lot of considerations for it are just as true for large production ready deployments in an enterprise context.&lt;/p&gt;

&lt;p&gt;Whilst working on all this, a thought came to mind: what about the costs? Is it worth it to run ECS Anywhere?&lt;/p&gt;

&lt;p&gt;So here are some thoughts and cost considerations to try to come to a decision on this.&lt;/p&gt;




&lt;h2&gt;
  
  
  Alternatives
&lt;/h2&gt;

&lt;p&gt;When one looks at container orchestration on-premise, there are a lot of different resources, and software to achieve that. &lt;strong&gt;So why would one consider using AWS ECS Anywhere over these?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Many blog posts about using Kubernetes (K8s) on-premise, and running a cluster yourself can be very cheap, or very expensive, depending on the hardware you use to run it and operational costs knowledge &amp;amp; expertise required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Let's say to stay in the realm of managed services for now.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If we were wanted to have K8s, AWS EKS Anywhere is an option. But, the cost for it is very high, and that's just for the control plane. Add on top of that, the upfront costs for the hardware and infrastructure to run it, and so on. Certainly worth considering for big corporations, but for someone to play around with in their Home Lab, it is something most of us can't afford.&lt;/p&gt;

&lt;h3&gt;
  
  
  ECS Anywhere pricing
&lt;/h3&gt;

&lt;p&gt;Looking at the costs of ECS Anywhere: $0.01025 per hour per instance.&lt;/p&gt;

&lt;p&gt;This means, $7.626 a month for each on-premise registered instance running.&lt;/p&gt;

&lt;p&gt;I say running, because if your ECS instance is not marked as such, it does not cost you anything. This can be very handy if you can automate turning on/off VMs / Hardware at home, when you need more compute for processing. In addition to my Pi4, I have an old Intel NUC, which I only turn on to test x86 based applications which don't have ARM support. So I barely pay anything for it.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;On the plus side, neither ECS nor EKS Anywhere has a cost based on the number of containers you run, or the hardware running these (i.e. licensing per vCPU/RAM).&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;So with my humble Raspberry Pi 4 and 4GB of RAM, I can very comfortably run several services before getting into&lt;br&gt;
hardware limits (it depends, of course, on the workload).&lt;/p&gt;

&lt;p&gt;Using CPU/RAM limits and reservations, one can ensure that applications get priority and have enough capacity to run, and we recommend that you set these wherever possible.&lt;/p&gt;

&lt;p&gt;If you want to have enhanced features and monitoring of the on-premise instance as well, you can enable that with SSM, at an additional cost, &lt;strong&gt;but that is optional&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Let's compare it also with VPS services. Of course, my Piv4 does not match exactly either the VM or Container profiles.&lt;/p&gt;

&lt;p&gt;So let's take a look at the closest options with AWS LightSail (not accounting for local storage or bandwidth, that's up to the infra/setup, more on that later):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;VM, 2vCPUs, 4GB of RAM -&amp;gt; $20 a month&lt;/li&gt;
&lt;li&gt;VM, 4vCPUs, 16BG of SAM -&amp;gt; $80 a month&lt;/li&gt;
&lt;li&gt;Containers, 2vCPUs, 4GB of RAM -&amp;gt; $80 a month&lt;/li&gt;
&lt;li&gt;Containers, 4vCPUs, 8GB of RAM -&amp;gt; $160 a month.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With digital Ocean Droplets, the closest in CPU RAM would be $24 or $48.00 a month. Again this is without considering the bandwidth and local storage. Other vendors have prices that vary whether you pay annually or monthly, so the comparison sheets start to become quite a bit of a mess.&lt;/p&gt;

&lt;p&gt;Now, for fairness, let's add the electricity costs for the Pi v4: 5V*3A = 15W =&amp;gt; $4 to $5 a month (varies based on your electricity costs).&lt;/p&gt;

&lt;p&gt;If you also add the costs of electricity for your router/switch, your ISP subscription and so on, it can accumulate to an expensive bill altogether.&lt;/p&gt;

&lt;p&gt;But, you are not planning on not watching Netflix? Browsing? Working from home, are you?&lt;br&gt;
So in a way, these additional costs are "what they are" and you would pay for them whether you run ECS Anywhere or not, &lt;em&gt;in the context of a Home Lab&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In the context of your data center however, with the cost of rack rental, the power supply, and connectivity are usually already factored in as well when you bought that racking space.&lt;/p&gt;

&lt;p&gt;So I am only going to factor in the costs of the Pi at its peak power usage. In total, estimate about $14 a month, for an unlimited number  of services to run (within the boundaries of available capacity). And you get all of the IAM benefits, from a security point of view.&lt;/p&gt;

&lt;p&gt;It is important to note, for fairness, that I am fortunate to have a 1GB fiber symmetrical connection, with unlimited data. So bandwidth is not a problem for me. But if you needed better bandwidth, and maybe features like multiple IP addresses, you might have to go for a VPS provider.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;So all together, ECS &amp;amp; ECS Anywhere make for a very appealing option when it comes to in-cloud and on-premise container orchestrator &amp;amp; managed service. It comes with a rich set of capabilities, from logging to monitoring, scalability, and observability.&lt;/p&gt;

&lt;p&gt;Even more so important, from an operational point of view: the configuration of ECS Task definitions and Services is nearly identical: only a few settings change.&lt;/p&gt;

&lt;p&gt;Some features, such as Service Discovery using &lt;a href="https://aws.amazon.com/cloud-map/"&gt;AWS CloudMap&lt;/a&gt;, however, are not available. And this is where we rely on AWS' APIs for discovery, in the way Traefik and many other services alike, do.&lt;/p&gt;

&lt;p&gt;I used to run some small services in LightSail, and although it made some management aspects easier, I am delighted to run services with ECS Anywhere for a lower cost. And it forces me to think about running applications in a not-as-perfect environment (hardware-wise) than AWS.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>costanalysis</category>
      <category>awsecs</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
