<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Routing on Colin Barker</title>
        <link>https://colinbarker.me.uk/tags/routing/</link>
        <description>Recent content in Routing on Colin Barker</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>en-gb</language>
        <lastBuildDate>Mon, 21 Oct 2024 14:52:00 +0000</lastBuildDate><atom:link href="https://colinbarker.me.uk/tags/routing/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>AWS Direct Connect Allowed Prefix lists - My &#34;gotchas&#34; with it!</title>
        <link>https://colinbarker.me.uk/blog/2024-10-21-aws-direct-connect-allowed-prefix-lists/</link>
        <pubDate>Mon, 21 Oct 2024 14:52:00 +0000</pubDate>
        
        <guid>https://colinbarker.me.uk/blog/2024-10-21-aws-direct-connect-allowed-prefix-lists/</guid>
        <description>&lt;img src="https://static.colinbarker.me.uk/img/blog/2024/10/jan-huber-4MDXq_aqHY4-unsplash.jpg" alt="Featured image of post AWS Direct Connect Allowed Prefix lists - My &#34;gotchas&#34; with it!" /&gt;&lt;blockquote&gt;
&lt;p&gt;Header photo by &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/@jan_huber?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Jan Huber&lt;/a&gt; on &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/photos/silhouette-of-trees-during-sunset-4MDXq_aqHY4?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;what-is-aws-direct-connect&#34;&gt;What is AWS Direct Connect?
&lt;/h2&gt;&lt;p&gt;In this world of cloud technologies, and the idea that the cloud can solve all your problems, there is always a need to have some level of connection from an on-premise, or data centre location into AWS. Typically, the use of a VPN can be enough for most organisations, and it is a lot cheaper than &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/aws-direct-connect.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Direct Connect&lt;/a&gt; however, there will always be a wider security policy, or additional protections you need on your network. This is where AWS Direct Connect comes in.&lt;/p&gt;
&lt;p&gt;Unlike a VPN connection, which creates a private, encrypted tunnel between different networks and AWS, AWS Direct Connect can be seen in the most simplest terms, as plugging a network cable from a switch in your racks into a switch inside AWS that is connected directly into an AWS network. A &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Data_link_layer&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;layer 2&lt;/a&gt; &amp;ldquo;wired&amp;rdquo; connection that you can push traffic you need through it. The connection never transits through the public internet, and is completely private (to a degree). It can reduce the number of hops over different internet routers to get to your AWS network, reducing the latency and improving the available bandwidth to and from your AWS resources, and depending on the size of the pipe you request from AWS, it could be faster than what is currently capable over a standard Site to Site VPN connection.&lt;/p&gt;
&lt;p&gt;It uses a networking standard called &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/IEEE_802.1Q&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;802.1Q&lt;/a&gt; VLAN tagging to be able to segment the traffic, by tagging traffic that transverses the network, switches can ensure that only the right ports see the right traffic. This is a very similar concept to the &lt;a class=&#34;link&#34; href=&#34;https://en.wikipedia.org/wiki/Virtual_local_area_network&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;VLANs&lt;/a&gt; that you may be familiar with from your home network, same technology, just in a different context.&lt;/p&gt;
&lt;p&gt;This post isn&amp;rsquo;t meant to be a complete re-hash of the documentation! If you would like to know more, then feel free to look at the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/whitepapers/latest/aws-vpc-connectivity-options/aws-direct-connect.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Direct Connect documentation&lt;/a&gt;. Instead, I will go through some of the gotchas that I have encountered with AWS Direct Connect while building a network for a customer.&lt;/p&gt;
&lt;h2 id=&#34;allowed-prefixes-for-aws-direct-connect-gateways&#34;&gt;Allowed Prefixes for AWS Direct Connect gateways
&lt;/h2&gt;&lt;p&gt;There is a whole page on the AWS documentation called &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/directconnect/latest/UserGuide/allowed-to-prefixes.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Allowed prefixes interactions&lt;/a&gt; specifically for this, so I will talk about the specific gotcha that I encountered. The allowed prefixes act differently depending on the type of association you have linked your AWS network up to Direct Connect with. Virtual Private Gateway (VPG) or Transit Gateway (TGW), the list changes from a filter to a whitelist of what can be advertised over Direct Connect, and in the case I worked with, in both directions.&lt;/p&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/DirectConnectBlogPost-Simple-Diagram.jpg&#34; data-caption=&#34;Example of an AWS Direct Connect connection between a Transit Gateway and a Virtual Private Gateway&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/DirectConnectBlogPost-Simple-Diagram.jpg&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Example of an AWS Direct Connect connection between a Transit Gateway and a Virtual Private Gateway&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;Firstly, this is just an example of a wider customer example! It wasn&amp;rsquo;t quite set up this way, but this is summarised to show the potential of two different ways to connect your network to AWS. In reality, the customer did have something similar setup, but connected to two different types of setup, that we came in to resolve for them. For this we shall look at the Allowed Prefixes list across both association types.&lt;/p&gt;
&lt;h2 id=&#34;where-to-find-the-allowed-prefixes-list&#34;&gt;Where to find the Allowed Prefixes list
&lt;/h2&gt;&lt;p&gt;This one caught me out when looking around the interface, if you have never had to use AWS Direct Connect before, while you know it might exist from training, locating the list took a few minutes to find! On many occasions during customer calls I got myself lost looking for this, mainly because - it&amp;rsquo;s available in two locations!&lt;/p&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/direct-connect-gateway-1.png&#34; data-caption=&#34;Location of the Allowed Prefixes from the Direct Connection Gateways UI&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/direct-connect-gateway-1.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Location of the Allowed Prefixes from the Direct Connection Gateways UI&lt;/figcaption&gt;
  &lt;/figure&gt;





  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/direct-connect-gateway-2.png&#34; data-caption=&#34;Location of the Allowed Prefixes from the Transit Gateways UI&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/direct-connect-gateway-2.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Location of the Allowed Prefixes from the Transit Gateways UI&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;Both locations will send you to the same place, so don&amp;rsquo;t worry that you are editing one and need to amend the other.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;: Just like with any other BGP connection, making a change to this list will reset the BGP connection and re-advertise the prefixes in the list. This normally isn&amp;rsquo;t an issue, but sometimes this can cause a connectivity break if there is an issue somewhere else in the BGP sessions that exist. Just be aware of this if you need to make a change. Include it in any change request, or process you have to amend the list.&lt;/p&gt;
&lt;h2 id=&#34;an-example-setup&#34;&gt;An example setup
&lt;/h2&gt;


  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/DirectConnectBlogPost-Networking-Example.jpg&#34; data-caption=&#34;Simple example of two different groups of CIDRs, can we work out what will be advertised on site?&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/DirectConnectBlogPost-Networking-Example.jpg&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Simple example of two different groups of CIDRs, can we work out what will be advertised on site?&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;In this example, we have listed essentially what the VPC&amp;rsquo;s are advertising into the different associations. This hasn&amp;rsquo;t covered the lower level examples of how this connects in, we shall assume that prorogation has been enabled properly on each, and both the Transit Gateway and the Virtual Private Gateway are receiving the correct prefixes.&lt;/p&gt;
&lt;h2 id=&#34;allowed-prefixes-list-with-a-transit-gateway-association&#34;&gt;Allowed Prefixes list with a Transit Gateway Association
&lt;/h2&gt;&lt;p&gt;Starting with an AWS Transit Gateway association, we had traffic being advertised over BGP to AWS, and the VPC&amp;rsquo;s being pushed back through to on-premise. We would need to be able to advertise network from the VPC connections, and On-Premise networks into the Transit Gateway. Remember, that essentially Direct Connect is one &amp;ldquo;router&amp;rdquo; and the Transit Gateway is another, linked with a &amp;ldquo;virtual cable&amp;rdquo;. The allowed prefix list in this case acts as both a filter and an announcer right in the middle of the two, but controlled from the Direct Connect side. This list acts as the CIDR&amp;rsquo;s that get advertised into the Transit Gateway. The &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/directconnect/latest/UserGuide/allowed-to-prefixes.html#allowed-to-prefixes-transit-gateway&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;documentation calls it out&lt;/a&gt; on this specific section, but it caught me out with my customer!&lt;/p&gt;
&lt;p&gt;For this example, we are going to use an allowed prefix list that looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;10.0.0.0/16&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;172.26.0.0/20&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;192.168.0.0/20&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;100.70.0.0/24&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this prefix list and the above listed AWS advertised prefixes, this will show you what gets advertised on to the on-premise network. This works the opposite way around as well, for on-premise networks advertised into AWS however, for this example we will just go one way.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AWS Advertised Prefix&lt;/th&gt;
&lt;th&gt;Allowed Prefix Entry&lt;/th&gt;
&lt;th&gt;On-Premise Received Prefix&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10.0.0.0/16&lt;/td&gt;
&lt;td&gt;10.0.0.0/16&lt;/td&gt;
&lt;td&gt;10.0.0.0/16&lt;/td&gt;
&lt;td&gt;Simple example, what was advertised is what was received&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;172.26.0.0/16&lt;/td&gt;
&lt;td&gt;172.26.0.0/20&lt;/td&gt;
&lt;td&gt;172.26.0.0/20&lt;/td&gt;
&lt;td&gt;Here we have a larger CIDR in AWS, but the prefix is smaller in the allowed prefix list, so the &lt;strong&gt;smaller&lt;/strong&gt; prefix is what is received&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;192.168.0.0/24&lt;/td&gt;
&lt;td&gt;192.168.0.0/20&lt;/td&gt;
&lt;td&gt;192.168.0.0/20&lt;/td&gt;
&lt;td&gt;Here we have a smaller CIDR in AWS, but the prefix is larger in the allowed prefix list, so the &lt;strong&gt;larger&lt;/strong&gt; prefix is what is received&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100.64.0.0/24&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;An example of the filter element working, while we have configured the AWS side to advertise the prefix, it is not allowed to be advertised over Direct Connect to on-premise&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;100.70.0.0/24&lt;/td&gt;
&lt;td&gt;100.70.0.0/24&lt;/td&gt;
&lt;td&gt;This is where it can get a little complex, we have added the allowed prefix, but it isn&amp;rsquo;t being advertised on AWS -or- on premise. In this instance both sides of the association will &lt;strong&gt;receive&lt;/strong&gt; the prefix, even though there is no network&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;GOTCHA&lt;/strong&gt;: Be careful when using the allowed prefix list with a Transit Gateway association, not to try and open up wider CIDR ranges than you need to, as this can have an unindented effect on the traffic that is advertised into the Transit Gateway and on premise.&lt;/p&gt;
&lt;h2 id=&#34;allowed-prefixes-list-with-a-virtual-private-gateway-association&#34;&gt;Allowed Prefixes list with a Virtual Private Gateway Association
&lt;/h2&gt;&lt;p&gt;Moving onto the Virtual Private Gateway association, this connection uses pure filtering. If you are on the filter list, then you will be allowed to advertise, if you are not, then you can&amp;rsquo;t. The CIDRs advertised must be exact otherwise the filter will block it. This list will not actively announce any CIDR in the list, so you can&amp;rsquo;t use it to advertise non-existent or wider ranges to make &amp;ldquo;administration&amp;rdquo; easier later on! The &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/directconnect/latest/UserGuide/allowed-to-prefixes.html#allowed-to-prefixes-virtual-private-gateway&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Documentation also calls this out&lt;/a&gt; but for me, this is where I was also caught out.&lt;/p&gt;
&lt;p&gt;For this example, we are going to use an allowed prefix list that looks like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;10.100.0.0/24&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;172.16.0.0/20&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;192.168.0.0/20&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this prefix list and the advertised routes that exist in the AWS side, we will show you what gets advertised on the on-premise network. Just like before, this works the opposite way around as well, for on-premise networks advertised into AWS however, for this example we will just go one way.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;AWS Advertised Prefix&lt;/th&gt;
&lt;th&gt;Allowed Prefix Entry&lt;/th&gt;
&lt;th&gt;On-Premise Received Prefix&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;10.100.0.0/24&lt;/td&gt;
&lt;td&gt;10.100.0.0/24&lt;/td&gt;
&lt;td&gt;10.100.0.0/24&lt;/td&gt;
&lt;td&gt;Simple example, what was advertised is what was received, filter is allowed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;172.16.0.0/16&lt;/td&gt;
&lt;td&gt;172.16.0.0/20&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;We h ave a wider CIDR in AWS, but the filter is of a smaller range, therefore this does not get advertised into the on-premise network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;192.168.20.0/24&lt;/td&gt;
&lt;td&gt;192.168.16.0/20&lt;/td&gt;
&lt;td&gt;192.168.20.0/24&lt;/td&gt;
&lt;td&gt;Here we have a smaller CIDR in AWS, and the filter is for a wider range, as the smaller prefix is within the larger prefix on the filter list, it will allow it through to the on-premise network&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;100.74.0.0/24&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;None&lt;/td&gt;
&lt;td&gt;Simple example, this CIDR is not in th prefix list, so it is not allowed to be advertised&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;GOTCHA&lt;/strong&gt;: Here we can see that the filter list is not the same as before, different ranges get advertised in different ways. While this is talked a lot in the AWS documentation, getting the experience of using this with AWS Direct Connect is a little harder due to it&amp;rsquo;s specific usage and adoption within different customers.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary
&lt;/h2&gt;


  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/DirectConnectBlogPost-Prefix-Lists.jpg&#34; data-caption=&#34;The final outcome of what would be received by the Customer Gateway&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2024/10/DirectConnectBlogPost-Prefix-Lists.jpg&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;The final outcome of what would be received by the Customer Gateway&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;Sometimes it can feel counter intuitive on how the two types of allowed prefix lists work, but they are important in knowing the best way to configure a large organisations connection into AWS. Being able to see this in person is very hard to see due to the adoption of AWS Direct Connect, so keep this in mind the next time you run into an odd routing problem with the use of AWS Direct Connect.&lt;/p&gt;
</description>
        </item>
        <item>
        <title>Zero Trust Network Router on AWS</title>
        <link>https://colinbarker.me.uk/blog/2024-04-12-zero-trust-network-router-on-aws/</link>
        <pubDate>Fri, 12 Apr 2024 18:41:00 +0000</pubDate>
        
        <guid>https://colinbarker.me.uk/blog/2024-04-12-zero-trust-network-router-on-aws/</guid>
        <description>&lt;img src="https://static.colinbarker.me.uk/img/blog/2024/04/sander-weeteling-KABfjuSOx74-unsplash.jpg" alt="Featured image of post Zero Trust Network Router on AWS" /&gt;&lt;blockquote&gt;
&lt;p&gt;Header photo by &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/@sanderweeteling?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Sander Weeteling&lt;/a&gt; on &lt;a class=&#34;link&#34; href=&#34;https://unsplash.com/photos/teal-bookeh-lights-KABfjuSOx74?utm_content=creditCopyText&amp;amp;utm_medium=referral&amp;amp;utm_source=unsplash&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Unsplash&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;what-is-a-zero-trust-network&#34;&gt;What is a &amp;ldquo;Zero Trust Network&amp;rdquo;
&lt;/h2&gt;&lt;p&gt;To put plainly, this is a network that is created that by default has Zero Trust within it, it is based off the idea of a Zero Trust security model which is a specific type of implementation used across different networks.&lt;/p&gt;
&lt;blockquote&gt;
    &lt;p&gt;The main concept behind the zero trust security model is &amp;ldquo;never trust, always verify&amp;rdquo;, which means that users and devices should not be trusted by default&lt;/p&gt;&lt;span class=&#34;cite&#34;&gt;&lt;span&gt;― &lt;/span&gt;&lt;span&gt;Zero trust security model, &lt;/span&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Zero_trust_security_model&#34;&gt;&lt;cite&gt;Wikipedia&lt;/cite&gt;&lt;/a&gt;&lt;/span&gt;&lt;/blockquote&gt;
&lt;p&gt;So, how does this apply to networking? Well the main concept here is, that you create a network that by default disallows traffic that isn&amp;rsquo;t known, verified, or wanted. This can be expanded, to then have all your devices connected into a single network, that by default, only allows traffic to pass between each node if you accept it. This is a concept that is often referred to as a &amp;ldquo;Zero Trust Network&amp;rdquo;.&lt;/p&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2024/04/switch-connection.png&#34; data-caption=&#34;Example of a simple network with switches and WiFi connection point&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2024/04/switch-connection.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Example of a simple network with switches and WiFi connection point&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;Starting with a basic scenario, above we have a simple office, it has a Data Room with a load of servers, with a couple of Virtual Machines, some Head office computers, a physical server, and a mobile phone connected to a WiFi network. Using this as a base, everything had to be in the same place, but it was all on the same network - devices would talk to each other through the switch, and traffic didn&amp;rsquo;t need to jump over anything other than the switch (excluding the phone!).&lt;/p&gt;
&lt;p&gt;As the business expanded, it migrated the on-premise data room to a data centre, the Head Office was moved to a new location, and people had the option of working from home. Additionally, the CTO has asked, &amp;ldquo;&lt;em&gt;We need to move to &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS&lt;/a&gt;&lt;/em&gt;&amp;rdquo;. Networking before this would have been quite complex to set up.&lt;/p&gt;
&lt;p&gt;This is where a Zero Trust Network comes into play.&lt;/p&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2024/04/zero-trust-connections.png&#34; data-caption=&#34;Depiction of a Zero Trust Network solution, with AWS hooked in&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2024/04/zero-trust-connections.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Depiction of a Zero Trust Network solution, with AWS hooked in&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;Let&amp;rsquo;s take a look at the above example. Even though the Head Office move was completed, the data centre had been set up, and there were workloads in AWS, we can see here - the network is still directly connected. With this scenario, each segment is part of the wider network, rather than using a VPN connection to route traffic between them, you can see that it is possible to just talk from one side to another, with the only hop being the Zero Trust network in the middle. Think of the provider as essentially a switch!&lt;/p&gt;
&lt;p&gt;In this post, I will concentrate primarily on the Zero Trust Appliance in AWS, and how we can connect to a Zero Trust Network.&lt;/p&gt;
&lt;h2 id=&#34;introduction-to-tailscale&#34;&gt;Introduction to Tailscale
&lt;/h2&gt;&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tailscale&lt;/a&gt; is one of the many different Software Defined, Zero Trust networking solutions that exist today. Many different providers have different ways of implementing their solutions, but they all are based on the same simple premise, &amp;ldquo;&lt;em&gt;never trust, always verify&lt;/em&gt;&amp;rdquo;. Tailscale has &lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/kb/1316/device-add&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;multiple methods&lt;/a&gt; for adding devices to the network, by default, the Access Control Lists (&lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/kb/1018/acls&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;ACLs&lt;/a&gt;) will not permit traffic between different devices unless explicitly states in the configuration of the ACL.&lt;/p&gt;
&lt;p&gt;For anyone looking at behind the scenes of the technology used at Tailscale, I would recommend &amp;ldquo;&lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/blog/how-tailscale-works&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;em&gt;How Tailscale Works&lt;/em&gt;&lt;/a&gt;&amp;rdquo; by Avery Pennarun who wrote how the data plan works, and a couple of examples as to why traditional VPNs might cause latency or even general issues in network connectivity.&lt;/p&gt;



  
    
    
    
  
  
  
  
  
  
  
  &lt;figure&gt;
    &lt;a data-fancybox=&#34;gallery&#34; href=&#34;https://static.colinbarker.me.uk/img/blog/2024/04/tailscale-appliance-demo.png&#34; data-caption=&#34;Our example, Tailscale to connect an Office to AWS&#34;&gt;&lt;img src=&#34;https://static.colinbarker.me.uk/img/blog/2024/04/tailscale-appliance-demo.png&#34;&gt;&lt;/a&gt;
    &lt;figcaption&gt;Our example, Tailscale to connect an Office to AWS&lt;/figcaption&gt;
  &lt;/figure&gt;


&lt;p&gt;Simply put, Tailscale will act as our &amp;ldquo;switch&amp;rdquo; and set up the point-to-point network between an &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/concepts.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;EC2 instance&lt;/a&gt;, and an office where they might have several desktops.&lt;/p&gt;
&lt;p&gt;For this post today, I will concentrate specifically on the Appliance that will sit in AWS, and how we would configure this for a customer.&lt;/p&gt;
&lt;h2 id=&#34;building-a-zero-trust-network-router-on-aws&#34;&gt;Building a Zero Trust Network Router on AWS
&lt;/h2&gt;&lt;p&gt;For this, we will be using a specific set of tooling:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://www.terraform.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform&lt;/a&gt; v1.7.5 - An infrastructure as code tool&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Provider&lt;/a&gt; - The translator between Terraform and the AWS API&lt;/li&gt;
&lt;li&gt;&lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/tailscale/tailscale/latest/docs&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tailscale Provider&lt;/a&gt; - The translator between Terraform and the Tailscale API&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each &amp;ldquo;device&amp;rdquo; that is connected to Tailscale will need to be authenticated and approved before the device will be given access to the network. Even if there is an ACL in place that permits the access, the approval must occur. This can cause an issue when working with Infrastructure as Code (IaC), as the process would need to be automated. This can be overcome by generating a &lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/kb/1085/auth-keys&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Tailnet Auth Key&lt;/a&gt; that is used specifically for the launching of the instance, and more specifically allowing your device to be added with &amp;ldquo;pre-approval&amp;rdquo;. For this, we will create a &amp;ldquo;&lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/tailscale/tailscale/latest/docs/resources/tailnet_key&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;tailnet key&lt;/a&gt;&amp;rdquo; resource.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt;1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;6
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Create an authorization token for the Tailscale router to add itself to the Tailnet
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tailscale_tailnet_key&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;tailnet_key&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;preauthorized&lt;/span&gt; = &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;    # Set to true to allow the pre-approval of the device
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;expiry&lt;/span&gt;        = &lt;span class=&#34;m&#34;&gt;7776000&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt; # Time in seconds
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;description&lt;/span&gt;   = &lt;span class=&#34;s2&#34;&gt;&amp;#34;Tailnet key for the server&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;Simply put, this generates the key as a resource, and then Terraform knows what the key is, and any other properties that will have been shown by the API call to create the key.&lt;/p&gt;
&lt;p&gt;With this key, the next step would be to install the Tailscale client onto the EC2 instance and make it into a router for any services within AWS. This would need to be done in a few stages when working with IaC, so we should start right at the beginning.&lt;/p&gt;
&lt;p&gt;Tailscale offers a very comprehensive guide on &lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/kb/1347/installation&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;how to install the tailscale client&lt;/a&gt; on a vast number of devices, including Linux, macOS, Windows, iOS, Android, and even down to Amazon Fire Devices, and Chromebooks too! What we are doing is creating a &lt;a class=&#34;link&#34; href=&#34;https://tailscale.com/kb/1019/subnets&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Subnet Router&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The Subnet Router is slightly different on a Zero Trust Network like this, while it is usually recommended to install the client on every single server, client, and virtual machine in the organisation, sometimes - it&amp;rsquo;s not needed. Even more so for organisations that use the Cloud, and have a LOT of ephemeral devices, and where the Software Defined Network of the Cloud Provider already has the security in place that keeps your network &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/architecture/well-architected/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Well-Architected&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Within Terraform, there is a function called &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/language/functions/templatefile&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;templatefile&lt;/code&gt;&lt;/a&gt; that can be used to generate strings or blocks of text that can use variables that are generated from within Terraform and then used within the string or block of text. Here, we are using the output of the &lt;code&gt;tailscale_tailnet_key&lt;/code&gt; resource above, and pushing the generated key value into the &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/user-data.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;user_data&lt;/code&gt;&lt;/a&gt; for an AWS EC2 Instance, to run a script on the first run. Below is the template used to install Tailscale.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;#!/bin/bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;cp&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;## Set the hostname of the server&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;hostnamectl hostname &lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;hostname&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;## Ensure that the server is up to date with all the current packges&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DEBIAN_FRONTEND&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;noninteractive sudo apt update -y
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nv&#34;&gt;DEBIAN_FRONTEND&lt;/span&gt;&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;noninteractive sudo apt upgrade -y
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;## Enable IP Forwarding on the router to ensure that packets will flow as required&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;net.ipv4.ip_forward = 1&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sudo tee -a /etc/sysctl.d/99-tailscale.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;nb&#34;&gt;echo&lt;/span&gt; &lt;span class=&#34;s1&#34;&gt;&amp;#39;net.ipv6.conf.all.forwarding = 1&amp;#39;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sudo tee -a /etc/sysctl.d/99-tailscale.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo sysctl -p /etc/sysctl.d/99-tailscale.conf
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;## Install Tailscale from the source&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;curl -fsSL https://tailscale.com/install.sh &lt;span class=&#34;p&#34;&gt;|&lt;/span&gt; sh
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;## Start Tailscale with the authorisation key to add it to the network&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;sudo tailscale up --authkey&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;ts_authkey&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt; --advertise-routes&lt;span class=&#34;o&#34;&gt;=&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;local_cidrs&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt; --accept-routes
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;There is quite a bit happening in the script, it can be summarised as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Set the hostname for the instance&lt;/em&gt; - While this is an EC2 instance, and usually in the cloud you would probably use more ephemeral devices, a Subnet Router will need to act more like a &amp;ldquo;&lt;a class=&#34;link&#34; href=&#34;https://twitter.com/randybias/status/444306871545892864&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;pet&lt;/a&gt;&amp;rdquo; so that Tailscale sees this as an appliance object. Setting the hostname will mean that it is recognisable as to which host this is within your Tailscale network&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Update the instance using apt&lt;/em&gt; - Pretty simple, make sure the instance is running the latest updates and patches before continuing!&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Set IP Forwarding on the device&lt;/em&gt; - This is a key step, especially so in Linux, as this is to enable the EC2 instance to take traffic that it receives and forward it on. This &lt;a class=&#34;link&#34; href=&#34;https://unix.stackexchange.com/questions/673573/what-exactly-happens-when-i-enable-net-ipv4-ip-forward-1&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;specific setting&lt;/a&gt; tells the networking device at a kernel level to route traffic through it, as by default this is switched off.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Install Tailscale&lt;/em&gt; - The primary install of Tailscale, taken from the latest version on the Tailscale site.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Startup tailscale WITH the keys&lt;/em&gt; - Here we finally get to see where our tailscale key will be used - using the up function, we can set the authkey generated before, as well as which routes to advertise. We will go into this in a second, but for now, this is where the key will go.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Simple enough script, now we have to move on to creating the EC2 instance that will run&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;div class=&#34;chroma&#34;&gt;
&lt;table class=&#34;lntable&#34;&gt;&lt;tr&gt;&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code&gt;&lt;span class=&#34;lnt&#34;&gt; 1
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 2
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 3
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 4
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 5
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 6
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 7
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 8
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt; 9
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;10
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;11
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;12
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;13
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;14
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;15
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;16
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;17
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;18
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;19
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;20
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;21
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;22
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;23
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;24
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;25
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;26
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;27
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;28
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;29
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;30
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;31
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;32
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;33
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;34
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;35
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;36
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;37
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;38
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;39
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;40
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;41
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;42
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;43
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;44
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;45
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;46
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;47
&lt;/span&gt;&lt;span class=&#34;lnt&#34;&gt;48
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class=&#34;lntd&#34;&gt;
&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-terraform&#34; data-lang=&#34;terraform&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Use a data object to get the latest version of Ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;data&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_ami&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;ubuntu&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;most_recent&lt;/span&gt; = &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;   = &lt;span class=&#34;s2&#34;&gt;&amp;#34;name&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;values&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-arm64-server-*&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;nx&#34;&gt;filter&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;name&lt;/span&gt;   = &lt;span class=&#34;s2&#34;&gt;&amp;#34;virtualization-type&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;na&#34;&gt;values&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;hvm&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;owners&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;099720109477&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;# Build the Tailscale router using Ubuntu 22.04 LTS
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;&lt;span class=&#34;kr&#34;&gt;resource&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;aws_instance&amp;#34;&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;this&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;  # General setup of the instance using the Ubuntu AMI
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;ami&lt;/span&gt;                     = &lt;span class=&#34;nb&#34;&gt;data&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;aws_ami&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ubuntu&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;ebs_optimized&lt;/span&gt;           = &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;instance_type&lt;/span&gt;           = &lt;span class=&#34;s2&#34;&gt;&amp;#34;t4g.small&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;disable_api_termination&lt;/span&gt; = &lt;span class=&#34;kc&#34;&gt;true&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;  # Key for SSH Access (if required)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;key_name&lt;/span&gt; = &lt;span class=&#34;nb&#34;&gt;try&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ssh_key_name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt; &lt;span class=&#34;nx&#34;&gt;null&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;  # Run the user_data for this instance to install Tailscale
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;user_data&lt;/span&gt; = &lt;span class=&#34;nb&#34;&gt;templatefile&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;${&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;path&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;module&lt;/span&gt;&lt;span class=&#34;si&#34;&gt;}&lt;/span&gt;&lt;span class=&#34;s2&#34;&gt;/templates/tailscale-install.sh.tpl&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;ts_authkey&lt;/span&gt;  = &lt;span class=&#34;nx&#34;&gt;tailscale_tailnet_key&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;key&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;hostname&lt;/span&gt;    = &lt;span class=&#34;nb&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;hostname&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;na&#34;&gt;local_cidrs&lt;/span&gt; = &lt;span class=&#34;nb&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;local_cidrs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;  # Networking Settings
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;source_dest_check&lt;/span&gt;      = &lt;span class=&#34;kc&#34;&gt;false&lt;/span&gt;&lt;span class=&#34;c1&#34;&gt; # Disabled to allow IP forwarding from the network
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;&lt;/span&gt;  &lt;span class=&#34;na&#34;&gt;private_ip&lt;/span&gt;             = &lt;span class=&#34;nb&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;private_ip&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;ipv6_addresses&lt;/span&gt;         = &lt;span class=&#34;nb&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;ipv6_addresses&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;subnet_id&lt;/span&gt;              = &lt;span class=&#34;nb&#34;&gt;var&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;subnet_id&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;na&#34;&gt;vpc_security_group_ids&lt;/span&gt; = &lt;span class=&#34;p&#34;&gt;[&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;aws_security_group&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;this&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;.&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;id&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;....&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nx&#34;&gt;snipped&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;A lot happening in this section, but in this example, we are using &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/ec2/graviton/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS Graviton&lt;/a&gt; (ARM-based) instances, as they are known to be a lot more efficient than other processor types, they can be cheaper, but also currently on &lt;a class=&#34;link&#34; href=&#34;https://aws.amazon.com/ec2/instance-types/t4/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;AWS&amp;rsquo;s Free Tier&lt;/a&gt; for the time being!&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;The data object for the &lt;code&gt;aws_ami&lt;/code&gt;&lt;/em&gt; - This will look for the latest version of the Ubuntu 22.04 image that exists in the Canonical account. Note the &lt;code&gt;arm64&lt;/code&gt; element of the filter string to look for the ARM version of the AMI.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The &lt;a class=&#34;link&#34; href=&#34;https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;&lt;code&gt;aws_instance&lt;/code&gt;&lt;/a&gt; resource to generate the subnet router&lt;/em&gt; - The standard for any EC2 instance, the primary resource with all its configuration&lt;/li&gt;
&lt;li&gt;&lt;em&gt;The general setup of the EC2 resource&lt;/em&gt; - Here we are using the &lt;code&gt;data.aws_ami.ubuntu.id&lt;/code&gt; to ensure the right AMI is set, additionally making sure that &lt;code&gt;api_termination&lt;/code&gt; has been configured, as we don&amp;rsquo;t want someone accidentally deleting the instance!&lt;/li&gt;
&lt;li&gt;&lt;em&gt;An SSH key&lt;/em&gt; - Some people might want to ensure they have an SSH key so they can log into the instance, in several cases this might not be needed.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;User data template&lt;/em&gt; - This part is where we are taking the template bash file above, and taking the variables it knows about and entering details of what Terraform knows. Here we can see the &lt;code&gt;ts_authkey&lt;/code&gt; variable is being set to the previously created &lt;code&gt;tailscale_tailnet_key&lt;/code&gt; resource. Additional settings are also entered here.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Network Settings&lt;/em&gt; - This one contains one key variable that &lt;strong&gt;MUST&lt;/strong&gt; be set for any EC2-based router that is created. The &lt;code&gt;source_dest_check&lt;/code&gt; variable must be set to &lt;code&gt;false&lt;/code&gt;. The &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/using-eni.html#eni-basics&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;source/destination checking&lt;/a&gt; is on by default, and within the software-defined VPC network on AWS, it will ensure that the traffic that sees, is the traffic for it - when it acts as a router, it will expect to see traffic pass through it from different devices that it needs to forward on. This check is disabled to allow this to happen. Without it, there is no way for traffic destined for another part of the network to flow to the EC2 instance.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Once this resource is launched, then it will appear in your Tailscale network, be approved, and should also be able to route traffic to and from your AWS network.&lt;/p&gt;
&lt;p&gt;Some other elements that make up the design for this router, for example, you will need &lt;a class=&#34;link&#34; href=&#34;https://docs.aws.amazon.com/vpc/latest/userguide/vpc-security-groups.html&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Security Groups&lt;/a&gt; set up to ensure traffic is allowed inbound and outbound to the EC2 instance and networks. To make this whole process easier, I created a &lt;a class=&#34;link&#34; href=&#34;https://developer.hashicorp.com/terraform/tutorials/modules/module&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Terraform Module&lt;/a&gt; that does all of this for you!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;a class=&#34;link&#34; href=&#34;https://github.com/mystcb/terraform-aws-tailscale-router&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;https://github.com/mystcb/terraform-aws-tailscale-router&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In Part 2 of this blog post series, I will go into how to use this module to create a Multi-AZ version of this set up, and also include the changes I will be made to the module to enable Instance Recovery if the Operating System stops responding.&lt;/p&gt;
&lt;h2 id=&#34;examples-of-other-zero-trust-networking-solutions&#34;&gt;Examples of other Zero Trust Networking Solutions
&lt;/h2&gt;&lt;p&gt;- &lt;a class=&#34;link&#34; href=&#34;https://developers.cloudflare.com/cloudflare-one/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;CloudFlare Zero Trust&lt;/a&gt; - This has more recently had an update that will allow access through one of its &lt;a class=&#34;link&#34; href=&#34;https://developers.cloudflare.com/warp-client/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;WARP&lt;/a&gt; clients. This is still in beta so one to keep an eye on. 
- &lt;a class=&#34;link&#34; href=&#34;https://enclave.io/&#34;  target=&#34;_blank&#34; rel=&#34;noopener&#34;
    &gt;Enclave&lt;/a&gt; - This was my first ever experience with Zero Trust networking, so I can&amp;rsquo;t not name-drop this one! While personally, I don&amp;rsquo;t use it anymore, it was here I learnt the basics of the Zero Trust network before moving myself to Tailscale.&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
