<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Azure Active Directory on Digi Hunch</title><link>https://static.digihunch.com/tag/azure-active-directory/</link><description>Recent content in Azure Active Directory on Digi Hunch</description><generator>Hugo -- gohugo.io</generator><language>en-US</language><lastBuildDate>Tue, 08 Apr 2025 14:19:11 -0400</lastBuildDate><atom:link href="https://static.digihunch.com/tag/azure-active-directory/index.xml" rel="self" type="application/rss+xml"/><item><title>Workload Identity on Kubernetes 1 of 2 – AKS</title><link>https://static.digihunch.com/2023/12/workload-identity-on-kubernetes-1-of-2-aks/</link><pubDate>Sat, 23 Dec 2023 16:43:00 -0400</pubDate><guid>https://static.digihunch.com/2023/12/workload-identity-on-kubernetes-1-of-2-aks/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-workload-identity-aks.webp" alt="Featured image of post Workload Identity on Kubernetes 1 of 2 – AKS" /&gt;&lt;p class="wp-block-paragraph"&gt;As applications are moved to the cloud, the application workload hosted on virtual machines need to interact with cloud resources. For this, we need an IAM solution with two mechanisms:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;a (non-human) identity in the cloud service platform (CSP), to represent the application;&lt;/li&gt;&#10;&lt;li&gt;a way to grant permission to this identity, so it can manage resources&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;CSPs such as Azure and AWS have their own implementations of the two mechanism. In Azure, we have Entra workload identity (including service principal and managed identity) for the first mechanism, and Azure roles for the second. On AWS, they are the identity pool capability of Amazon Cognito and IAM role. Next, what about the workload on managed Kubernetes service? Essentially, we will need to more mechanisms:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;a native Kubernetes identity to represent the workload (Pod);&lt;/li&gt;&#10;&lt;li&gt;a way to map the Kubernetes identity to the identity in CSP&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Kubernetes Service Account is designed for the first item. The second mechanism is for the CSP to address. In this post, let&amp;#8217;s examine this in Azure. Specifically, how does Azure manage workload identity with Azure Kubernetes Service (AKS). &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Node Identity and Cluster Identity in AKS&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Let&amp;#8217;s define what exactly is a workload identity. In Azure we think of it as one type of non-human identity. In our context, workload identity in the broader sense contains:&lt;/p&gt;&#10;&lt;ol class="wp-block-list"&gt;&#10;&lt;li&gt;the identity that represents the control plane (or the whole cluster)&lt;/li&gt;&#10;&lt;li&gt;the identity that represents the node (or kubelet process)&lt;/li&gt;&#10;&lt;li&gt;the identity that represents the application in a Pod (workload identity in the narrow sense);&lt;/li&gt;&#10;&lt;/ol&gt;&#10;&lt;p class="wp-block-paragraph"&gt;So it is important not to confuse these identities. In this section, I&amp;#8217;ll focus on 1 and 2 since they are part of workload identity in the broad sense. In the rest of the sections, I&amp;#8217;ll discuss 3, and use the narrow sense of workload identity. &lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img loading="lazy" decoding="async" width="934" height="322" src="https://static.digihunch.com/wp-content/uploads/2023/12/aks-identity.webp" alt="" class="wp-image-12970" srcset="https://static.digihunch.com/wp-content/uploads/2023/12/aks-identity.webp 934w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-identity-300x103.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-identity-768x265.webp 768w" sizes="auto, (max-width: 934px) 100vw, 934px" /&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When we create an AKS cluster, we create both a cluster control plane and a node pool. Both the control plane and the nodes need to provision cloud resources using Cloud API from Azure. For example, if we use Terraform&amp;#8217;s AzureRM provider to create an &lt;code&gt;azurerm_kubernetes_cluster&lt;/code&gt; resource, then we specify the cluster&amp;#8217;s identity using &lt;code&gt;service_principal&lt;/code&gt; or &lt;code&gt;identity&lt;/code&gt; block. We specify the nodes&amp;#8217; identity using the &lt;code&gt;kubelet_identity&lt;/code&gt; block, because &lt;code&gt;kubelet&lt;/code&gt; is the process that runs on each node. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Even though a cluster builder might be tempted to assign the same identity to both Control plane and kubelet, the security best practice is to keep them separated. It is also the responsibility of the cluster builder to distinguish activities by the control plane and by kubelet process on each node, and attache an Azure Role with minimum privilege to each of the identities.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;These two types of identities (control plane and kubelet) are relatively straightforward. In order to use them, we don&amp;#8217;t have to play with Kubernetes objects. In the next section, we&amp;#8217;ll continue to discuss the identities that represents each Pod in Azure. We now refer to them as workload identities, but the first available technology was pod managed identity.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Pod Managed Identity in AKS&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When I first worked on &lt;a href="https://static.digihunch.com/2021/12/aks-lessons-learned-2-of-2/"&gt;Azure Kubernetes&lt;/a&gt;, Pod managed identity was in preview and was the recommendation. However, Microsoft renamed it (to &lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity"&gt;Microsoft Entra pod-managed identities&lt;/a&gt;) and then deprecated it after a couple years of preview. As of Oct 2022, the recommended mechanism becomes Microsoft Entra Workload ID. For simplicity, we refer to the deprecated mechanism as &amp;#8220;Pod Identity&amp;#8221;. We discuss pod identity only for the purpose of understanding why it is no longer recommended and what is missing in it. For new workload deployment, we should always use workload identity. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For Pod Identity to work, a&lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity#register-the-enablepodidentitypreview-feature-flag"&gt; feature flag&lt;/a&gt; &lt;code&gt;EnablePodIdentityPreview&lt;/code&gt; must turn on. Pod Managed Identity &lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity#operation-mode-options"&gt;operates&lt;/a&gt; on a Kubernetes &lt;a href="https://static.digihunch.com/2022/04/kubernetes-operator/"&gt;controller&lt;/a&gt; called MIC (Managed Identity Controller) and a DaemonSet called NMI (Node Managed identity). You start with an Azure managed identity with appropriate roles. Once you installed Pod Identity, there will be two CRDs &lt;code&gt;AzureIdentity&lt;/code&gt; and &lt;code&gt;AzureIdentityBinding&lt;/code&gt;. To grant Azure permissions to a Pod, you create a CR for each CRD. The &lt;code&gt;AzureIdentity&lt;/code&gt; CR connects to your Azure managed identity. You also create an &lt;code&gt;AzureIdentityBindign&lt;/code&gt; CR. When declaring a Pod, you link to AzureIdentityBinding by using the label aadpodidbinding. &lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full is-resized"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="508" src="https://static.digihunch.com/wp-content/uploads/2023/12/aks-pod-mgd-identity.webp" alt="" class="wp-image-12971" style="width:663px;height:auto" srcset="https://static.digihunch.com/wp-content/uploads/2023/12/aks-pod-mgd-identity.webp 1024w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-pod-mgd-identity-300x149.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-pod-mgd-identity-768x381.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are two problems with pod managed identity. First, there is a &lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity#using-kubenet-network-plugin-with-microsoft-entra-pod-managed-identities"&gt;vulnerability&lt;/a&gt; when it works with kubenet as network plugin. This vulnerability requires an additional &lt;a href="https://learn.microsoft.com/en-us/azure/aks/use-azure-ad-pod-identity#mitigation"&gt;mitigation step&lt;/a&gt;. Second, it does not make use of Kubernete&amp;#8217;s Service Account. Let&amp;#8217;s discuss in the next section why it&amp;#8217;s favourable to use Kubernetes&amp;#8217; ServiceAccount. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Kubernetes Service Account&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In Kubernetes RBAC model, &lt;a href="https://kubernetes.io/docs/concepts/security/service-accounts/"&gt;Service Account&lt;/a&gt; can bind to Roles to gain access to other Kubernetes resources. The most common use case is allowing the running application in a Pod to access other Kubernetes resources. When it comes to letting an application in Pod access cloud resources in the CSP, it makes sense to use Service Account, for a a consistent pattern.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A service account must carry a token to function. Each namespace has a default service account with the token mounted automatically. Each Pod created in a namespace uses the default service account of the namespace, unless otherwise specified. However, many security organizations do not considered this default behaviour as the best practice. For example, CIS Kubernetes &lt;a href="https://www.cisecurity.org/benchmark/kubernetes"&gt;benchmark&lt;/a&gt; 1.8 has these two recommendations:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Ensure that the default service accounts are not actively used (5.1.5)&lt;/li&gt;&#10;&lt;li&gt;Ensure that Service Account Tokens are only mounted where necessary (5.1.6)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In other words, we should create non-default service account with &lt;strong&gt;automountServiceAccountToken&lt;/strong&gt; set to false. Then when declaring a Pod, we explicitly specify the service account and where to grab the token for the service account. One way to pass ServiceAccount token is through &lt;a href="https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/#serviceaccount-token-volume-projection"&gt;volume projection&lt;/a&gt;. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To allow a Pod to access Azure resources, we use the combination of Kubernetes Service Account and Microsoft Entra workload identity. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Workload Identity for AKS&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Microsoft introduced Entra Workload Identities in late 2022 to address IAM issues around machine identities. It comes with some modern features such as conditional access (e.g. location-based access, anomaly sign-in detection, etc). A &lt;a href="https://learn.microsoft.com/en-us/entra/workload-id/workload-identities-overview"&gt;workload identity&lt;/a&gt; can be:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;application: an abstract entity as the global representation of your application for use across all tenants;&lt;/li&gt;&#10;&lt;li&gt;service principal: the local representation of a global application object in a specific tenants;&lt;/li&gt;&#10;&lt;li&gt;managed identity: a special type of service principal that eliminates the need for developers to manage credentials&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In our use case for AKS workload, we also make use of Azure&amp;#8217;s Managed Identity. This part is the same as the pod identity mechanism. However, here we create a federated identity credential for managed identity. The OIDC federated identity credential is issued by the AKS cluster. Within the AKS, the service account references the identity by client_id. &lt;a href="https://learn.microsoft.com/en-us/azure/aks/workload-identity-deploy-cluster"&gt;Here&lt;/a&gt; is the documentation for the whole process.&lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="588" src="https://static.digihunch.com/wp-content/uploads/2023/12/aks-workload-identity.webp" alt="" class="wp-image-12972" srcset="https://static.digihunch.com/wp-content/uploads/2023/12/aks-workload-identity.webp 1024w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-workload-identity-300x172.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/12/aks-workload-identity-768x441.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;One of the improvements in Entra workload identity for AKS, is the use of service account, which obviates the use of CRDs. Another improvement is the use of federated identity, whose lifecycle is tied to the cluster. This pattern is not only neater, but also standard. We map a service account to a managed identity with federated credential. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Summary&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;On managed Kubernetes services, we need an integration mechanism to grant Kubernetes workload access to cloud resources. We discussed what&amp;#8217;s needed in this integration mechanism and looked at Azure Kubernetes as an example. In the next post, we&amp;#8217;ll discuss how this issue is addressed in Elastic Kubernetes Service on the AWS side.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2023/11/wordpress-security/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;WordPress Security Basics&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2024/01/workload-identity-on-kubernetes-2-of-2-eks-and-rosa-on-aws/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Workload Identity on Kubernetes 2 of 2 – EKS&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Connect kubectl to private Kubernetes cluster in EKS and AKS</title><link>https://static.digihunch.com/2023/06/connect-kubectl-to-private-kubernetes-cluster-in-eks-and-aks/</link><pubDate>Sat, 10 Jun 2023 19:31:00 -0400</pubDate><guid>https://static.digihunch.com/2023/06/connect-kubectl-to-private-kubernetes-cluster-in-eks-and-aks/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-kubectl-private-cluster.webp" alt="Featured image of post Connect kubectl to private Kubernetes cluster in EKS and AKS" /&gt;&lt;p class="wp-block-paragraph"&gt;Managed Kubernetes services give user a cluster endpoint and a number of worker nodes, with the choice. For each access, users have the choice of making them publicly available, or keeping them on private networking. In my opinion, any deployment beyond personal hobbies, should use Kubernetes private cluster, with both cluster endpoint and worker nodes on private subnet. There is no reason to expose computing nodes or Kubernetes management traffic publicly. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;For worker nodes, it is fairly easy to put VMs on private network, but many companies still have the cluster endpoint exposed publicly. There are usually two reasons. First, their CI/CD agent is hosted somewhere else on the Internet (instead of on private network with private connectivity to Kubernetes cluster) and need to access Kubernetes cluster endpoint. Second, when the cluster needs to connect with third-party identity provider as OIDC provider, a two-way communication is needed. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There is a classic pattern of using a public bastion host (jump box), with a bastion host on the public subnet, routable to the private endpoint of managed Kubernetes service. Clients then connect to the bastion host via port 22 on a public IP address. The authentication is based on SSH key pair, or worse, password. The port forwarding (aka &lt;a href="https://www.ssh.com/academy/ssh/tunneling-example"&gt;SSH tunnelling&lt;/a&gt;) capability enables all the magics. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Exposing a jump box in the public subnet with RSA key authentication is still not favourable. In this post, I&amp;#8217;ll examine some secure patterns to connect to private endpoint with improved security posture. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-aws-options"&gt;AWS options&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There are two problems. First, how to establish connectivity to the Bastion host in a private subnet. Second, how to use the Bastion host to proxy traffic to the cluster endpoint also in private subnet. To the first problem, there are two potential solutions: SSM Session Manager, and EC2 Instance Connect (EIC) with EIC endpoint (EICE).&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;SSM Session Manager was introduce in 2018. It runs an agent on the EC2, which initiates a connection to the SSM endpoint on the AWS side. This connection enables not only Session Manager, but also other Systems Managers (SSM) services such as Fleet Manager, Patch Manager and State Manager. The problem that session manager originally addresses is server management.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;AWS launched EC2 Instance Connect (EIC) in 2019, and EIC Endpoint (EICE) in 2023. EIC addresses the problem with managing SSH key pairs at scale. It dynamically generates an SSH key pair for server access, based on IAM permission. However, it still requires an instance to have its SSH port publicly accessible. With EICE, it is no longer a requirement. In the &lt;a href="https://aws.amazon.com/blogs/compute/secure-connectivity-from-public-to-private-introducing-ec2-instance-connect-endpoint-june-13-2023/?utm_content=bufferfded7&amp;amp;utm_medium=social&amp;amp;utm_source=linkedin.com&amp;amp;utm_campaign=buffer"&gt;diagram&lt;/a&gt;, EICE is placed in a private subnet, allowing EICE service to reach private instances at their SSH port. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Here is a comparison of the two:&lt;/p&gt;&#10;&lt;figure class="wp-block-table is-style-stripes"&gt;&lt;table class="has-white-background-color has-background"&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;&lt;/th&gt;&lt;th&gt;EC2 Instance Connect (EIC) with EIC Endpoint&lt;/th&gt;&lt;th&gt;SSM Session Manager&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Location of Bastion host&lt;/td&gt;&lt;td&gt;Private Subnet.&lt;/td&gt;&lt;td&gt;Private Subnet&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Need Ingress Port&lt;/td&gt;&lt;td&gt;Yes. Port 22 must open to the endpoint.&lt;/td&gt;&lt;td&gt;No. SSM agent initiate outbound connection from the instance&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Traffic Path&lt;/td&gt;&lt;td&gt;AWS CLI → AWS EIC ES → EICE→EC2 Inst&lt;/td&gt;&lt;td&gt;AWS CLI → AWS SSM ES → SSM ← EC2 Inst&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Authentication&lt;/td&gt;&lt;td&gt;AWS IAM and ephemeral SSH key when using AWS CLI directly&lt;br&gt;AWS IAM and long-term SSH key when using SSH proxy command&lt;/td&gt;&lt;td&gt;AWS IAM and long-term SSH key when using AWS CLI directly or SSH proxy command&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Work with OpenSSH&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;td&gt;Yes&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Cost&lt;/td&gt;&lt;td&gt;There is no additional cost for using EIC.&lt;/td&gt;&lt;td&gt;No additional cost, unless private SSM Endpoint.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Let&amp;#8217;s take a look at each option.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;EC2 Instance Connect&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To use EIC, pick an AMI that has it pre-installed and ensure instance profile has correct policy, as the document states &lt;a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-connect-prerequisites.html"&gt;here&lt;/a&gt;. AWC CLI will make use of local OpenSSL client. So make sure there connection at port 22 is open. To make it work with EC2 instance on a private subnet, create an EC2 Instance Connect Endpoint on the VPC, and ensure that the security group of EC2 allows port 22 from the Endpoint. Run this command:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ aws ec2-instance-connect ssh --instance-id i-00ea30a6e02db33fe&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;The command above simply generates a key pair internally, add the public key to the server side, and connect with SSH from the client side. The command takes you to an SSH session. Checking &lt;code&gt;ps -ef | grep ssh&lt;/code&gt; on the client machine, you can see the full parameter of SSH, including the location of the ephemeral private key. &lt;/p&gt;&#10;&lt;figure class="wp-block-image size-full"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="95" src="https://static.digihunch.com/wp-content/uploads/2023/06/ssh-process.webp" alt="" class="wp-image-12921" srcset="https://static.digihunch.com/wp-content/uploads/2023/06/ssh-process.webp 1024w, https://static.digihunch.com/wp-content/uploads/2023/06/ssh-process-300x28.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/06/ssh-process-768x71.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;/figure&gt;&#10;&lt;p class="wp-block-paragraph"&gt;However, if you use AWS CLI open-tunnel as proxy command to ssh, then you&amp;#8217;d still have to use the key pair used to create the EC2 instance. As suggested at the bottom of &lt;a href="https://aws.amazon.com/blogs/compute/secure-connectivity-from-public-to-private-introducing-ec2-instance-connect-endpoint-june-13-2023/?utm_content=bufferfded7&amp;amp;utm_medium=social&amp;amp;utm_source=linkedin.com&amp;amp;utm_campaign=buffer"&gt;this&lt;/a&gt; blog post, the command is:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ssh ec2-user@&lt;span style="color:#f92672"&gt;[&lt;/span&gt;INSTANCE&lt;span style="color:#f92672"&gt;]&lt;/span&gt; -i &lt;span style="color:#f92672"&gt;[&lt;/span&gt;SSH-KEY&lt;span style="color:#f92672"&gt;]&lt;/span&gt; -o ProxyCommand&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;aws ec2-instance-connect open-tunnel --instance-id %h&amp;#39;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;This is a bummer, because with native SSH tool you do not get the primary benefit of EIC &amp;#8211; ephemeral key pair. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;SSM Session Manager&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Now let&amp;#8217;s look at SSM session manager. Similarly, it needs an agent installed and &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/setup-instance-permissions.html"&gt;IAM role&lt;/a&gt; configured. You can connect to from web console but more importantly, from AWS CLI:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ aws ssm start-session --target i-0531b19bec8ad022d&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;This command takes you to an SSH session with user &lt;code&gt;ssm-user&lt;/code&gt;, without starting an OpenSSH client process locally. User do not have to manage key pair. There is also a &lt;a href="https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager-getting-started-enable-ssh-connections.html"&gt;document&lt;/a&gt; about using this command as proxy command, which uses an SSM document. I have one of the SSH config entry as:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;host i-* mi-*&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ProxyCommand sh -c &lt;span style="color:#e6db74"&gt;&amp;#34;aws ssm start-session --target %h --document-name AWS-StartSSHSession --parameters &amp;#39;portNumber=%p&amp;#39;&amp;#34;&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; User ec2-user&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; IdentityFile ~/.ssh/id_rsa&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;This allows me to directly SSH to client using OpenSSL client (e.g. &lt;code&gt;ssh i-0531b19bec8ad022d&lt;/code&gt;) by Instance ID. With this, I also need to specify my own OS user and matching private key.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;I know I will use the OpenSSH client a lot from pipelines because it is very powerful. In both options, I have to live with managing key pairs myself. With SSM session manager&amp;#8217;s proxy command, the instance does not need port 22 to open, which is a great advantage, in terms of security and operation. SSM Session Manager is a winner.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;SOCKS5 proxy for kubectl&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Either SSM Session Manager or EIC with EICE enables an SSH tunnel with key encryption between client (a local computer or a pipeline agent). On top of the SSH tunnel, we can build a &lt;a href="https://en.wikipedia.org/wiki/SOCKS#SOCKS5"&gt;SOCKS5&lt;/a&gt; proxy. Kubernetes document has a good &lt;a href="https://kubernetes.io/docs/tasks/extend-kubernetes/socks5-proxy-access-api/"&gt;page&lt;/a&gt; on how to do this. I managed to get this to work with a few gotchas.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="827px" viewBox="-0.5 -0.5 827 512" style="max-width:100%;max-height:512px;"&gt;&lt;defs&gt;&lt;linearGradient x1="0%" y1="100%" x2="0%" y2="0%" id="mx-gradient-f78e04-1-d05c17-1-s-0"&gt;&lt;stop offset="0%" style="stop-color: rgb(208, 92, 23); stop-opacity: 1;"/&gt;&lt;stop offset="100%" style="stop-color: rgb(247, 142, 4); stop-opacity: 1;"/&gt;&lt;/linearGradient&gt;&lt;style type="text/css"&gt;@import url(https://fonts.googleapis.com/css?family=Architects+Daughter);&amp;#xa;&lt;/style&gt;&lt;/defs&gt;&lt;g&gt;&lt;rect x="0" y="0" width="825" height="510" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all"/&gt;&lt;rect x="25" y="78.88" width="270" height="251.12" rx="25.11" ry="25.11" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" pointer-events="all"/&gt;&lt;rect x="435" y="60" width="370" height="240" rx="24" ry="24" fill="#dae8fc" stroke="#6c8ebf" stroke-width="2" pointer-events="all"/&gt;&lt;rect x="455" y="80" width="260" height="200" rx="20" ry="20" fill="#f5f5f5" stroke="#666666" stroke-width="2" pointer-events="all"/&gt;&lt;g fill="#333333" font-family="Helvetica" text-anchor="middle" font-size="12px"&gt;&lt;text x="584.5" y="97.5"&gt;Private Subnet&lt;/text&gt;&lt;/g&gt;&lt;rect x="475" y="123.75" width="120" height="130" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 131px; margin-left: 476px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"&gt;Bastion Host&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="535" y="143" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Bastion Host&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="75" y="110" width="190" height="193.75" fill="#fff2cc" stroke="#d6b656" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 188px; height: 1px; padding-top: 117px; margin-left: 76px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"&gt;Pipeline Agent&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="170" y="129" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Pipeline Agent&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 351.25 68 C 351.25 66.34 353.49 65 356.25 65 C 357.58 65 358.85 65.32 359.79 65.88 C 360.72 66.44 361.25 67.2 361.25 68 L 361.25 309.5 C 361.25 311.16 359.01 312.5 356.25 312.5 C 353.49 312.5 351.25 311.16 351.25 309.5 Z" fill="#bac8d3" stroke="#23445d" stroke-miterlimit="10" transform="rotate(-90,356.25,188.75)" pointer-events="all"/&gt;&lt;path d="M 361.25 68 C 361.25 69.66 359.01 71 356.25 71 C 353.49 71 351.25 69.66 351.25 68" fill="none" stroke="#23445d" stroke-miterlimit="10" transform="rotate(-90,356.25,188.75)" pointer-events="all"/&gt;&lt;rect x="312.5" y="163.75" width="90" height="20" fill="none" stroke="none" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 88px; height: 1px; padding-top: 174px; margin-left: 314px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"&gt;SSH Tunnel&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="358" y="177" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;SSH Tunnel&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 513.09 207.45 L 511.26 176.65 L 513.7 176.11 L 515.76 178.18 C 516.3 178.12 516.83 178.15 517.37 178.25 L 518.13 176.72 L 520.42 176.27 L 522.1 177.3 L 522.6 180.77 C 523.56 181.65 524.4 182.82 525.08 184.21 L 527.37 184.71 L 528.05 186.81 L 526.83 189.64 C 527.07 191.14 527.15 192.69 527.06 194.23 L 528.66 196.75 L 528.21 199.5 L 525.92 200.03 C 525.37 201.1 524.73 202.03 524.01 202.79 L 524.01 206.34 L 522.56 207.22 L 519.96 207.6 L 517.44 204.08 L 514.92 207.52 Z M 517.9 192.62 L 517.21 189.79 C 516.97 189.6 516.7 189.72 516.5 190.12 C 516.31 190.52 516.2 191.14 516.22 191.78 C 516.29 192.51 516.57 193.09 516.93 193.27 C 517.29 193.45 517.67 193.2 517.9 192.62 Z" fill="#697079" stroke="#697079" stroke-width="0.46" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;rect x="505" y="159.91" width="0" height="0" fill="none" stroke="none" pointer-events="all"/&gt;&lt;path d="M 529.43 191.24 L 527.6 160.44 L 530.04 159.91 L 532.1 161.97 C 532.63 161.92 533.17 161.94 533.7 162.05 L 534.47 160.52 L 536.76 160.06 L 538.44 161.09 L 538.93 164.57 C 539.89 165.45 540.74 166.62 541.41 168.01 L 543.7 168.51 L 544.39 170.61 L 543.17 173.44 C 543.41 174.93 543.49 176.48 543.4 178.02 L 545 180.55 L 544.54 183.3 L 542.25 183.83 C 541.71 184.9 541.06 185.83 540.34 186.58 L 540.34 190.14 L 538.89 191.02 L 536.3 191.4 L 533.78 187.88 L 531.26 191.32 Z M 534.24 176.42 L 533.55 173.59 C 533.31 173.4 533.04 173.52 532.84 173.92 C 532.64 174.32 532.53 174.94 532.56 175.58 C 532.63 176.31 532.9 176.89 533.26 177.07 C 533.62 177.25 534 177 534.24 176.42 Z" fill="#697079" stroke="#697079" stroke-width="0.46" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;path d="M 529.43 191.24 L 527.9 190.48 L 527.52 186.93 C 526.49 186.07 525.58 184.89 524.85 183.45 L 522.63 183.07 L 521.79 180.77 L 523.24 177.95 C 522.97 176.43 522.87 174.86 522.94 173.28 L 521.34 170.69 L 521.79 168.47 L 524.08 168.13 C 524.63 166.9 525.3 165.83 526.07 164.95 L 526.07 161.51 L 527.6 160.44 L 529.27 162.58 C 530.33 162.26 531.42 162.26 532.48 162.58 L 534.47 160.52 L 535.99 161.44 L 536.22 164.8 C 537.17 165.7 538 166.9 538.66 168.32 L 541.03 168.7 L 541.87 171.07 L 540.57 173.82 C 540.82 175.34 540.9 176.92 540.8 178.48 L 542.56 181.31 L 542.02 183.91 L 539.81 183.91 C 539.24 185.16 538.55 186.25 537.75 187.12 L 537.67 190.71 L 536.22 191.4 L 534.16 189.03 C 533.18 189.36 532.17 189.41 531.18 189.18 Z M 532.02 178.94 C 532.55 178.94 533.05 178.6 533.41 177.99 C 533.77 177.38 533.96 176.57 533.93 175.73 C 533.75 174.32 532.73 173.24 531.49 173.13 C 531 173.07 530.52 173.37 530.21 173.93 C 529.89 174.49 529.77 175.25 529.89 175.96 C 529.91 177.54 530.84 178.84 532.02 178.94" fill="#c0c6d2" stroke="#697079" stroke-width="0.46" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;path d="M 513.09 207.45 L 511.56 206.68 L 511.18 203.13 C 510.15 202.28 509.24 201.09 508.51 199.65 L 506.3 199.27 L 505.46 196.98 L 506.91 194.15 C 506.64 192.64 506.53 191.06 506.6 189.49 L 505 186.89 L 505.46 184.67 L 507.75 184.33 C 508.29 183.1 508.96 182.03 509.73 181.16 L 509.73 177.72 L 511.26 176.65 L 512.94 178.79 C 514 178.46 515.09 178.46 516.15 178.79 L 518.13 176.72 L 519.66 177.64 L 519.89 181 C 520.84 181.91 521.67 183.1 522.33 184.52 L 524.69 184.9 L 525.53 187.27 L 524.24 190.02 C 524.48 191.54 524.56 193.12 524.47 194.68 L 526.22 197.51 L 525.69 200.11 L 523.47 200.11 C 522.91 201.36 522.21 202.45 521.41 203.32 L 521.34 206.91 L 519.89 207.6 L 517.82 205.23 C 516.85 205.56 515.84 205.62 514.85 205.38 Z M 515.69 195.14 C 516.21 195.14 516.71 194.8 517.07 194.19 C 517.43 193.59 517.62 192.77 517.6 191.93 C 517.41 190.52 516.4 189.44 515.15 189.33 C 514.66 189.28 514.19 189.57 513.87 190.13 C 513.55 190.69 513.43 191.45 513.55 192.16 C 513.58 193.74 514.5 195.04 515.69 195.14" fill="#c0c6d2" stroke="#697079" stroke-width="0.46" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;path d="M 530.06 204.96 L 529.21 190.65 L 530.34 190.4 L 531.3 191.36 C 531.55 191.34 531.8 191.35 532.04 191.4 L 532.4 190.69 L 533.46 190.48 L 534.24 190.95 L 534.47 192.57 C 534.92 192.98 535.31 193.52 535.62 194.17 L 536.69 194.4 L 537.01 195.38 L 536.44 196.69 C 536.55 197.38 536.59 198.1 536.55 198.82 L 537.29 199.99 L 537.08 201.27 L 536.02 201.52 C 535.76 202.01 535.46 202.44 535.13 202.79 L 535.13 204.44 L 534.45 204.85 L 533.25 205.03 L 532.08 203.4 L 530.91 204.99 Z Z M 532.29 198.07 L 531.97 196.76 C 531.6 196.9 531.4 197.3 531.51 197.68 C 531.7 198.03 532 198.18 532.29 198.07 Z" fill="#697079" stroke="#697079" stroke-width="0.46" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;path d="M 530.06 204.96 L 529.35 204.6 L 529.17 202.95 C 528.69 202.56 528.27 202.01 527.93 201.34 L 526.9 201.16 L 526.51 200.09 L 527.18 198.78 C 527.06 198.08 527.01 197.35 527.04 196.62 L 526.3 195.41 L 526.51 194.38 L 527.57 194.22 C 527.83 193.65 528.14 193.15 528.5 192.75 L 528.5 191.15 L 529.21 190.65 L 529.98 191.65 C 530.48 191.49 530.98 191.49 531.47 191.65 L 532.4 190.69 L 533.11 191.11 L 533.21 192.68 C 533.66 193.1 534.04 193.65 534.35 194.31 L 535.45 194.49 L 535.84 195.59 L 535.23 196.87 C 535.35 197.57 535.38 198.31 535.34 199.03 L 536.16 200.34 L 535.91 201.55 L 534.88 201.55 C 534.61 202.13 534.29 202.64 533.92 203.04 L 533.89 204.71 L 533.21 205.03 L 532.26 203.93 C 531.8 204.09 531.33 204.11 530.87 204 Z M 531.26 199.24 C 531.54 199.3 531.82 199.16 532 198.85 C 532.18 198.55 532.24 198.13 532.15 197.75 C 532.03 197.04 531.56 196.54 531.02 196.54 C 530.8 196.55 530.59 196.7 530.44 196.95 C 530.3 197.2 530.24 197.53 530.27 197.86 C 530.32 198.57 530.73 199.15 531.26 199.24 Z" fill="#c0c6d2" stroke="#697079" stroke-width="0.46" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 215px; margin-left: 525px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"&gt;SSHD&lt;br /&gt;Process&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="525" y="227" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;SSHD&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 195 204.89 L 195 169.8 L 213.58 165.22 L 229.15 169.93 L 229.15 205.42 L 210.83 209.74 Z" fill="#abb4c5" stroke="none" pointer-events="all"/&gt;&lt;path d="M 195 169.8 L 213.58 165.22 L 229.15 169.93 L 210.83 174.39 Z" fill="#b8bfd1" stroke="none" pointer-events="all"/&gt;&lt;path d="M 210.83 174.39 L 229.15 169.93 L 229.15 205.42 L 210.83 209.74 Z" fill="#5b6369" stroke="none" pointer-events="all"/&gt;&lt;path d="M 211.02 193.68 C 207.61 192.37 204.34 190.7 201.28 188.71 C 199.81 187.69 198.56 186.38 197.62 184.86 C 196.97 183.67 196.63 182.34 196.65 180.98 C 196.59 179.53 196.62 178.07 196.73 176.61 C 196.8 175.31 196.94 174.02 197.15 172.74 C 197.34 172.03 197.63 171.35 198.01 170.72 C 198.8 170.18 199.71 169.74 200.68 169.41 C 202.34 168.85 204.02 168.36 205.73 167.97 C 207.51 167.49 209.32 167.14 211.15 166.92 C 212.39 166.77 213.64 166.72 214.89 166.79 C 216.92 166.94 218.92 167.38 220.83 168.1 L 227.03 170.38 C 227.58 171.28 227.93 172.29 228.08 173.34 C 228.25 174.75 228.35 176.16 228.37 177.58 C 228.47 180.71 228.38 183.84 228.1 186.95 C 228.07 188.33 227.6 189.66 226.77 190.75 C 225.56 192.09 223.92 192.97 222.14 193.24 C 220.71 193.46 219.27 193.57 217.82 193.55 Z" fill-opacity="0.4" fill="#ffffff" stroke="none" pointer-events="all"/&gt;&lt;rect x="195" y="165.22" width="0" height="0" fill="none" stroke="none" pointer-events="all"/&gt;&lt;path d="M 196.83 175.17 L 196.83 174.25 L 208.74 177.92 L 208.74 178.84 Z M 198.79 202.93 L 198.79 202.01 L 206.12 204.11 L 206.12 205.02 Z" fill="#52595e" stroke="none" pointer-events="all"/&gt;&lt;path d="M 195 204.89 L 195 169.8 L 213.58 165.22 L 229.15 169.93 L 229.15 205.42 L 210.83 209.74 Z" fill="none" stroke="#000000" stroke-width="0.31" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;rect x="195" y="165.22" width="0" height="0" fill="none" stroke="none" pointer-events="all"/&gt;&lt;ellipse cx="224.81" cy="202.43" rx="9.839712136081127" ry="9.846174392076122" fill="#008cce" stroke="none" pointer-events="all"/&gt;&lt;path d="M 218.09 195.38 C 218.19 195.65 218.32 195.91 218.49 196.15 C 218.76 196.18 219.02 196.26 219.26 196.4 C 219.2 196.67 219.31 196.96 219.55 197.11 C 219.74 197.22 219.86 197.4 219.89 197.61 C 219.9 197.72 219.95 197.82 220.03 197.88 C 220.11 197.95 220.21 197.99 220.32 197.98 C 220.44 197.96 220.56 197.95 220.69 197.95 C 220.95 197.92 221.22 197.97 221.45 198.11 L 222.28 198.71 C 222.41 198.8 222.51 198.94 222.55 199.1 C 222.59 199.25 222.59 199.41 222.55 199.56 C 222.48 199.58 222.41 199.57 222.35 199.54 C 222.3 199.41 222.2 199.3 222.08 199.24 C 221.92 199.18 221.74 199.18 221.58 199.24 C 221.37 199.36 221.12 199.4 220.88 199.36 C 220.68 199.37 220.5 199.47 220.38 199.63 C 220.29 199.76 220.14 199.84 219.98 199.86 C 219.82 199.87 219.67 199.81 219.55 199.69 C 219.46 199.56 219.3 199.49 219.13 199.51 C 218.97 199.52 218.83 199.62 218.76 199.77 C 218.67 199.96 218.62 200.17 218.6 200.37 C 218.6 200.64 218.55 200.91 218.45 201.16 C 218.4 201.29 218.3 201.39 218.18 201.46 C 217.99 201.52 217.87 201.7 217.89 201.9 C 218.05 202.09 218.17 202.3 218.25 202.53 C 218.32 202.67 218.27 202.84 218.12 202.93 C 217.97 203.05 217.9 203.24 217.93 203.43 C 217.7 203.44 217.47 203.4 217.25 203.33 C 217.17 203.22 217.05 203.14 216.92 203.1 C 216.8 203.07 216.67 203.12 216.59 203.22 C 216.44 203.43 216.33 203.67 216.27 203.93 C 216.22 204.1 216.19 204.28 216.19 204.46 C 216.36 204.78 216.45 205.13 216.43 205.5 L 216.56 206.56 C 216.57 206.7 216.54 206.84 216.46 206.96 C 216.38 207.07 216.27 207.14 216.14 207.18 C 214.05 203.26 214.84 198.43 218.08 195.38 Z" fill="#00527f" stroke="none" pointer-events="all"/&gt;&lt;path d="M 230.12 194.25 C 230.08 194.4 229.99 194.53 229.86 194.61 C 229.74 194.66 229.61 194.69 229.49 194.69 L 228.76 194.78 C 228.44 194.75 228.12 194.78 227.82 194.89 C 227.85 194.99 227.81 195.11 227.72 195.17 C 227.64 195.23 227.52 195.24 227.43 195.18 C 227.24 195.19 227.06 195.27 226.93 195.41 C 226.84 195.52 226.71 195.59 226.56 195.61 C 226.36 195.65 226.19 195.78 226.1 195.97 C 226.01 196.13 225.85 196.16 225.74 196.05 C 225.67 195.9 225.62 195.74 225.61 195.58 C 225.48 195.27 225.24 195.01 224.94 194.85 C 224.64 194.72 224.35 194.54 224.1 194.32 C 223.94 194.2 223.84 194.01 223.84 193.81 C 223.83 193.69 223.84 193.57 223.88 193.45 C 223.78 193.25 223.57 193.1 223.34 193.08 C 223.17 193.04 223.03 192.91 222.97 192.75 C 225.5 192.28 228.12 192.82 230.26 194.25 Z" fill="#64aadc" stroke="none" pointer-events="all"/&gt;&lt;path d="M 234.25 205.1 C 234.22 204.79 234.1 204.5 233.91 204.26 C 233.71 204.24 233.51 204.34 233.41 204.52 C 233.25 204.76 233 204.92 232.72 204.96 C 232.52 204.74 232.56 204.44 232.81 204.26 C 232.97 204.02 233.01 203.71 232.92 203.43 C 232.9 203.31 232.85 203.2 232.79 203.1 C 232.6 202.91 232.46 202.69 232.39 202.43 C 232.21 202.55 232 202.53 231.84 202.39 C 231.68 202.25 231.59 202.01 231.61 201.77 C 231.62 201.48 231.52 201.21 231.32 201 C 231.34 200.54 231.2 200.1 230.92 199.73 C 230.65 199.46 230.28 199.29 229.89 199.27 C 229.56 199.27 229.29 199.08 229.28 198.83 C 229.27 198.59 229.53 198.38 229.86 198.38 C 230.36 198.43 230.86 198.42 231.35 198.34 C 231.83 198.28 232.29 198.13 232.72 197.91 L 233.18 197.27 C 234.61 199.62 235 202.45 234.25 205.1 Z" fill="#0a79b9" stroke="none" pointer-events="all"/&gt;&lt;path d="M 233.25 207.56 C 233.02 207.84 232.72 208.06 232.39 208.18 C 232.12 208.26 231.93 208.5 231.92 208.78 C 231.89 208.88 231.86 208.83 231.84 208.64 C 231.81 208.45 231.79 208.14 231.79 207.78 C 231.83 207.45 231.95 207.13 232.15 206.85 C 232.36 206.65 232.55 206.43 232.72 206.19 C 232.78 206.09 232.78 205.97 232.72 205.87 C 232.66 205.77 232.55 205.72 232.44 205.73 C 232.32 205.74 232.23 205.81 232.19 205.92 C 231.94 206.21 231.72 206.52 231.52 206.85 C 231.2 207.34 230.73 207.54 230.28 207.39 C 230.02 207.25 229.72 207.19 229.42 207.18 C 229.24 207.25 229.13 207.37 229.12 207.49 C 229.11 207.62 229.19 207.74 229.36 207.82 C 229.6 207.9 229.82 208.07 229.95 208.29 C 230.16 208.65 229.74 209.01 228.93 209.18 C 228.37 209.2 227.82 209.3 227.29 209.49 C 226.99 209.77 226.78 210.14 226.69 210.55 C 226.6 210.73 226.1 210.87 225.5 210.88 C 225.07 210.82 224.63 210.84 224.21 210.95 C 223.86 211.08 223.46 211.01 223.17 210.78 C 223.1 210.64 222.96 210.55 222.81 210.54 C 222.65 210.53 222.5 210.61 222.42 210.74 C 222.34 210.87 222.34 211.04 222.41 211.18 C 222.55 211.42 222.83 211.56 223.1 211.51 C 223.3 211.4 223.56 211.35 223.81 211.38 C 223.96 211.41 224.09 211.5 224.14 211.61 C 224.23 211.69 224.4 211.74 224.62 211.77 C 224.83 211.79 225.07 211.79 225.27 211.75 C 225.6 211.65 226.02 211.59 226.47 211.58 C 226.78 211.55 227.08 211.51 227.33 211.44 C 227.58 211.26 227.89 211.16 228.2 211.18 C 228.37 211.14 228.51 211.09 228.6 211.04 C 228.72 210.95 228.87 210.9 229.02 210.91 C 229.1 210.97 229.13 211.07 229.09 211.15 C 228.99 211.29 228.86 211.42 228.73 211.52 C 230.61 210.71 232.19 209.32 233.25 207.56 Z" fill="#266792" stroke="none" pointer-events="all"/&gt;&lt;ellipse cx="224.21" cy="198.24" rx="7.114164213280995" ry="4.923087196038061" fill-opacity="0.3" fill="#ffffff" stroke="none" pointer-events="all"/&gt;&lt;ellipse cx="220.96" cy="197.31" rx="2.0608439646712466" ry="1.5018034611318236" fill-opacity="0.4" fill="#ffffff" stroke="none" pointer-events="all"/&gt;&lt;rect x="195" y="165.22" width="0" height="0" fill="none" stroke="none" pointer-events="all"/&gt;&lt;ellipse cx="224.81" cy="202.43" rx="9.839712136081127" ry="9.846174392076122" fill="none" stroke="#000000" stroke-width="0.25" pointer-events="all"/&gt;&lt;rect x="195" y="165.22" width="0" height="0" fill="none" stroke="none" pointer-events="all"/&gt;&lt;path d="M 219.46 209.2 L 219.46 200.52 L 221.53 199.95 L 221.53 193.72 L 222.48 193.41 L 227.82 195.04 L 227.82 200.96 L 229.64 201.46 L 229.64 210.39 L 226 211.27 Z M 223.29 199.57 L 226.12 200.45 L 226.12 195.86 L 223.29 195.04 Z" fill="#a3acbd" stroke="none" pointer-events="all"/&gt;&lt;path d="M 229.64 201.46 L 226.06 202.34 L 219.46 200.52 L 222.98 199.51 Z" fill="#b2b9ca" stroke="none" pointer-events="all"/&gt;&lt;path d="M 229.64 210.39 L 226.06 211.27 L 226.06 202.34 L 229.64 201.46 Z" fill="#5b6369" stroke="none" pointer-events="all"/&gt;&lt;path d="M 226.06 210.71 L 219.46 208.7 L 219.46 207.88 L 226.06 209.83 L 229.64 208.95 L 229.64 209.83 Z" fill-opacity="0.7" fill="#0378b2" stroke="none" pointer-events="all"/&gt;&lt;rect x="195" y="165.22" width="0" height="0" fill="none" stroke="none" pointer-events="all"/&gt;&lt;path d="M 221.97 205.74 C 221.72 205.54 221.6 205.26 221.66 204.98 C 221.8 204.73 222.02 204.64 222.22 204.76 C 222.47 204.83 222.68 205.07 222.77 205.39 C 222.79 205.57 222.72 205.75 222.56 205.86 L 222.67 207.44 C 222.67 207.54 222.63 207.63 222.56 207.7 C 222.48 207.78 222.39 207.82 222.29 207.82 C 222.12 207.81 221.96 207.75 221.85 207.63 C 221.74 207.51 221.69 207.34 221.72 207.18 Z" fill="#3b393b" stroke="none" pointer-events="all"/&gt;&lt;path d="M 227.82 195.04 L 226.88 195.36 L 221.53 193.79 L 222.48 193.41 Z" fill="#d9dde6" stroke="none" pointer-events="all"/&gt;&lt;path d="M 226.06 203.52 L 219.46 201.65 L 219.46 200.82 L 226.06 202.64 L 229.64 201.76 L 229.64 202.64 Z" fill-opacity="0.7" fill="#0378b2" stroke="none" pointer-events="all"/&gt;&lt;path d="M 220.09 200.71 C 220.45 200.51 220.83 200.37 221.22 200.27 L 223.61 199.69 L 228.39 201.1 C 228.59 201.24 228.76 201.42 228.89 201.62 C 228.97 202.05 228.98 202.48 228.91 202.91 C 228.87 203.97 228.56 205 228.01 205.9 C 227.5 206.44 226.85 206.82 226.12 207 C 225.36 207.3 224.55 207.45 223.73 207.44 C 222.97 207.41 222.23 207.06 221.67 206.43 C 221.09 205.88 220.61 205.21 220.28 204.48 C 220.01 203.82 219.88 203.12 219.9 202.41 C 219.89 201.83 219.95 201.26 220.09 200.71 Z" fill-opacity="0.3" fill="#ffffff" stroke="none" pointer-events="all"/&gt;&lt;rect x="195" y="165.22" width="0" height="0" fill="none" stroke="none" pointer-events="all"/&gt;&lt;path d="M 221.53 193.79 L 226.88 195.36 L 226.88 201.9 L 226.12 201.71 L 226.12 195.86 L 222.41 194.73 L 222.41 200.52 L 221.53 200.27 Z" fill="#9ba5b6" stroke="none" pointer-events="all"/&gt;&lt;path d="M 227.82 195.04 L 227.82 201.65 L 226.88 201.9 L 226.88 195.36 Z" fill="#60686f" stroke="none" pointer-events="all"/&gt;&lt;path d="M 223.29 195.03 L 223.29 200.27 L 222.41 200.52 L 222.41 194.73 Z" fill="#5c6369" stroke="none" pointer-events="all"/&gt;&lt;path d="M 219.46 209.2 L 219.46 200.52 L 221.53 199.95 L 221.53 193.72 L 222.48 193.41 L 227.82 195.04 L 227.82 200.96 L 229.64 201.46 L 229.64 210.39 L 226 211.27 Z M 223.29 199.57 L 226.12 200.45 L 226.12 195.86 L 223.29 195.04 Z" fill="none" stroke="#000000" stroke-width="0.15" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 219px; margin-left: 215px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"&gt;SOCKS5 Proxy&lt;br /&gt;by SSH&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="215" y="231" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;SOCKS5&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="115" y="153.75" width="42.55" height="30" fill="none" stroke="none" pointer-events="all"/&gt;&lt;path d="M 115.06 172.69 L 123.57 172.69 L 123.57 170.76 L 115.06 170.76 Z M 115.06 166.74 L 125.27 166.74 L 125.27 164.81 L 115.06 164.81 Z M 115.06 160.78 L 126.97 160.78 L 126.97 158.85 L 115.06 158.85 Z M 146.63 170.76 L 133.31 170.76 L 134.53 165.89 L 147.85 165.89 Z M 133.02 163.96 L 130.84 172.69 L 148.14 172.69 L 150.32 163.96 Z M 150.07 181.52 C 150.03 181.69 149.88 181.82 149.7 181.82 L 126.09 181.82 C 125.93 181.82 125.83 181.73 125.79 181.68 C 125.74 181.62 125.68 181.51 125.71 181.35 L 130.08 160.74 L 154.48 160.74 Z M 131.47 155.68 L 155.08 155.68 C 155.24 155.68 155.33 155.77 155.38 155.82 C 155.42 155.88 155.49 155.99 155.45 156.15 L 154.89 158.81 L 130.49 158.81 L 131.09 155.99 C 131.13 155.81 131.29 155.68 131.47 155.68 Z M 156.87 154.61 C 156.43 154.06 155.78 153.75 155.08 153.75 L 131.47 153.75 C 130.38 153.75 129.43 154.52 129.2 155.59 L 123.82 180.96 C 123.68 181.64 123.85 182.35 124.29 182.89 C 124.73 183.44 125.38 183.75 126.09 183.75 L 149.7 183.75 C 150.78 183.75 151.73 182.98 151.96 181.92 L 157.34 156.55 C 157.49 155.86 157.32 155.15 156.87 154.61 Z" fill="#b0084d" stroke="none" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 191px; margin-left: 136px;"&gt;&lt;div data-drawio-colors="color: #232F3E; " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(35, 47, 62); line-height: 1.2; pointer-events: all; white-space: nowrap;"&gt;kubectl&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="136" y="203" fill="#232F3E" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;kubectl&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="115" y="240" width="42.55" height="30" fill="none" stroke="none" pointer-events="all"/&gt;&lt;path d="M 115.06 258.94 L 123.57 258.94 L 123.57 257.01 L 115.06 257.01 Z M 115.06 252.99 L 125.27 252.99 L 125.27 251.06 L 115.06 251.06 Z M 115.06 247.03 L 126.97 247.03 L 126.97 245.1 L 115.06 245.1 Z M 146.63 257.01 L 133.31 257.01 L 134.53 252.14 L 147.85 252.14 Z M 133.02 250.21 L 130.84 258.94 L 148.14 258.94 L 150.32 250.21 Z M 150.07 267.77 C 150.03 267.94 149.88 268.07 149.7 268.07 L 126.09 268.07 C 125.93 268.07 125.83 267.98 125.79 267.93 C 125.74 267.87 125.68 267.76 125.71 267.6 L 130.08 246.99 L 154.48 246.99 Z M 131.47 241.93 L 155.08 241.93 C 155.24 241.93 155.33 242.02 155.38 242.07 C 155.42 242.13 155.49 242.24 155.45 242.4 L 154.89 245.06 L 130.49 245.06 L 131.09 242.24 C 131.13 242.06 131.29 241.93 131.47 241.93 Z M 156.87 240.86 C 156.43 240.31 155.78 240 155.08 240 L 131.47 240 C 130.38 240 129.43 240.77 129.2 241.84 L 123.82 267.21 C 123.68 267.89 123.85 268.6 124.29 269.14 C 124.73 269.69 125.38 270 126.09 270 L 149.7 270 C 150.78 270 151.73 269.23 151.96 268.17 L 157.34 242.8 C 157.49 242.11 157.32 241.4 156.87 240.86 Z" fill="#b0084d" stroke="none" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 277px; margin-left: 136px;"&gt;&lt;div data-drawio-colors="color: #232F3E; " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(35, 47, 62); line-height: 1.2; pointer-events: all; white-space: nowrap;"&gt;aws cli&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="136" y="289" fill="#232F3E" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;aws cli&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 545 183.75 L 688.63 183.75" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/&gt;&lt;path d="M 693.88 183.75 L 686.88 187.25 L 688.63 183.75 L 686.88 180.25 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;path d="M 480.7 72.67 L 489.28 72.67 L 489.28 67.89 C 489.28 66.64 488.46 64.69 486.66 64.69 L 483.25 64.69 C 482 64.69 480.7 65.98 480.7 67.89 Z M 475 90 L 475 72.67 L 477.83 72.67 L 477.83 65.36 C 477.83 62.48 479.81 60 482.05 60 L 487.91 60 C 490.18 60 492.13 62.43 492.13 65.49 L 492.13 72.67 L 495 72.67 L 495 90 Z" fill="#d9a741" stroke="none" pointer-events="all"/&gt;&lt;path d="M 489.28 67.89 C 489.28 66.64 488.46 64.69 486.66 64.69 L 483.25 64.69 C 482 64.69 480.7 65.99 480.7 67.89 L 480.7 66.87 C 480.7 65.2 481.77 63.63 483.26 63.63 L 486.75 63.63 C 488.02 63.63 489.28 65.03 489.28 66.82 Z M 475 90 L 475 88.98 L 495 88.98 L 495 90 Z" fill-opacity="0.3" fill="#000000" stroke="none" pointer-events="all"/&gt;&lt;path d="M 47.26 100.88 C 45.95 100.88 45 99.85 45 98.69 L 45 61.03 C 45 59.99 45.83 58.88 47.12 58.88 L 72.84 58.88 C 73.96 58.88 75 59.79 75 61.08 L 75 98.94 C 75 99.94 74.01 100.88 72.82 100.88 Z" fill="#7d7c7c" stroke="none" pointer-events="all"/&gt;&lt;path d="M 75 96.78 L 75 98.94 C 75 99.94 74.01 100.88 72.82 100.88 L 47.26 100.88 C 45.95 100.88 45 99.84 45 98.69 L 45 97.04 C 45 98.19 46.1 99.01 47.09 99.01 L 72.78 99.01 C 73.96 99.01 75 98.07 75 96.78 Z" fill-opacity="0.3" fill="#000000" stroke="none" pointer-events="all"/&gt;&lt;rect x="45" y="58.88" width="0" height="0" fill="none" stroke="rgb(0, 0, 0)" pointer-events="all"/&gt;&lt;path d="M 54.63 66.43 L 48.56 66.43 L 48.56 63.97 L 54.63 63.97 Z M 62.98 66.43 L 56.91 66.43 L 56.91 63.97 L 62.98 63.97 Z M 71.34 66.43 L 65.26 66.43 L 65.26 63.97 L 71.34 63.97 Z M 54.63 70.73 L 48.56 70.73 L 48.56 68.27 L 54.63 68.27 Z M 62.98 70.73 L 56.91 70.73 L 56.91 68.27 L 62.98 68.27 Z M 71.34 70.73 L 65.26 70.73 L 65.26 68.27 L 71.34 68.27 Z M 54.63 75.04 L 48.56 75.04 L 48.56 72.58 L 54.63 72.58 Z M 62.98 75.04 L 56.91 75.04 L 56.91 72.58 L 62.98 72.58 Z M 71.34 75.04 L 65.26 75.04 L 65.26 72.58 L 71.34 72.58 Z M 54.63 79.34 L 48.56 79.34 L 48.56 76.88 L 54.63 76.88 Z M 62.98 79.34 L 56.91 79.34 L 56.91 76.88 L 62.98 76.88 Z M 71.34 79.34 L 65.26 79.34 L 65.26 76.88 L 71.34 76.88 Z M 54.63 83.65 L 48.56 83.65 L 48.56 81.19 L 54.63 81.19 Z M 62.98 83.65 L 56.91 83.65 L 56.91 81.19 L 62.98 81.19 Z M 71.34 83.65 L 65.26 83.65 L 65.26 81.19 L 71.34 81.19 Z M 54.63 87.95 L 48.56 87.95 L 48.56 85.49 L 54.63 85.49 Z M 62.98 87.95 L 56.91 87.95 L 56.91 85.49 L 62.98 85.49 Z M 71.34 87.95 L 65.26 87.95 L 65.26 85.49 L 71.34 85.49 Z" fill="#ffffff" stroke="none" pointer-events="all"/&gt;&lt;path d="M 745.96 76 C 740.09 76 735.55 71.43 735.55 67.19 L 735.55 65.43 C 735.09 60.07 739.29 55.87 742.21 55.04 C 742.04 51.25 743.66 46.93 747.09 44.04 C 752.05 40 757.87 40.62 761.39 42.53 C 763.87 43.81 766.1 46.07 767.39 49.06 C 770.04 47.23 772.87 47.78 774.49 48.73 C 776.67 50.01 777.84 52.28 777.87 54.5 C 780.12 54.75 782.79 55.78 785.11 58.85 C 786.32 60.5 787.06 63.42 787.09 65.17 L 787.09 66.98 C 787.09 71.56 782.32 76 776.7 76 Z" fill="#f58536" stroke="none" pointer-events="all"/&gt;&lt;path d="M 787.09 65.17 L 787.09 66.98 C 787.09 71.55 782.32 76 776.7 76 L 745.96 76 C 740.09 76 735.55 71.42 735.55 67.19 L 735.55 65.43 C 735.55 69.28 739.85 74.11 745.88 74.11 L 776.24 74.11 C 782.68 74.11 787.09 69.52 787.09 65.17 Z" fill-opacity="0.3" fill="#000000" stroke="none" pointer-events="all"/&gt;&lt;rect x="735.09" y="40" width="0" height="0" fill="none" stroke="rgb(0, 0, 0)" pointer-events="all"/&gt;&lt;path d="M 748.15 64.72 L 750.99 64.72 L 749.61 58.59 Z M 750.92 56.94 L 754.14 69.34 L 752.09 69.34 L 751.36 66.32 L 747.85 66.32 L 747.04 69.34 L 744.99 69.34 L 748.43 56.94 Z M 766.29 56.94 L 763.88 69.34 L 761.6 69.34 L 760.03 59.73 L 758.47 69.34 L 756.26 69.34 L 753.92 56.94 L 755.82 56.94 L 757.47 66.81 L 759.04 56.94 L 761.09 56.94 L 762.74 66.88 L 764.32 56.94 Z M 774.58 60.11 L 772.67 60.11 C 772.71 59.17 772.47 58.55 771.87 58.25 C 771.5 58.07 770.71 57.92 770.1 58.29 C 769.77 58.5 769.36 58.89 769.37 59.92 C 769.39 61.23 770.33 61.72 771.25 62.09 C 772.37 62.45 773.36 62.76 774.09 63.47 C 775.22 64.55 775.11 66.27 774.79 67.31 C 774.35 68.59 773.35 69.21 772 69.42 C 770.8 69.56 769.51 69.53 768.56 68.81 C 767.49 67.95 767.29 66.68 767.32 65.41 L 769.23 65.41 C 769.2 66.25 769.31 66.91 769.65 67.33 C 770.17 67.99 771.07 68.09 771.85 67.88 C 772.8 67.58 773.05 66.69 773.02 66.12 C 773.04 65.06 772.51 64.38 771.57 64.06 C 770.04 63.52 768.88 63.28 768.05 62.3 C 767.63 61.82 767.22 60.83 767.46 59.28 C 767.67 57.98 768.53 57.22 769.31 56.9 C 770.4 56.39 772.17 56.46 773.12 56.94 C 774.09 57.39 774.65 58.38 774.58 60.11 Z" fill="#ffffff" stroke="none" pointer-events="all"/&gt;&lt;path d="M 695 163.71 L 735.09 163.71 L 735.09 203.8 L 695 203.8 Z" fill="url(#mx-gradient-f78e04-1-d05c17-1-s-0)" stroke="none" pointer-events="all"/&gt;&lt;path d="M 718.61 179.1 L 714.77 183.55 L 718.95 188.43 L 717.39 188.43 L 713.64 184.05 L 713.64 188.55 L 712.52 188.55 L 712.52 178.99 L 713.64 178.99 L 713.64 182.92 L 717.11 179.1 Z M 728.26 188.12 L 723.76 185.42 L 723.76 178.99 C 723.76 178.79 723.65 178.6 723.48 178.5 L 717.01 174.73 L 717.01 169.29 L 728.26 175.94 Z M 729.11 175.13 L 716.74 167.82 C 716.56 167.72 716.35 167.72 716.17 167.82 C 716 167.92 715.89 168.11 715.89 168.31 L 715.89 175.05 C 715.89 175.25 715.99 175.44 716.17 175.54 L 722.63 179.31 L 722.63 185.74 C 722.63 185.93 722.74 186.12 722.91 186.22 L 728.53 189.59 C 728.62 189.64 728.72 189.67 728.82 189.67 C 728.91 189.67 729.01 189.65 729.1 189.6 C 729.27 189.5 729.38 189.31 729.38 189.11 L 729.38 175.62 C 729.38 175.42 729.28 175.23 729.11 175.13 Z M 715.01 198.59 L 701.83 191.58 L 701.83 175.94 L 713.08 169.29 L 713.08 174.74 L 707.15 178.51 C 706.99 178.62 706.89 178.8 706.89 178.99 L 706.89 188.55 C 706.89 188.76 707.01 188.95 707.2 189.05 L 714.76 192.98 C 714.92 193.07 715.11 193.07 715.28 192.98 L 722.61 189.19 L 727.13 191.9 Z M 728.55 191.44 L 722.92 188.06 C 722.76 187.96 722.55 187.96 722.38 188.05 L 715.02 191.85 L 708.02 188.21 L 708.02 179.3 L 713.94 175.53 C 714.1 175.42 714.2 175.25 714.2 175.05 L 714.2 168.31 C 714.2 168.11 714.09 167.92 713.92 167.82 C 713.74 167.72 713.53 167.72 713.35 167.82 L 700.98 175.13 C 700.81 175.23 700.71 175.42 700.71 175.62 L 700.71 191.92 C 700.71 192.13 700.82 192.32 701.01 192.42 L 714.75 199.73 C 714.84 199.77 714.93 199.79 715.02 199.79 C 715.11 199.79 715.21 199.77 715.29 199.72 L 728.53 192.41 C 728.71 192.31 728.82 192.13 728.82 191.93 C 728.82 191.73 728.72 191.54 728.55 191.44 Z" fill="#ffffff" stroke="none" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 184px; margin-left: 737px;"&gt;&lt;div data-drawio-colors="color: #232F3E; " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(35, 47, 62); line-height: 1.2; pointer-events: all; white-space: nowrap;"&gt;EKS&lt;br /&gt;Cluster&lt;br /&gt;Endpoint&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="737" y="187" fill="#232F3E" font-family="Helvetica" font-size="12px"&gt;EKS&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 525.02 456 C 511.25 456 500 444.6 500 431.53 L 500 428.52 C 500 415.94 510.46 404 524.91 404 C 539.69 404 550 415.94 550 428.72 L 550 431.14 C 550 444.73 538.98 456 525.02 456 Z" fill="#f58534" stroke="none" pointer-events="all"/&gt;&lt;path d="M 500 428.52 C 500 443.8 512.18 453.86 524.95 453.86 C 539.44 453.86 550 442.07 550 428.72 L 550 431.14 C 550 444.76 538.98 456 525.02 456 C 511.14 456 500 444.59 500 431.53 Z" fill-opacity="0.3" fill="#000000" stroke="none" pointer-events="all"/&gt;&lt;rect x="500" y="404" width="0" height="0" fill="none" stroke="rgb(0, 0, 0)" pointer-events="all"/&gt;&lt;path d="M 513.25 429.26 C 515.12 436.4 519.07 442.04 525 444.99 C 528.79 443.32 531.86 439.82 533.52 437.03 C 536.51 432.03 537.91 426.02 537.97 419.67 C 536.39 419.48 534.76 418.95 533.83 418.06 C 533 417.31 532.14 415.84 531.81 414 C 529.38 413.22 526.9 412.74 524.75 412.78 C 522.25 412.87 520.14 413.42 518.33 414 C 518.08 415.61 517.25 417.28 516.28 418.08 C 515.03 419.12 513.52 419.53 512.01 419.74 C 512.02 421.85 512.25 424.14 512.62 426.3 L 524.75 426.3 L 524.75 421.46 L 532.48 427.86 L 524.75 434.18 L 524.75 429.26 Z M 504.85 429.26 L 504.85 426.3 L 510.15 426.3 C 509.67 423.41 509.5 420.39 509.54 417.44 C 511.74 417.55 513.73 417.13 514.61 416.23 C 515.54 415.24 515.82 413.79 515.95 412.36 C 518.5 411.29 521.71 410.43 524.64 410.4 C 527.82 410.32 530.93 411.13 534.05 412.19 C 534.21 414.49 534.9 415.95 535.94 416.49 C 537.29 417.12 538.95 417.22 540.45 417.27 C 540.45 425.99 539.22 431.56 536 437.45 C 533.77 441.47 530.08 445.42 524.99 447.55 C 520.99 446.01 517.2 442.74 514.59 438.57 C 512.83 435.81 511.5 432.53 510.75 429.26 Z" fill="#ffffff" stroke="none" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-start; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 463px; margin-left: 525px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: nowrap;"&gt;AWS Service Endpoint&lt;br /&gt;https://eks.us-west-2.amazonaws.com&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="525" y="475" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;AWS Serv&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 157.49 255 L 230 255 L 230 430 L 493.63 430" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/&gt;&lt;path d="M 498.88 430 L 491.88 433.5 L 493.63 430 L 491.88 426.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;path d="M 157.49 174.14 L 188.83 182.1" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke"/&gt;&lt;path d="M 193.92 183.39 L 186.27 185.06 L 188.83 182.1 L 187.99 178.28 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;path d="M 290 410 C 266 410 260 430 279.2 434 C 260 442.8 281.6 462 297.2 454 C 308 470 344 470 356 454 C 380 454 380 438 365 430 C 380 414 356 398 335 406 C 320 394 296 394 290 410 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 430px; margin-left: 261px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;"&gt;&lt;div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"&gt;Internet&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="320" y="434" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle"&gt;Internet&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;rect x="0" y="390" width="210" height="110" fill="none" stroke="none" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 208px; height: 1px; padding-top: 445px; margin-left: 2px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"&gt;Note: kubectl calls aws-cli for authentication. So make sure that aws-cli uses the right profile and assumes the right role, if applicable.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="2" y="449" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="14px"&gt;Note: kubectl calls aws-cli fo&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 115.06 168.81 L 50 169 L 52.43 383.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="8 8" pointer-events="stroke"/&gt;&lt;path d="M 52.49 388.88 L 48.91 381.92 L 52.43 383.63 L 55.91 381.84 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;path d="M 356.25 193.75 L 359.36 333.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="8 8" pointer-events="stroke"/&gt;&lt;path d="M 359.48 338.88 L 355.82 331.96 L 359.36 333.63 L 362.82 331.81 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;rect x="286" y="340" width="294" height="40" fill="none" stroke="none" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 292px; height: 1px; padding-top: 360px; margin-left: 288px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"&gt;The SSH Tunnel is established on top of a proxy command using SSM session manager or EC2 Instance Connect with EIC Endpoint&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="288" y="364" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="14px"&gt;The SSH Tunnel is established on top of a&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;path d="M 215.45 165.22 L 217.38 65.25" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" stroke-dasharray="3 3" pointer-events="stroke"/&gt;&lt;path d="M 217.48 60 L 220.84 67.06 L 217.38 65.25 L 213.84 66.93 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all"/&gt;&lt;rect x="150" y="8.88" width="270" height="50" fill="none" stroke="none" pointer-events="all"/&gt;&lt;g transform="translate(-0.5 -0.5)"&gt;&lt;switch&gt;&lt;foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;"&gt;&lt;div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe flex-start; width: 268px; height: 1px; padding-top: 34px; margin-left: 152px;"&gt;&lt;div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: left;"&gt;&lt;div style="display: inline-block; font-size: 14px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;"&gt;Tell kubectl to use SOCKS5 proxy by the HTTPS_PROXY environment variable or by the proxy-url attribute in .kube/config&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/foreignObject&gt;&lt;text x="152" y="38" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="14px"&gt;Tell kubectl to use SOCKS5 proxy by th&amp;#8230;&lt;/text&gt;&lt;/switch&gt;&lt;/g&gt;&lt;/g&gt;&lt;switch&gt;&lt;g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/&gt;&lt;a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank" rel="noopener"&gt;&lt;text text-anchor="middle" font-size="10px" x="50%" y="100%"&gt;Text is not SVG &amp;#8211; cannot display&lt;/text&gt;&lt;/a&gt;&lt;/switch&gt;&lt;/svg&gt;&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;To put this in practice, I first created a VPC stack with a bastion host using terraform template from my &lt;a href="https://github.com/digihunch/vpc-base/tree/main"&gt;vpc-base&lt;/a&gt; project. The terraform output will give the next set of commands to run to create a private cluster, using a manifest rendered from the file &lt;a href="https://github.com/digihunch/vpc-base/blob/main/template/eksctl.tpl"&gt;private-cluster.yaml.tmpl&lt;/a&gt;:&lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# cd aws_vpc&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# terraform init&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# terraform plan&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# terraform apply&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# ... run the given command ...&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# envsubst &amp;lt; private-cluster.yaml.tmpl | tee | eksctl create cluster -f -&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Run this from a remote host without access to cluster endpoint.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Run terraform apply and terraform output contains the variables needed for the next steps&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# the command below may take 15 minutes to create a private cluster&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;eksctl create cluster -f private-cluster.yaml &#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;aws eks update-kubeconfig --name private-cluster&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;At this point, the kubeconfig file has been updated, but kubectl (from Internet or on-prem) is unable to connect to cluster endpoint (on private network). In order to &lt;/p&gt;&#10;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;BASTION_SECURITY_GROUP_ID&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;terraform output -raw bastion_sg_id&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;CLUSTER_SECURITY_GROUP_ID&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;aws eks describe-cluster --name private-cluster --query &lt;span style="color:#e6db74"&gt;&amp;#34;cluster.resourcesVpcConfig.clusterSecurityGroupId&amp;#34;&lt;/span&gt; --output text&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# In Cluster Endpoint&amp;#39;s security group, open up port 443 to Bastion host&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;aws ec2 authorize-security-group-ingress --group-id $CLUSTER_SECURITY_GROUP_ID --source-group $BASTION_SECURITY_GROUP_ID --protocol tcp --port &lt;span style="color:#ae81ff"&gt;443&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# Test with connecting to Bastion host with ssh i-0750643179667a5b6, assuming .ssh/config file is configured as above. From the bastion host, you can test:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# curl -k https://EC5405EE1846F19F9F61ED28FB12A6A9.sk1.us-west-2.eks.amazonaws.com/api &lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# if you get an HTTP response, even an error code 403, the bastion host has TCP connectivity to cluster endpoint&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# then we can start an SSH session as a SOCKS5 proxy on the remote host&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ssh -D &lt;span style="color:#ae81ff"&gt;1080&lt;/span&gt; -q -N i-0750643179667a5b6&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# add &amp;gt; /dev/null 2&amp;gt;&amp;amp;1 &amp;amp; to push it to background, or use ctrl+z after running the command&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# to validate that the SOCKS5 proxy is working, you can run the same curl command with a proxy parameter:&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# curl -k https://EC5405EE1846F19F9F61ED28FB12A6A9.sk1.us-west-2.eks.amazonaws.com/api --proxy socks5://localhost:1080&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# you can instruct kubectl to use the SOCKS5 proxy with the following environment variable&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;export HTTPS_PROXY&lt;span style="color:#f92672"&gt;=&lt;/span&gt;socks5://localhost:1080&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;kubectl get node&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# alternatively, add &amp;#34;proxy-url: socks5://localhost:1080&amp;#34; below server attribute in ~/.kube/config file.&lt;/span&gt;&#10;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p class="wp-block-paragraph"&gt;There are some pitfalls to watch for. On the remote host both ssh command and kubectl command implicitly uses AWS CLI. Therefore, make sure the profile and IAM role are correctly configured. For example, if SSM agent requires one IAM role, and kubectl is created with another IAM role, then make sure AWS CLI &lt;a href="https://repost.aws/knowledge-center/iam-assume-role-cli"&gt;assumes the correct IAM role&lt;/a&gt; using environment variables, and use &amp;#8220;aws sts get-caller-identity&amp;#8221; to validate the IAM identity being used.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;What about AKS in Azure&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;I touched on this in my &lt;a href="https://static.digihunch.com/2021/10/notes-on-azure/"&gt;Azure notes&lt;/a&gt; in 2021 and did a research again. Unfortunately, options are still fairly limited. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The first option is to use a managed service called &amp;#8220;Azure Bastion&amp;#8221;, which requires public IP and a dedicated subnet with the exact name of AzureBastionSubnet, as well as some &lt;a href="https://learn.microsoft.com/en-us/azure/bastion/configuration-settings#subnet"&gt;additional requirement&lt;/a&gt;. I&amp;#8217;m not impressed with these requirement because it is meant to be a managed service. The other option, is essentially to DIY a JumpBox. The idea is the same: put the jumpbox in a public subnet, which is routable to private subnets. When you need to connect to private VMs, get to the jumpbox first.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Apart from having to put the bastion VM on a public subnet, the pattern that we discussed above involving SOCKS5 proxy still works. Exposing a bastion host isn&amp;#8217;t ideal but it still reduces attack surface significantly, comparing to exposing the cluster endpoints of all Kubernetes API servers.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Summary&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Many immature Kubernetes configurations exposes private endpoint publicly. Having cluster endpoint in private subnet greatly improves security posture. In my opinion, there are very few situations where cluster endpoint must exposed publicly. Having private endpoint should be mandatory for all Kubernetes cluster. In the next &lt;a href="https://static.digihunch.com/2023/06/kubernetes-paas-and-red-hat-openshift/"&gt;post&lt;/a&gt;, I also cover how to create a ROSA cluster with private endpoint.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2023/05/kubernetes-with-multiple-cpu-architectures/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Kubernetes with Multiple CPU Architectures 2 of 2 – Node and Workload&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2023/06/kubernetes-paas-and-red-hat-openshift/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Kubernetes Platform as a Service and Red Hat OpenShift&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item><item><title>Landing Zone in Azure – Introduction</title><link>https://static.digihunch.com/2023/03/landing-zone-in-azure/</link><pubDate>Sat, 25 Mar 2023 01:30:00 -0400</pubDate><guid>https://static.digihunch.com/2023/03/landing-zone-in-azure/</guid><description>&lt;img src="https://static.digihunch.com/wp-content/uploads/2025/04/feature-az-lz.webp" alt="Featured image of post Landing Zone in Azure – Introduction" /&gt;&lt;p class="wp-block-paragraph"&gt;I recently renewed my associate administrator certification, and feel it&amp;#8217;s a good opportunity to brush up on Azure landing zone. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The lame part of this is the semantics. I found many similar terms across cloud service provider (CSPs). In the context of Azure, it makes sense to clarify the terms again for Cloud Adoption Framework (CAF) and Cloud Operating Models.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading" id="h-cloud-adoption-framework-caf"&gt;Cloud Adoption Framework (CAF)&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Similar to AWS Cloud Adoption Framework (CAF), Azure also has the concept of CAF and it means the same thing. This part may feel lofty, but it&amp;#8217;s in fact foundational. To get started on the cloud there are thousand ways to configure the foundation (right or wrong). The adopter needs CAF to navigate through the offerings and define what they can achieve. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/"&gt;CAF&lt;/a&gt; documentation is good although length. The most &amp;#8220;beefy&amp;#8221; part is &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/"&gt;Ready&lt;/a&gt; section. &lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Cloud Operating Models&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Every cloud company has some narrative about cloud operating model. For example, Here&amp;#8217;s &lt;a href="https://developer.hashicorp.com/well-architected-framework/com/cloud-operating-model"&gt;Hashicorp&amp;#8217;s&lt;/a&gt; definition, and here&amp;#8217;s &lt;a href="https://docs.aws.amazon.com/whitepapers/latest/building-cloud-operating-model/building-cloud-operating-model.html"&gt;AWS&lt;/a&gt;&amp;#8216; white paper on it. In the context of Azure, the CAF document gives some guidance on developing your own operating model in alignment with the CAF. In addition, it also gives a few example cloud operating models:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Decentralized operations&lt;/li&gt;&#10;&lt;li&gt;Centralized operations&lt;/li&gt;&#10;&lt;li&gt;Enterprise operations&lt;/li&gt;&#10;&lt;li&gt;Distributed operations&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;There is a &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/operating-model/compare#priorities-or-scope"&gt;comparison table&lt;/a&gt; that highlights their differences as well as an &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/operating-model/compare#accountability-alignment"&gt;accountability chart&lt;/a&gt; proposing team divisions. Another &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/operating-model/compare#accelerate-operating-model-implementation-in-azure"&gt;insightful table&lt;/a&gt; is the one that list out implementation starting point and typical path of iterations for each operating model. The table also suggests that Azure Landing Zone includes two implementation options: starting small and CAF enterprise-scale.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Landing Zone at High Level&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Followed by Cloud Operating Model is the design and implementation of Azure Landing Zone. There are currently eight design areas:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Billing and Active Directory tenant: including Azure AD tenant&lt;/li&gt;&#10;&lt;li&gt;Identity and Access Management: including hybrid identity&lt;/li&gt;&#10;&lt;li&gt;Network Topology and Connectivity&lt;/li&gt;&#10;&lt;li&gt;Resource Organization: different levels of resource containers&lt;/li&gt;&#10;&lt;li&gt;Security&lt;/li&gt;&#10;&lt;li&gt;Management&lt;/li&gt;&#10;&lt;li&gt;Governance&lt;/li&gt;&#10;&lt;li&gt;Platform automation and DevOps&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Out of the many design areas, I fell short off IAM and Network so I&amp;#8217;ll try to discuss them in more details below in the next section. As for resource organization, apart from Resource Group and Subscription, it is also important to understand management group.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Most cloud engineers work with subscription and resource group. That is where a lot are going on. For enterprises however, Azure has to address the requirement for the capability of top-down enforcement. Management Group provides a governance scope above subscriptions, provided that all subscriptions trust a single Azure AD account. Management groups may form a hierarchy of up to six levels to help you configure policies and access, so that the all the subscriptions under each management group have unified policy and access configuration. At the very top is root management group. Any assignment of user access or policy on the root management group applies to all resources within the directory. Because of this, all customers should evaluate the need to have items defined on this scope.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We can apply policy guardrails (e.g Azure Policy) at management group level so that the policies are effect across subscriptions. Azure Policy can also address operational compliance considerations by &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/management-operational-compliance#monitor-for-configuration-drift"&gt;monitoring configuration drift&lt;/a&gt;.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Identity and Access Management&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;First, we really need to distinguish &lt;strong&gt;AD DS on Windows Server&lt;/strong&gt;, &lt;strong&gt;Azure AD&lt;/strong&gt; and &lt;strong&gt;Azure AD DS&lt;/strong&gt;. In an &lt;a href="https://static.digihunch.com/2020/02/everything-about-the-domain/"&gt;old post&lt;/a&gt;, I discussed what is a Windows domain, the key role of a domain controller (to manage user identity, as well computer identity), and the fact that Active Directory is a complete redesign of Windows Domain system since Windows 2000. So we can start with AD DS on Windows Server:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;&lt;strong&gt;AD DS on Windows Server&lt;/strong&gt;: In the good old days, some common network administrative activities were to configure Active Directory (including the X.500 compatible database, the OUs, domains and forests) on Windows Servers, joining computers to the company&amp;#8217;s domain, configure group policy, configure LDAP and Kerberos, upgrading Domain controllers, etc. Over the years, Microsoft moved these activities to the cloud and offer them as a managed service, known as Azure AD DS.&lt;/li&gt;&#10;&lt;li&gt;&lt;strong&gt;Azure Active Directory Domain Service (Azure AD DS)&lt;/strong&gt;: allows you to use managed domain services (e.g. Windows Domain Join, group policy, LDAP, Kerberos authentication) without having to deploy, manage or patch domain controllers. It is a SaaS offering to manage your domain controllers in the cloud, with a pay-as-you-go model. The counterpart in AWS is &amp;#8220;AWS Directory Service&amp;#8221; which lets you run Microsoft Active Directory (AD) as an AWS managed service.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In summary, both AD DS on Windows Server (self-hosted) and Azure AD DS (managed service) are identity stores that operates on Windows domains. Even though the latter is a managed service, it supports LDAP or Kerberos as integration protocol for third party applications (usually on-premis) to use. Both LDAP and Kerberos came around prior to the cloud era and they are not optimized for cloud connectivity. For example, insecure bind (on port 389) in &lt;a href="https://static.digihunch.com/2020/03/lightweight-directory-access-protocol-ldap/"&gt;LDAP&lt;/a&gt; is still prevalent. &lt;a href="https://static.digihunch.com/2020/03/ntlm-and-kerberos/"&gt;Kerberos&lt;/a&gt; is fairly complex to configure. However, they are not phased out right away because of their established presence as well as the domain&amp;#8217;s awareness to authenticate devices. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Many organizations have to keep their domain service and when they move to cloud so they still have to use Active Directory as identity store. For this, Azure has Azure AD connect. On the AWS side, there is also an &lt;a href="https://docs.aws.amazon.com/directoryservice/latest/admin-guide/directory_ad_connector.html"&gt;AD connector&lt;/a&gt; tool to allow on-prem users to log into AWS applications and services. With AD connector you can also join EC2 instance to existing AD domain. &lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Now let&amp;#8217;s examine Azure AD.&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Azure AD: is an IAM solution. It contains an identity store (with users and groups in a flat directory structure) but more importantly it integrates with external identity stores (including Domain Service, self-hosted or SaaS managed), which gives it hybrid-identity capability. A company can even sync their own on-prem identity store to Azure AD using Azure AD Connect. As an IAM solution, Azure AD also allows a company to tie their identity store to applications using modern protocols such as SAML and OAuth. Azure AD treats applications as objects, and they can represents either Microsoft Applications (Office 365, Dynamics 365, Azure) or third-party ones (Slack, Salesforce) as long as they use the supported protocol for SSO. The closest AWS counterpart of Azure AD is Amazon Cognito (arguably), even though their capabilities are not identical in every aspect.&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Compared to Domain Service, Azure AD alone doesn&amp;#8217;t have the concept of domain. Therefore you cannot join a server or PC to a domain and configure group policy. Azure AD&amp;#8217;s native identity store is a flat directory structure without OUs or forests. Azure AD is NOT a replacement of domain service, either self-hosted or managed.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Now coming back to the Azure landing zone literature, the &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/landing-zone/design-area/identity-access-active-directory-hybrid-identity"&gt;document&lt;/a&gt; lays out the key decision to make about identity:&lt;/p&gt;&#10;&lt;blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"&gt;&#10;&lt;p class="wp-block-paragraph"&gt;A critical design decision for enterprise organizations adopting Azure is whether to extend current on-premises identity domains into Azure or to create new identity domains.&lt;/p&gt;&#10;&lt;cite&gt;Azure Active Directory (Azure AD) and hybrid identity&lt;/cite&gt;&lt;/blockquote&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The document even includes a comprehensive &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/decision-guides/identity/"&gt;identity decision guide&lt;/a&gt;. After this decision, we&amp;#8217;ll know what identity store to use. Then we can address the problem of platform access vs workload access. In other words, IAM of management traffic vs business traffic, which opens up topics such as RBAC, service principle and managed identities.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Networking&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Back in 2017, Azure published a &lt;a href="https://learn.microsoft.com/en-us/azure/architecture/networking/architecture/hub-spoke"&gt;white paper&lt;/a&gt; about V-Net and it focuses on mesh network and hub-and-spoke. Back then Azure customers run multiple lines of business (LOB) on different V-Nets. The V-Net peering feature allows early cloud adopters to organize all their V-Nets in a mesh topology, ensuring all peers have access to all other peers, or a hub-and-spoke topology to aggregate shared resources in hubs so they can be shared by the spokes in the network.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;When setting up a landing zone, network topology is a big decision. In the landing zone document today, clients need to consider the followings: &lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;Traditional Azure networking topologies, including:&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;large flat V-Net&lt;/li&gt;&#10;&lt;li&gt;multiple V-Nets connected with multiple Azure ExpressRoute circuits/connections&lt;/li&gt;&#10;&lt;li&gt;hub-and-spoke &lt;/li&gt;&#10;&lt;li&gt;full mesh&lt;/li&gt;&#10;&lt;li&gt;hybrid&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;/li&gt;&#10;&lt;li&gt;Microsoft managed networking topology (on top of Virtual WAN)&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;From the 2017 white paper, most organizations at that time solve their need for network isolation and connectivity by creating a mesh architecture among various V-Nets. All nodes in the network are interconnected so network traffic is fast and can be easily redirected. However, mesh topology has significant disadvantages because it requires too many connections as the footprint expands, making it very costly to operate and quick to reach limit of number of peering links. It is not scalable. The white paper is to advocate the use of hub-and-spoke topology, which I will discuss in the next section.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;It is worth-noting that, today (Jan 2023) one can create both topologies with &lt;a href="https://learn.microsoft.com/en-us/azure/virtual-network-manager/"&gt;Azure Virtual Network Manager&lt;/a&gt;. It is currently a preview service but I can foresee it will eventually get integrated with landing zone.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;No matter which topology, another issue to address is &lt;a href="https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/hybrid-networking/#hub-spoke-network-topology"&gt;connectivity to on-prem network&lt;/a&gt;, and to Azure &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure-paas-services"&gt;PaaS services&lt;/a&gt;. If the traffic is light, we can use VPN gateway to configure IPSec tunnel that goes over public internet encrypted. It is simple to configure with a good aggregate bandwidth. This connection requires a VPN device on premise as well. A faster alternative is Azure &lt;a href="https://learn.microsoft.com/en-us/azure/expressroute/"&gt;ExpressRoute&lt;/a&gt;, which runs a private connection with a third-party connectivity provider. &lt;a href="https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/hybrid-networking/#azure-expressroute-connection"&gt;ExpressRoute&lt;/a&gt; is more complex and expensive to set up, but it supports much higher bandwidth with direct access and better SLA. In reality, many clients configures ExpressRoute with VPN failover for connectivity to on-prem network. For &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/connectivity-to-azure-paas-services"&gt;connectivity to PaaS services&lt;/a&gt;, options are service endpoint and private link endpoint.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Hub-and-spoke topology&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In the &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/traditional-azure-networking-topology"&gt;traditional topologies&lt;/a&gt;, &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/hub-spoke-network-topology"&gt;hub-and-spoke&lt;/a&gt; network topology is popular as the hub network provides a central point of management. Also it overcomes &lt;a href="https://learn.microsoft.com/en-us/azure/azure-resource-manager/management/azure-subscription-service-limits#networking-limits"&gt;subscription limits&lt;/a&gt; and institutes a separation of concerns. The Azure documentation recommends &lt;a href="https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/hybrid-networking/hub-spoke?tabs=cli"&gt;hub-and-spoke architecture &lt;/a&gt;for larger cloud adoption efforts. If the footprint is even massive, we can even extend the model to a cluster of hubs and spokes. &lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full"&gt;&lt;img loading="lazy" decoding="async" width="677" height="452" src="https://static.digihunch.com/wp-content/uploads/2023/03/azure-hub-spoke.webp" alt="" class="wp-image-12907" srcset="https://static.digihunch.com/wp-content/uploads/2023/03/azure-hub-spoke.webp 677w, https://static.digihunch.com/wp-content/uploads/2023/03/azure-hub-spoke-300x200.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/03/azure-hub-spoke-410x275.webp 410w" sizes="auto, (max-width: 677px) 100vw, 677px" /&gt;&lt;figcaption class="wp-element-caption"&gt;A cluster of multiple hub-and-spoke&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;We can connect multiple hubs using:&lt;/p&gt;&#10;&lt;ul class="wp-block-list"&gt;&#10;&lt;li&gt;V-Net peering&lt;/li&gt;&#10;&lt;li&gt;Azure ExpressRoute&lt;/li&gt;&#10;&lt;li&gt;Azure Virtual WAN&lt;/li&gt;&#10;&lt;li&gt;Site-to-site VPN&lt;/li&gt;&#10;&lt;/ul&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Within a single hub-and-spoke model, the Hub V-Net hosts shared services and acts as central point of connectivity (to many spoke V-Nets). Often in the Hub V-Net are Azure Bastion, Azure Firewall and VPN Gateway or ExpressRoute gateway. The spoke V-Nets (in same or different subscriptions) isolates and manage workloads in prod, non-prod, etc. Since a single V-Net cannot traverse subscription boundaries, you have to use V-Net peering (preferred), ExpressRoute circuit, or VPN Gateways. V-Net peering works across regions, and across Azure AD tenants. It is low-latency but isn&amp;#8217;t transitive.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;In some cases we also configure &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/perimeter-networks"&gt;perimeter networks&lt;/a&gt; (aka DMZs) in the hub-and-spoke architecture, to handle external traffic. Perimeter networks host services such as External Load balancer, &lt;a href="https://learn.microsoft.com/en-us/azure/firewall/overview"&gt;Azure Firewall&lt;/a&gt;, Azure Application Firewall &lt;a href="https://learn.microsoft.com/en-us/azure/web-application-firewall/ag/ag-overview"&gt;on Azure Application Gateway&lt;/a&gt; or &lt;a href="https://learn.microsoft.com/en-us/azure/web-application-firewall/afds/afds-overview"&gt;on Azure FrontDoor&lt;/a&gt;) , &lt;a href="https://learn.microsoft.com/en-us/azure/architecture/reference-architectures/dmz/nva-ha"&gt;network virtual appliances&lt;/a&gt; (&lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/perimeter-networks#network-virtual-appliances"&gt;NVAs&lt;/a&gt;), IDS, IPS, and other security appliances. Incoming packets flow through the security appliances before reaching back-end servers. Internet-bound packets from workloads must also flow through security appliances in the perimeter network before they can leave the network. The document gives an &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/perimeter-networks#perimeter-network-topology"&gt;example&lt;/a&gt; of a DMZ hub V-Net with two perimeter networks.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Virtual WANs&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;a href="https://www.techtarget.com/searchnetworking/definition/WAN-wide-area-network"&gt;This&lt;/a&gt; page discusses what is WAN and SD-WAN. WAN connects multiple LANs in different geographic areas and is common with companies with multiple offices in different regions. WAN infrastructure may be privately owned or leased as a service from a third-party service provider (hybrid WAN). Companies may use IPSec VPN, SSL VPN or direct connection to build their WANs. Software-defined WAN (SD-WAN) leverages virtualization technologies, network overlays, on-site SD-WAN devices and software platforms to build hybrid WANs.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;&lt;a href="https://learn.microsoft.com/en-us/azure/virtual-wan/virtual-wan-about"&gt;Azure Virtual WAN&lt;/a&gt; (similar to &lt;a href="https://aws.amazon.com/blogs/networking-and-content-delivery/introducing-aws-cloud-wan-preview/"&gt;AWS cloud WAN&lt;/a&gt;) is a managed service to build a virtual WAN with a single operational interface that brings many networking, security and routing functionalities together. It simplifies end-to-end network connectivity (within Azure, between Azure and on-prem) by creating a hub-and-spoke architecture. &lt;/p&gt;&#10;&lt;div class="wp-block-image"&gt;&#10;&lt;figure class="aligncenter size-full"&gt;&lt;img loading="lazy" decoding="async" width="1024" height="608" src="https://static.digihunch.com/wp-content/uploads/2023/03/azure-virtual-wan.webp" alt="" class="wp-image-12908" srcset="https://static.digihunch.com/wp-content/uploads/2023/03/azure-virtual-wan.webp 1024w, https://static.digihunch.com/wp-content/uploads/2023/03/azure-virtual-wan-300x178.webp 300w, https://static.digihunch.com/wp-content/uploads/2023/03/azure-virtual-wan-768x456.webp 768w" sizes="auto, (max-width: 1024px) 100vw, 1024px" /&gt;&lt;figcaption class="wp-element-caption"&gt;Virtual WAN&lt;/figcaption&gt;&lt;/figure&gt;&#10;&lt;/div&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Virtual WAN is essentially an integrated connectivity solutions (in hub and spoke), with a &lt;a href="https://learn.microsoft.com/en-us/azure/virtual-wan/virtual-wan-global-transit-network-architecture"&gt;global transit network architecture&lt;/a&gt;. The configurations, including spoke setup) is automated and troubleshooting is more intuitive. Global transit network configures multiple virtual WAN hubs with hub-to-hub connectivity, which ultimately enables any-to-any connectivity, with different paths discussed &lt;a href="https://learn.microsoft.com/en-us/azure/virtual-wan/virtual-wan-global-transit-network-architecture#anytoany"&gt;here&lt;/a&gt;.&lt;/p&gt;&#10;&lt;p class="wp-block-paragraph"&gt;The landing zone document &lt;a href="https://learn.microsoft.com/en-us/azure/cloud-adoption-framework/ready/azure-best-practices/virtual-wan-network-topology#virtual-wan-network-design-recommendations"&gt;recommends&lt;/a&gt; Virtual WAN for new large or global network deployments in Azure where you need global transit connectivity across Azure regions and on-premises locations.&lt;/p&gt;&#10;&lt;h2 class="wp-block-heading"&gt;Summary&lt;/h2&gt;&#10;&lt;p class="wp-block-paragraph"&gt;Landing Zone configuration involves many components and there is no way to discuss everything thoroughly. In this post I put down my notes reading Azure landing zone documentation. Overall, working on landing zones requires learning a variety of services by the CSP.&lt;/p&gt;&#10;&lt;nav class="wp-post-navigation" aria-label="Post navigation"&gt;&#10;&lt;a rel="prev" href="https://static.digihunch.com/2023/03/a-taste-of-iot-device-tracking/"&gt;&lt;span class="wp-post-navigation-label"&gt;Previous Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;A taste of IoT device tracking&lt;/strong&gt;&lt;/a&gt;&#10;&lt;a rel="next" href="https://static.digihunch.com/2023/04/kubernetes-multiple-cpu-architecture-container-image/"&gt;&lt;span class="wp-post-navigation-label"&gt;Next Post&lt;/span&gt;&lt;strong class="wp-post-navigation-title"&gt;Kubernetes with Multiple CPU Architectures 1 of 2 – Container Image&lt;/strong&gt;&lt;/a&gt;&#10;&lt;/nav&gt;&#10;</description></item></channel></rss>