<?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: Austin</title>
    <description>The latest articles on Forem by Austin (@amcdnl).</description>
    <link>https://forem.com/amcdnl</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%2F262808%2F91220291-b4ae-4471-ad98-6af9a2c712b5.jpg</url>
      <title>Forem: Austin</title>
      <link>https://forem.com/amcdnl</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/amcdnl"/>
    <language>en</language>
    <item>
      <title>Build It, Block It, Visualize It: Introducing Unify Viz Blocks 2.0</title>
      <dc:creator>Austin</dc:creator>
      <pubDate>Tue, 09 Apr 2024 09:50:25 +0000</pubDate>
      <link>https://forem.com/amcdnl/build-it-block-it-visualize-it-introducing-unify-viz-blocks-20-419e</link>
      <guid>https://forem.com/amcdnl/build-it-block-it-visualize-it-introducing-unify-viz-blocks-20-419e</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxk22c8prbdz1jelnm5t.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuxk22c8prbdz1jelnm5t.jpg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hello Everyone! 🌟 Welcome to Unify Viz Blocks 2.0!&lt;/p&gt;

&lt;p&gt;We're excited to share some big news with you. Our team has been working hard, and it’s finally here: Unify Viz Blocks 2.0! With this update, we're adding more than 500 new blocks to our already robust library, empowering you to create even more stunning charts, graphs, and dashboards directly within Unify.&lt;/p&gt;

&lt;h2&gt;
  
  
  Designed for Deeper Insights and Engagement
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bqi6gw9i7jru8wmedmb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7bqi6gw9i7jru8wmedmb.png" alt="Image description" width="800" height="555"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Each block has been meticulously crafted to not only enhance the visual appeal of your data presentations but also to make data analysis more intuitive and insightful. From dynamic area charts and detailed bar graphs to insightful funnel charts, comprehensive heatmap blocks, and revealing scatter plots, Unify Viz Blocks 2.0 offers a diverse range of options to suit your every need.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;84 Area Chart Blocks: Visualize data trends over time with new levels of depth and clarity.&lt;/li&gt;
&lt;li&gt;196 Bar Chart Blocks: Compare different data sets with ease, thanks to enhanced detail and customization options.&lt;/li&gt;
&lt;li&gt;32 Funnel Chart Blocks: Track conversion rates and process efficiency with precision, identifying opportunities for improvement.&lt;/li&gt;
&lt;li&gt;170 Heatmap Blocks: Discover patterns and correlations within your data, making complex data sets understandable at a glance.&lt;/li&gt;
&lt;li&gt;40 Scatter Plot Blocks: Explore the relationships between variables, unlocking new insights with sophisticated analytical capabilities.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Empower Your Data Analysis Across Any Field
&lt;/h2&gt;

&lt;p&gt;Unify Viz Blocks 2.0 is designed to be a game-changer across a variety of fields, whether you're in cybersecurity, finance, marketing, or any other domain where data plays a crucial role. Visualize data in ways that are not only more engaging but also provide clearer insights, helping you to make informed decisions based on complex data sets.&lt;/p&gt;

&lt;h2&gt;
  
  
  Simplifying Complexity
&lt;/h2&gt;

&lt;p&gt;We understand the challenges of working with complex data, which is why we’ve focused on creating a user-friendly experience that doesn’t compromise on power or flexibility. Whether you’re a data scientist, a business analyst, or someone who just loves to explore data, Unify Viz Blocks 2.0 is designed to cater to your needs, simplifying the complex and bringing your data to life.&lt;/p&gt;

&lt;h2&gt;
  
  
  Ready to Transform Your Data?
&lt;/h2&gt;

&lt;p&gt;Dive into the vast possibilities offered by Unify Viz Blocks 2.0 and start exploring your data in new, more meaningful ways. With over 250+ blocks at your fingertips, your ability to analyze, understand, and present data is about to reach new heights.&lt;/p&gt;

&lt;p&gt;Join us in embracing the future of data visualization. Welcome to Unify Viz Blocks 2.0. &lt;a href="https://unifyviz.com"&gt;Learn more →&lt;/a&gt;&lt;/p&gt;

</description>
      <category>figma</category>
      <category>react</category>
      <category>chart</category>
      <category>dataviz</category>
    </item>
    <item>
      <title>Unify Viz - 300+ Premium charts for Figma and React</title>
      <dc:creator>Austin</dc:creator>
      <pubDate>Tue, 26 Dec 2023 13:51:10 +0000</pubDate>
      <link>https://forem.com/amcdnl/unify-viz-300-premium-charts-for-figma-and-react-5a6k</link>
      <guid>https://forem.com/amcdnl/unify-viz-300-premium-charts-for-figma-and-react-5a6k</guid>
      <description>&lt;p&gt;We are thrilled to announce the launch of Unify Viz. Prepare to revolutionize the way you analyze data with this feature-rich library of 300+ charts for Figma and React.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Unify Viz?
&lt;/h2&gt;

&lt;p&gt;Unify Viz is a comprehensive set of Figma components and React code assets that empower users to effortlessly design and develop captivating data visualizations. It offers a vast selection of more than 300 chart combinations, ensuring that you will consistently discover the ideal graphic representation for your data. Additionally, Unify Viz is continuously updated with new chart options, providing you with an ever-expanding library of possibilities to enhance your data storytelling.&lt;/p&gt;

&lt;h2&gt;
  
  
  What sets Unify Viz apart?
&lt;/h2&gt;

&lt;p&gt;While there are numerous Figma and React component libraries available, few offer both design assets and matching code. This often creates friction during the handoff process, as charts can be challenging to design and build with all their intricacies. With Unify Viz, your designer can simply copy and paste the component, adjust labels and colors, and share the code link with the developer. It's as simple as that! Every chart includes a corresponding Figma design and code sample for easy implementation.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's included in Unify Viz?
&lt;/h2&gt;

&lt;p&gt;We offer a comprehensive collection of 21 chart categories, each catering to different data visualization needs. These include an Area Chart, Line Chart, Bar Chart, Pie Chart, Donut Chart, Sankey Plot, Bubble Plot, Funnel Chart, Heatmap, Gauges, Map, Meter, Radial, Scatter, Sparklines, Treemap, Venn Diagram and more!&lt;/p&gt;

&lt;p&gt;In addition to the extensive range of Base Charts, we also provide an impressive selection of 300+ Variations of these charts. This ensures that you have ample options to customize and tailor your visualizations to suit your specific requirements.&lt;/p&gt;

&lt;p&gt;To enhance your design workflow, our package includes ready-to-use Figma Components. These components are designed to seamlessly integrate with your Figma projects and enable quick and efficient chart creation.&lt;/p&gt;

&lt;p&gt;For developers using React, we offer a handy set of React Component Snippets. These snippets simplify the process of integrating our charts into your React applications, saving you valuable time and effort.&lt;/p&gt;

&lt;p&gt;As part of our commitment to continuously enhance our offering, we provide free monthly updates. These updates include new charts, feature improvements, and bug fixes, ensuring that you always have access to the latest and greatest in data visualization.&lt;/p&gt;

&lt;p&gt;For those seeking additional assistance, we offer optional support and consulting services. Our team of experts is available to provide guidance, answer questions, and help you maximize the value of our charts in your projects.&lt;br&gt;
To cater to a wide range of app styles and preferences, our charts are available in both Light and Dark Color Schemes. Each scheme offers a diverse palette of colors, allowing you to find the perfect match for your app's visual identity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why did we create Unify Viz?
&lt;/h2&gt;

&lt;p&gt;At &lt;a href="https://goodcode.us"&gt;Good Code&lt;/a&gt;, we work with customers of all sizes and have found that while there are many resources available, they often require additional assembly. This can be frustrating for developers who are just starting out or don't have time to build complex charts from scratch. We wanted to simplify the process by making it as easy as copy and paste. That's why we call it Unify – because we are unifying the design and development of data visualizations!&lt;/p&gt;

&lt;h2&gt;
  
  
  Previews
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2h2s3hfxkyiolaw1gw1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs2h2s3hfxkyiolaw1gw1.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fby4u5htxa6xntm3dwj9h.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fby4u5htxa6xntm3dwj9h.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffv83kpotks0vnm1hcbbg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffv83kpotks0vnm1hcbbg.png" alt="Image description" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How can you get Unify Viz?
&lt;/h2&gt;

&lt;p&gt;We launched the product today at &lt;a href="https://store.goodcode.us"&gt;https://store.goodcode.us&lt;/a&gt;. We hope you enjoy the package, and stay tuned for more amazing charts in future updates!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>figma</category>
      <category>d3</category>
      <category>charts</category>
    </item>
    <item>
      <title>The cyber-security impacts of an AWS Outage</title>
      <dc:creator>Austin</dc:creator>
      <pubDate>Wed, 08 Dec 2021 13:42:12 +0000</pubDate>
      <link>https://forem.com/amcdnl/the-cyber-security-impacts-of-aws-outages-46lg</link>
      <guid>https://forem.com/amcdnl/the-cyber-security-impacts-of-aws-outages-46lg</guid>
      <description>&lt;p&gt;On the morning of December 7th, AWS had a major outage that effected a large portion of the us-east regions. The outage affected everything from the AWS Console to Disney+, Netflix and even home security devices such as Ring and Wyze.&lt;/p&gt;

&lt;p&gt;The outage lasted a good duration of the afternoon where for a good portion of the time AWS service health dashboard didn't even report any issues per AWS: "This issue is also affecting some of our monitoring and incident response tooling."&lt;/p&gt;

&lt;p&gt;For most people, it was an inconvenience but its situations like this where not only cyber criminals thrive but even average criminals can monopolize on this too. &lt;/p&gt;

&lt;p&gt;Let's imagine you use a Ring camera ( without the security subscription ) to monitor your home while you're at work. Around lunch time, it was widely known that there was a major outage and even broadcasted on local TV news. Ordinary criminals become aware of the situation and act targeting anyone with that nice Ring sign in their front-yard.&lt;/p&gt;

&lt;p&gt;Most products like Ring or Wyze have mandatory disclosures about outages like this; ironically enough I received one from Wyze which I have only a smart plug but never received one from Ring which I have setup around my entire home.&lt;/p&gt;

&lt;p&gt;Now let's imagine your company has EC2 machines setup for monitoring or SAAS services to scan for phishing attempts or even security response automation. Sophisticated attackers have systems setup to monitor critical infrastructure like AWS for outages and then start attacks. If an attacker see that a system is down, they will launch a series of attacks to try and bypass the systems that might be down. If these systems are down then it creates opportunities for attacks to slide under the radar and likely never even be noticed until it's too late.&lt;/p&gt;

&lt;p&gt;After everyone's PagerDuty alarms stop and the dust settles, situations like this can be good opportunities to remind organizations that putting all your eggs in one basket ( or us-east-1 in this case ) should be treated as a security vulnerability not just 'bad devops'.&lt;/p&gt;

&lt;p&gt;These situations also highlight our reliance on infrastructure that most of us highlight as 'too big to fail' but it's better to be prepared for the worst than not.&lt;/p&gt;

</description>
      <category>cybersecurity</category>
      <category>aws</category>
      <category>devops</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Mergers &amp; Acquisitions - For the JavaScript Developer</title>
      <dc:creator>Austin</dc:creator>
      <pubDate>Fri, 10 Sep 2021 12:38:32 +0000</pubDate>
      <link>https://forem.com/amcdnl/mergers-acquisitions-for-the-javascript-developer-1hc0</link>
      <guid>https://forem.com/amcdnl/mergers-acquisitions-for-the-javascript-developer-1hc0</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Technology changes at lightning speed and for larger businesses to grow their core business but stay innovative and capture new markets, it's almost always easier to acquire a smaller organization and roll them into their broader product offering than actually build something. One thing that I've learned over the years is that for a business, the time to market or opportunity loss cost largely outweighs actual dollars. &lt;/p&gt;

&lt;p&gt;Over my career, I've been part of 4 acquisitions, including my own company ( &lt;a href="https://crft.app"&gt;https://crft.app&lt;/a&gt; ) last year. If you've ever been part of an acquisition after the champaign popping is over, it's right to how can we integrate these applications so they feel like one offering. This is always messy because it's almost never the case that both companies have the same technology, languages, tools that are the same. The first acquisition I was apart of our technology stack was heavy C# / .NET and the acquiring company was Java. At the time, there wasn't any frontend tooling like we have today and putting ASPX pages in JSP pages was pretty much a iframe and then a rewrite. &lt;/p&gt;

&lt;p&gt;During the acquisition of my company last year, the dreams and aspirations of React finally were realized to me. In this article, I want to take you through how we took two completely different applications written in React and made one unified page ( no iframes required ).&lt;/p&gt;

&lt;h2&gt;
  
  
  The Theory
&lt;/h2&gt;

&lt;p&gt;A React application is just a set of components pieced together to build a larger application. If you have two different applications written in React, theoretically you should be able to treat one of them like any other component you might install from NPM. &lt;/p&gt;

&lt;p&gt;In our particular case, we wanted to create two experiences; one experience that was embedded in the larger application and another that was a stand alone version. This would allow us to create a unified experience for the existing customers but also serve two distinct personas ( since one buyer might not want the other product and vice versus ). This increases code and deployment complexity but it can also help keep some things isolated which makes merging easier.&lt;/p&gt;

&lt;p&gt;I hypothesized that we could keep the same code bases and products and then build/package one of the apps and just have on consume the other.&lt;/p&gt;

&lt;h2&gt;
  
  
  Audit the tech
&lt;/h2&gt;

&lt;p&gt;The first thing you need to do is audit the overlap and figure out what 'container' level items are shared and what can't be. This list usually looks something like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Authentication ( Custom / Okta / Auth0 / etc )&lt;/li&gt;
&lt;li&gt;Store ( Redux / Recoil / etc )&lt;/li&gt;
&lt;li&gt;Component Libraries ( Material / Custom / etc )&lt;/li&gt;
&lt;li&gt;Style Systems ( SASS / PostCSS / CSS-IN-JS )&lt;/li&gt;
&lt;li&gt;Test Systems ( Cypress / Jest / etc )&lt;/li&gt;
&lt;li&gt;Build Systems ( Webpack / CRA / etc )&lt;/li&gt;
&lt;li&gt;Programming Languages ( JavaScript / TypeScript / CoffeeScript &amp;lt; sorry if thats you )&lt;/li&gt;
&lt;li&gt;Backend APIs ( Rest / GraphQL / SOAP &amp;lt; sorry if thats you )&lt;/li&gt;
&lt;li&gt;Backend Cloud Providers ( GCP / AWS / Azure / etc )&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once we have an understanding of the tech, we can start to tease out the overlap and put together a plan.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where do things overlap?
&lt;/h2&gt;

&lt;p&gt;The only thing that overlapped in the frontends was the authentication providers. Luckily most organizations are not writing their own auth providers anymore and so if you have 2 organizations both using let's say Okta, you can actually share the same authentication token minters and its like magic, no seriously I couldn't believe it just worked ( &amp;lt; This might be a future article ).&lt;/p&gt;

&lt;p&gt;To make things even more fun, one application is JavaScript + custom webpack and the other is TypeScript CRA. Now I know what your about to say, TypeScript is just JavaScript but believe me converting a large mature code base from JavaScript to TypeScript is quite a lift, mainly because you find so many things that might be 3 years old that the types don't match up and you have to go in circles if this is even used anymore and how to fix it. The last time I did this migration on a mature large code base, it took us about 3 weeks of 3 full time developers on it. I won't argue that knocking out this tech debt and making the code bases the same language has quite a bit of merit but the business wants the product out yesterday and a code migration is just scary for most PMs.&lt;/p&gt;

&lt;p&gt;Given the language differences, a copy / paste into the same directory was not really an option. Going back to my original theory, since both systems are React which is just a bunch of components, why can't we build and bundle one of the applications and publish it to NPM just like I do on my open-source projects ( shameless plug: &lt;a href="https://github.com/reaviz"&gt;https://github.com/reaviz&lt;/a&gt; ).&lt;/p&gt;

&lt;h2&gt;
  
  
  Rollup to the rescue
&lt;/h2&gt;

&lt;p&gt;Webpack is not really designed to package things for consuming them externally; its possible but not ideal. Rollup on the other hand is perfect for this, it can help you include / exclude / compile to different targets in a ( somewhat ) easy fashion.&lt;/p&gt;

&lt;p&gt;We already defined our overlap above, in our case:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React / React DOM&lt;/li&gt;
&lt;li&gt;React Router&lt;/li&gt;
&lt;li&gt;Moment&lt;/li&gt;
&lt;li&gt;Classnames&lt;/li&gt;
&lt;li&gt;Okta React / Signin Widget&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We want to make sure we have both applications on the same versions and then we can exclude these items from our Rollup build. This will help make the integration easier and the package size smaller.&lt;/p&gt;

&lt;p&gt;The next thing we need to do is tease out the 'provider' level items that don't overlap. This typically looks like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Theme&lt;/li&gt;
&lt;li&gt;Notifications&lt;/li&gt;
&lt;li&gt;Error Boundaries&lt;/li&gt;
&lt;li&gt;HTTP Providers ( Apollo / etc )&lt;/li&gt;
&lt;li&gt;State management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and then make a new component called something like &lt;code&gt;Embed.tsx&lt;/code&gt; that encapsulates those items and defines the sub applications routes. Here's a rough outline of what mine looked like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight tsx"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Embed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;FC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Theme&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Notifications&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ApolloProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt; &lt;span class="na"&gt;fallback&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Loader&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Switch&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt;
                &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"/embed/home"&lt;/span&gt;
                &lt;span class="na"&gt;component&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;Home&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
              &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
              &lt;span class="si"&gt;{&lt;/span&gt; &lt;span class="cm"&gt;/* rest of your routes */&lt;/span&gt; &lt;span class="si"&gt;}&lt;/span&gt;
            &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Switch&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Suspense&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
        &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ErrorBoundary&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;ApolloProvider&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Notifications&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Theme&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is the component that we will embed in the parent application and the component that will be in the rollup build path.&lt;/p&gt;

&lt;p&gt;Next thing is the rollup config. This is going to differ based on your toolchain but they roughly look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;resolve&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollup/plugin-node-resolve&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;commonjs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollup/plugin-commonjs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postcss&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rollup-plugin-postcss&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;svgr&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@svgr/rollup&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollup/plugin-url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;babel&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollup/plugin-babel&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;json&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@rollup/plugin-json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;replace&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rollup-plugin-re&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;peerDepsExternal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rollup-plugin-peer-deps-external&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;pkg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./package.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;extensions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.jsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.ts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.tsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.svg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.css&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;input&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./src/Embed/Embed.tsx&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;output&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;file&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pkg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;sourcemap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;umd&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;emebed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;strict&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;inlineDynamicImports&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nf"&gt;peerDepsExternal&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nf"&gt;resolve&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;browser&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;preferBuiltins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="nf"&gt;postcss&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;plugins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;postcss-preset-env&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)({&lt;/span&gt; &lt;span class="na"&gt;stage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
          &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;autoprefixer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;patterns&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
          &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;test&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;([&lt;/span&gt;&lt;span class="sr"&gt;'`"&lt;/span&gt;&lt;span class="se"&gt;])(\/&lt;/span&gt;&lt;span class="sr"&gt;home&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;/g&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;$1/embed/home&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
          &lt;span class="p"&gt;}&lt;/span&gt;
          &lt;span class="cm"&gt;/** rest of your routes */&lt;/span&gt;
        &lt;span class="p"&gt;]&lt;/span&gt;
      &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nf"&gt;url&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nf"&gt;svgr&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nf"&gt;commonjs&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
      &lt;span class="nf"&gt;babel&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's take a moment to review what this is doing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;input&lt;/code&gt; defines the entry path for our new &lt;code&gt;Embed&lt;/code&gt; component.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;output&lt;/code&gt; defines how we want to package the application&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;plugins&lt;/code&gt; defines things that tools like CRA typically handle for us that we need to include a rollup version for.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Inside the plugins, we have 2 things I want to make sure and note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;peerDepsExternal&lt;/code&gt; plugin will resolve the packages we deteremined overlapped and exclude them from the build. I defined these packages in the &lt;code&gt;peerDependencies&lt;/code&gt; section of the &lt;code&gt;package.json&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;replace&lt;/code&gt; plugin will rewrite the paths of anchors and &lt;code&gt;history.push&lt;/code&gt; type components. Typically you can use the &lt;code&gt;Redirect&lt;/code&gt; component in react-router to do this but it causes us quite a bit of issues so we opted for this approach.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This configuration will now compile the TypeScript to JavaScript and all the styles and images in a friendly format that any React app can consume.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bringing the code together
&lt;/h2&gt;

&lt;p&gt;Another fun challenge was that one company used Github and the other Gitlab and of course different build systems. &lt;/p&gt;

&lt;p&gt;NPM provides an excellent way to publish and version packages so instead of manually copying or submodules, why not take this approach? &lt;/p&gt;

&lt;p&gt;At this point, it truly became just like any other NPM dependency we would include in a React app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Every organization has different requirements, tools, timelines and priorities but more than likely in these situations its mainly focused around time to market. Hopefully this brain dump can help make someone's life easier the next time you get a new step-parent of a company.&lt;/p&gt;

&lt;p&gt;I hope you enjoyed the post, if you liked it follow me on &lt;a href="https://twitter.com/amcdnl"&gt;Twitter&lt;/a&gt; and &lt;a href="https://github.com/amcdnl"&gt;Github&lt;/a&gt; for more JavaScript tips/opinions/projects/articles/etc!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Asking Your Big Security Data Questions</title>
      <dc:creator>Austin</dc:creator>
      <pubDate>Tue, 08 Dec 2020 17:52:50 +0000</pubDate>
      <link>https://forem.com/amcdnl/asking-your-big-security-data-questions-5630</link>
      <guid>https://forem.com/amcdnl/asking-your-big-security-data-questions-5630</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--D9HwiPQo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.pinimg.com/474x/d7/17/dc/d717dce5ff4f0bfe17acd76f3a7328a1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--D9HwiPQo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://i.pinimg.com/474x/d7/17/dc/d717dce5ff4f0bfe17acd76f3a7328a1.jpg" alt="q" width="250" height="262"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Humans are now producing more data on a day-by-day basis than ever before. Every minute, users on the internet generate 2.5 quintillion bytes of data on average. The data varies from selfies and pictures of food, to network data created every time we visit a website or get a DoS attack.&lt;/p&gt;

&lt;p&gt;As humans become more ‘datafied’ the cyber security industry needs to ingest and make decisions on this vast information every day. With the pace of of data creation showing no signs of slowing down, this means that the cyber security industry needs to adapt to identify threats faster and respond more quickly to more events that could make or break a business.&lt;/p&gt;

&lt;h2&gt;
  
  
  Interpreting Data with Technology
&lt;/h2&gt;

&lt;p&gt;As the amount of data grows, we need to be able to better understand this information and make decisions from it. Promising technology like machine learning and neural networks dominate every sector of business today, but the problem is the very fact that they are still promising — not yet delivering in a practical sense.&lt;/p&gt;

&lt;p&gt;It still takes a lot of work to create good insights from the information, often employing the need for a data scientist. And, while the data science field is growing at an exponential rate every year, it takes time and money to build and perfect these algorithms that many organizations just can’t afford.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--eNzHhng---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/max/1800/1%2AwBFKrP7IuGuE2himm71Onw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--eNzHhng---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://miro.medium.com/max/1800/1%2AwBFKrP7IuGuE2himm71Onw.png" alt="trend" width="800" height="444"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Even after organizations invest in all this technology, it doesn’t solve the root problem of how we as humans interact with our data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Today’s Interfaces
&lt;/h2&gt;

&lt;p&gt;Today many interfaces are built around the technical challenges that developers encounter. To be frank, they look like they were created for computers, not humans. These interfaces are either a circus input elements like checkboxes and text boxes where you don’t even know what to type in them…&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--IiKMokDE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bulkrenameutility.co.uk/assets/img-bru/mainscr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--IiKMokDE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://www.bulkrenameutility.co.uk/assets/img-bru/mainscr.png" alt="form" width="800" height="608"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;…or so complex you have to be a database developer to write a simple query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT
   extract(dow FROM sale_timestamp) AS day,
   count(sale_id) as num_sales
FROM SALES
WHERE sale_timestamp &amp;gt;= now() - INTERVAL '7 DAY'
GROUP BY extract(dow FROM scale_timestamp)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As humans, we don’t communicate this way. The above query is actually a simple question you might walk up and ask a colleague: How many sales did we close each day last week? Asking this question of a computer is clearly more complex.&lt;/p&gt;

&lt;p&gt;Although software engineering is becoming a more common skill, it’s not a valid reason for us avoid the root problem: Why can’t we ask simple questions of our data like we do of each other?&lt;/p&gt;

&lt;h2&gt;
  
  
  Turning to NLP
&lt;/h2&gt;

&lt;p&gt;Another old but new technology emerging to deal with this issue is called Natural Language Processing (NLP). This technology literally dates back to the birth of computers in the 1950s, but until recently we have not been able to harness it well. Even with all the technology at our hands today, much like machine learning, it’s still emerging and relatively buggy.&lt;/p&gt;

&lt;p&gt;Just try and ask Siri &lt;code&gt;What time does Best Buy open today?&lt;/code&gt; That’s a relatively easy question to process and understand but, still our technology is not quite there.&lt;/p&gt;

&lt;p&gt;Now imagine trying to use a methodology and ask an open ended question on a petabyte of data about your network traffic today as you work to understand if there was a network attack. The level of complexity cyber security teams require of NLP goes above and beyond what our technologies are able to deliver today.&lt;/p&gt;

&lt;p&gt;So it’s easy to see how human and technological limitations are currently holding security teams and analysts back from asking direct questions of our data. But how do we as an industry move forward to overcome these challenges?&lt;/p&gt;

&lt;h2&gt;
  
  
  Approaches to Solving This
&lt;/h2&gt;

&lt;p&gt;The cybersecurity industry needs to ingest and make decisions on this information every day, but as more data is generated it gets harder and harder to find meaningful answers from it.&lt;/p&gt;

&lt;p&gt;This issue is compounded by today’s interfaces, which feel like they were built for computers. Even the most ambitious UIs fall victim to limitations in the way we as humans operate. As data grows, how do analysts communicate with machines? How do we ask the data better questions to make critical business decisions?&lt;/p&gt;

&lt;h3&gt;
  
  
  The State of the Cybersecurity Industry
&lt;/h3&gt;

&lt;p&gt;Splunk is among one of the most popular organizations in the space that security practitioners use to analyze data and make decisions. Splunk and similar companies tend to use a SQL-like experience to find and filter data. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--k_9tvL1H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.splunk.com/images/thumb/7/7e/7.1.0_transactionEmail1-compressor.png/700px-7.1.0_transactionEmail1-compressor.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k_9tvL1H--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://docs.splunk.com/images/thumb/7/7e/7.1.0_transactionEmail1-compressor.png/700px-7.1.0_transactionEmail1-compressor.png" alt="splunk" width="700" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This method, while powerful, takes years of experience to become an expert at and be effective and still yet is error prone. In interfaces like the one depicted above, it’s also difficult to re-adjust the query without re-writing and pivoting on data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Auditing the Available Technologies
&lt;/h2&gt;

&lt;p&gt;Exciting new technologies like NLP are promising, but it can be cumbersome to type out simple questions in the ‘right’ way to achieve the desired response. NLP is also difficult to use when analysts don’t know exactly what they are looking for. Imagine trying to ask Siri &lt;code&gt;What stores have the new Call of Duty game in stock and are within a 15 mile range and open after 5PM?&lt;/code&gt; Even after you have a broad set of answers, you need to analyze and pivot on results, which would require re-typing the question multiple times, with slightly new conditions.&lt;/p&gt;

&lt;p&gt;Point-and-click interfaces are easy to use, but very quickly become complex and difficult to understand. They are unpopular amongst senior analysts who just want to jump into a terminal and type out a grep query.&lt;/p&gt;

&lt;p&gt;Technologies that use SQL are very powerful, but require years of training to be effective. It is also still difficult to pivot on the information without re-writing the query.&lt;/p&gt;

&lt;p&gt;I wanted to combine the strengths of all of these technologies; making a tool that is easy for entry level analysts to use and powerful enough for the most sophisticated analysts. We also wanted to make it feel more natural, as if you were asking your data a question like you would a colleague.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Ideal State
&lt;/h2&gt;

&lt;p&gt;I believe that the ideal state is on that builds on the strengths of some of the oldest and newest technologies to create an intuitive interface. As analysts explore their data sets, you can quickly type or point and click queries that provide context such as suggestions and visual elements such as calendars.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.screencast.com/users/amcdaniel22/folders/Snagit/media/29eda673-7450-469e-b053-550c0dceb69c"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mVQf2Z8c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://content.screencast.com/users/amcdaniel22/folders/Snagit/media/29eda673-7450-469e-b053-550c0dceb69c/FirstFrame.jpg" alt="video" width="800" height="447"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this experience, the analysts can filter down to find insights that are important to them. By providing an experience that allows a user to visually ask the question one word at a time, the analyst can create better queries. Once the user creates a query, they can easily go back and edit it without having to re-create the full query, allowing for easy data pivoting. The experience takes creating and modifying complex queries — like showing Insights created in the past seven days, are unassigned and still open — and makes them easy enough for an entry level analyst to build.&lt;/p&gt;

&lt;p&gt;This is just one of the ways we are making it easy for security operations centers to operate more effectively while addressing the security job gap in the market today.&lt;/p&gt;

</description>
      <category>bigdata</category>
      <category>cybersecurity</category>
      <category>nlp</category>
    </item>
    <item>
      <title>🔗 Static IPs for AWS Lambdas</title>
      <dc:creator>Austin</dc:creator>
      <pubDate>Fri, 14 Aug 2020 13:41:57 +0000</pubDate>
      <link>https://forem.com/amcdnl/static-ips-for-aws-lambdas-14e7</link>
      <guid>https://forem.com/amcdnl/static-ips-for-aws-lambdas-14e7</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;As more and more organizations move to the cloud, developers are faced with new challenges of how to secure these new services. As this trend continues, you can expect to see hybrid models of some cloud and some on-premise. How you secure the tunnels for traditional architectures like VMs is quite straight forward, however, for the some of the newer serverless architecture patterns it can be quite difficult.&lt;/p&gt;

&lt;p&gt;There are a few approaches you can take to secure these new technologies to communicate to on-premise infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Static IPs for Whitelisting&lt;/li&gt;
&lt;li&gt;SSH Tunnels&lt;/li&gt;
&lt;li&gt;VPNs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These approaches are fairly straight forward with VMs but with services like Lambdas where you can expect to see the IPs change a few times a week it can be very difficult to create predictable ranges that don't open all of AWS to your infrastructure.&lt;/p&gt;

&lt;p&gt;In this article, I will show you how to setup Static IPs and in the future posts, we will dive into the other approaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  Static IPs
&lt;/h2&gt;

&lt;p&gt;This is one of the easier but also less secure options. Security is less about making impossible passwords and more about adding several layers. Each layer has its own vulnerabilities but combining a few together can improve your security posture. I recommend adding static IPs in addition to one of the other approaches.&lt;/p&gt;

&lt;p&gt;In AWS, it's not the most straight forward thing to do since it requires a variety of resources for a VPC:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Public Subnet&lt;/li&gt;
&lt;li&gt;Private Subnet&lt;/li&gt;
&lt;li&gt;NAT Gateway&lt;/li&gt;
&lt;li&gt;Elastic IP&lt;/li&gt;
&lt;li&gt;2 Routes (public/private)&lt;/li&gt;
&lt;li&gt;Internet Gateway&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Luckily, we can script all this with a CloudFormation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"AWSTemplateFormatVersion"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"2010-09-09"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS CloudFormation for VPC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Parameters"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"env"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"String"&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Resources"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"VPCStaticIP"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::VPC"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"CidrBlock"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11.0.0.0/16"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="nl"&gt;"Fn::Join"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"lambavpc"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"SubnetPublic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::Subnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"CidrBlock"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11.0.0.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="nl"&gt;"Fn::Join"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"lambavpc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"public-subnet"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"VpcId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VPCStaticIP"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"SubnetPrivate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::Subnet"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"CidrBlock"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"11.0.1.0/24"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="nl"&gt;"Fn::Join"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"lambavpc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"private-subnet"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"VpcId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VPCStaticIP"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"InternetGateway"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::InternetGateway"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="nl"&gt;"Fn::Join"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"lambavpc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"igw"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"VPCGatewayAttachment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::VPCGatewayAttachment"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"InternetGatewayId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"InternetGateway"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"VpcId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VPCStaticIP"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"RouteTablePublic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::RouteTable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"VpcId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VPCStaticIP"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="nl"&gt;"Fn::Join"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"lambavpc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"public-route"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"RoutePublic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::Route"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"DestinationCidrBlock"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"GatewayId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"InternetGateway"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"RouteTableId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RouteTablePublic"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"SubnetRouteTableAssociationPublic"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::SubnetRouteTableAssociation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"RouteTableId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RouteTablePublic"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"SubnetId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SubnetPublic"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"EIP"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::EIP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Domain"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"vpc"&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"NatGateway"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::NatGateway"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"AllocationId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Fn::GetAtt"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"EIP"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="s2"&gt;"AllocationId"&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"SubnetId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SubnetPublic"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"RouteTablePrivate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::RouteTable"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"VpcId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"VPCStaticIP"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"Tags"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Key"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Name"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="nl"&gt;"Value"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="nl"&gt;"Fn::Join"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"lambavpc"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"-"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                                    &lt;/span&gt;&lt;span class="s2"&gt;"private-route"&lt;/span&gt;&lt;span class="w"&gt;
                                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                            &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
                        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"RoutePrivate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::Route"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"DestinationCidrBlock"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"0.0.0.0/0"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"NatGatewayId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"NatGateway"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"RouteTableId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RouteTablePrivate"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="nl"&gt;"SubnetRouteTableMainAssociationPrivate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"AWS::EC2::SubnetRouteTableAssociation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="nl"&gt;"Properties"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"RouteTableId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"RouteTablePrivate"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="nl"&gt;"SubnetId"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
                    &lt;/span&gt;&lt;span class="nl"&gt;"Ref"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"SubnetPrivate"&lt;/span&gt;&lt;span class="w"&gt;
                &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
            &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
        &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"Outputs"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This formation will create all the resources I mentioned above, next all you have to do is attach your Lambda to the new VPC network:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--bfSpc-cA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://content.screencast.com/users/amcdaniel22/folders/Snagit/media/b006c7db-7bf4-4b53-a9a4-d22f18c2d1f6/2020-08-14_09-23-52.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bfSpc-cA--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://content.screencast.com/users/amcdaniel22/folders/Snagit/media/b006c7db-7bf4-4b53-a9a4-d22f18c2d1f6/2020-08-14_09-23-52.png" alt="setup" width="800" height="465"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you are using the AWS SDK you can also do this programmatically like this example in JavaScript:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;aws-sdk&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;lambda&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;AWS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nc"&gt;Lambda&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;lambda&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createFunction&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;Code&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;S3Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;BUCKET&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;S3Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;KEY&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="na"&gt;FunctionName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;NAME&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Handler&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;index.main&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Publish&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Runtime&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nodejs12.x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;VpcConfig&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;SecurityGroupIds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SG_ID&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;SubnetIds&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SUBNET_ID1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;SUBNET_ID2&lt;/span&gt;
      &lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;promise&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can test this by making a simple Lambda that will call a website that tells us our IP.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;axios&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;handler&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;axio&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://www.whatismyip.com/&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Result&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recapping the above, this is not the most secure option but it is a layer you can add to make things more secure. When you combine this with other factors you can help harden your code so you don't have to worry about waking up at 2AM to fix an attack.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Me
&lt;/h2&gt;

&lt;p&gt;My name is Austin McDaniel, I'm the CTO and Co-founder of &lt;a href="https://crft.app"&gt;CRFT&lt;/a&gt; where we are setting out to disrupt how organizations automate security operations in the cloud. &lt;/p&gt;

&lt;p&gt;Follow me on &lt;a href="https://twitter.com/amcdnl"&gt;Twitter&lt;/a&gt; and &lt;a href="https://github.com/amcdnl"&gt;Github&lt;/a&gt; for all things JavaScript, Cloud, Security and Data viz.&lt;/p&gt;

</description>
      <category>aws</category>
      <category>serverless</category>
      <category>security</category>
    </item>
    <item>
      <title>🎣 React Hooks: The journey of mixins to hooks</title>
      <dc:creator>Austin</dc:creator>
      <pubDate>Fri, 01 Nov 2019 15:18:50 +0000</pubDate>
      <link>https://forem.com/amcdnl/react-hooks-the-journey-of-mixins-to-hooks-2jch</link>
      <guid>https://forem.com/amcdnl/react-hooks-the-journey-of-mixins-to-hooks-2jch</guid>
      <description>&lt;h2&gt;
  
  
  A brief introduction
&lt;/h2&gt;

&lt;p&gt;Unless you live under a rock (not sure that would be comfortable 😂), you've heard of hooks and how they have exploded in popularity with the community.&lt;/p&gt;

&lt;p&gt;It's easy to get caught up in the hype and not really understand how we got here and why. If you haven't watched the &lt;a href="https://reactjs.org/blog/2018/11/13/react-conf-recap.html"&gt;original video&lt;/a&gt; that Dan did at ReactConf in 2018, I recommend giving it a quick watch. The video explains what hooks give us and why they made them.&lt;/p&gt;

&lt;h2&gt;
  
  
  How did we get here?
&lt;/h2&gt;

&lt;p&gt;React has two ways to develop components: classes and functions. The irony here is that up until recently the JavaScript community had complained for so many years why don't we have classes in JavaScript and even built things like &lt;code&gt;createClass&lt;/code&gt;/etc. Recently the community has flipped the other direction going full on functional. Why did this happen? Well maybe its the fact that as humans we often want what we can't have or maybe its just because we realized that once we got them they don't really fit the JavaScript prototypical inheritance model.&lt;/p&gt;

&lt;p&gt;Prior to the launch of hooks, the functional component development approach was limited to very basic components since there was no way to leverage state or life-cycle functions. When I first saw hooks, I had flash backs to Angular 1.x code with huge functions. Granted thats a huge no-no but let's be honest in the real world it will happen eventually. I personally favored the class approach because it kept things very organized so I wasn't sold on the functional approach at first but the more I used them the more I enjoyed them. &lt;/p&gt;

&lt;h2&gt;
  
  
  History time!
&lt;/h2&gt;

&lt;p&gt;As I used hooks more and more, I started enjoying them more. One day when I was using hooks, I thought to myself how did we get here and as I started thinking about it, there is quite a history here. &lt;/p&gt;

&lt;p&gt;The problem statement is simple, how do we share the code between several components? After all code re-use is one of the first things we are often taught when we start writing code. This is typically code that handles generic things like window resize events, scroll events, etc. The hard problem is how do you make this as explicit as possible so there isn't 'magical' bits going on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Directives
&lt;/h2&gt;

&lt;p&gt;In Angular, there is a concept of directives which allow you to decorate elements with bits of functionality. For example, I could do something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt;
  &lt;span class="na"&gt;[appWindowResize]=&lt;/span&gt;&lt;span class="s"&gt;"myBreakpoints"&lt;/span&gt; 
  &lt;span class="na"&gt;(windowWidthChanged)=&lt;/span&gt;&lt;span class="s"&gt;"setNewSize($event)"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When I first started writing React, this was one of biggest things I missed. One of the biggest issues with this approach is its difficult difficult to chain these together with shared scope.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mixins
&lt;/h3&gt;

&lt;p&gt;The early versions of React used a &lt;code&gt;createClass&lt;/code&gt; method and had a concept of mixins. Not too long ago React put out a article called &lt;a href="https://reactjs.org/blog/2016/07/13/mixins-considered-harmful.html"&gt;Mixins Considered Harmful&lt;/a&gt;. The premise behind the article is that as components grow with several mixins it becomes 'incomprehensible' to understand whats going on. A component with mixins might look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;var&lt;/span&gt; &lt;span class="nx"&gt;Button&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;React&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createClass&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;mixins&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;WindowReisze&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Orientation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Animation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Tap&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Drag&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;in the body of this component, now you have all these methods that are there now magically. Where did these methods come from, what if they have name overlap, and so on.&lt;/p&gt;

&lt;p&gt;On top of all of this, React favor a more functional approach so the &lt;code&gt;createClass&lt;/code&gt; was not really good approach for this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Decorators
&lt;/h3&gt;

&lt;p&gt;Once classes landed in JavaScript, we instantly started bringing concepts from other languages like C#. Angular doubled down on this approach in Angular 2.x making the entire framework driven off decorators.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Component&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;MyComponent&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;Input&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Honestly, I don't have a problem with decorators but we hadn't even let the paint dry on classes before we started adding all these other language features and well they had to change. Now all of this code that relies so heavily on decorators is likely gonna have to be re-thought.&lt;/p&gt;

&lt;p&gt;The problem with decorators for React is the same problem I mentioned above, React favors a functional approach and when you apply decorators to functions, it ends up looking something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;bind&lt;/span&gt;
&lt;span class="p"&gt;@&lt;/span&gt;&lt;span class="nd"&gt;resize&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;bar&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and it becomes hard to comprehend again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Higher Order Components (HOCs)
&lt;/h3&gt;

&lt;p&gt;Higher order components came next. They gave us similar features as decorators but didn't require the new language feature. However they had the same problem as decorators, they are hard to reason what's going on with them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;withRouter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;connect&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="p"&gt;{},&lt;/span&gt; &lt;span class="nx"&gt;DashboardProps&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;mapStateToProps&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nx"&gt;mapDispatchToProps&lt;/span&gt;
  &lt;span class="p"&gt;)(&lt;/span&gt;&lt;span class="nx"&gt;Dashboard&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example above, there is only two HOCs wired up and I already couldn't tell you what exactly is going on.&lt;/p&gt;

&lt;h3&gt;
  
  
  Render Functions
&lt;/h3&gt;

&lt;p&gt;Once we came to the realization that all these higher order approaches suffered the same problem of being difficult to reason with, the community came up with the 'render functions' approach. While this approach is more explicit and favors a declarative approach that feels natural for web dev, it gets out of control quite quickly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
     &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Permissions&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;roles&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt; &lt;span class="na"&gt;variables&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
              &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Dashboard&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;roles&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt; &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
          &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Query&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
       &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
     &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Permissions&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Route&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach is more explicit but thats comes with a price too.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up...
&lt;/h2&gt;

&lt;p&gt;As you can see all of these approaches come with a price. Hooks give us a fresh look at making composable components with high code re-use but its hard to tell how they will play out in the real world after several developers have worked on the same bits of code in a large code base&lt;/p&gt;

&lt;p&gt;I hope you enjoyed the post, if you liked it follow me on &lt;a href="https://twitter.com/amcdnl"&gt;Twitter&lt;/a&gt; and &lt;a href="https://github.com/amcdnl"&gt;Github&lt;/a&gt; for more JavaScript tips/opinions/projects/articles/etc!&lt;/p&gt;

</description>
      <category>react</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
