{"activeVersionTag":"latest","latestAvailableVersionTag":"latest","collection":{"info":{"_postman_id":"789c6766-7a97-47e3-ab94-d59a99f9bd5b","name":"Deploy with Amazon EKS and Kubernetes API","description":"![](https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/images/K8s-AWS-Postman.png?raw=true)\n\n> The following template is accompanied by [this](https://blog.postman.com/kubernetes-tutorial/) blog post\n\n[![Run in Postman](https://run.pstmn.io/button.svg)](https://god.gw.postman.com/run-collection/13059338-789c6766-7a97-47e3-ab94-d59a99f9bd5b?action=collection%2Ffork&collection-url=entityId%3D13059338-789c6766-7a97-47e3-ab94-d59a99f9bd5b%26entityType%3Dcollection%26workspaceId%3Daa2ddd64-1a22-4bc8-8aef-dca0ef22c370)\n\nKubernetes is open source and useful for container orchestration. In this tutorial, we are going to use Postman collections to learn Kubernetes and use it's API to deploy an app on a Kubernetes cluster hosted on AWS.\n\nThis is a hands-on tutorial. Don't fret if you are not familiar with Kubernetes and containerization. We aim to deliver the following through this tutorial:\n\n☸️ Prerequisites <br>\n☸️ Brief Overview on Containers <br>\n☸️ Enter Kubernetes <br>\n☸️ Creating a Kubernetes cluster <br>\n☸️ Accessing the Kubernetes API from Postman <br>\n☸️ Authorising Postman Collection <br>\n☸️ Deploy an app <br>\n☸️ Expose your App <br>\n☸️ Clean up <br>\n☸️ What Next?\n\n**Note**: We will be creating the Kubernetes cluster on AWS EKS, but you can also follow the tutorial with a cluster hosted on any other cloud providers or locally using Minikube.  \n\n# Prerequisites\nFamiliarity with REST APIs would be required. In addition you also need the following: \n- Create an [AWS account](https://portal.aws.amazon.com/billing/signup?refid=em_127222&redirect_url=https%3A%2F%2Faws.amazon.com%2Fregistration-confirmation#/start) \n- [Install](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html) and [configure aws cli](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html) - Required to configure credentials\n\n- [Install eskctl](https://eksctl.io/introduction/#installation) - a command utility to interact and create the cluster on EKS\n- [Install kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) - command line utility to work with Kubernetes clusters\n- Clone [Github repository](https://github.com/meenakshi-dhanani/k8s-postman-tutorial) - Contains .yaml files required in upcoming sections\n- Create your Amazon Cluster IAM role to access the cluster\n- Setting up Amazon EKS cluster VPC\n\nThis is a good guide that has all of the prerequisites mentioned above and instructions to install them - https://docs.aws.amazon.com/eks/latest/userguide/getting-started-console.html\n\n# Brief Overview on Containers\nAre you familiar with the ***but it works on my machine*** problem? A lot of times your application does not perform as it does in your local environment, it may be because the production environment may have different versions of the libraries, a different operating system, different system dependencies, etc. Containers provide you with a sustainable environment because your application now runs in a box (container) that includes all dependencies required by your app to run and is isolated from other applications running in other containers. They are preferred over VMs since they use operating system level virtualization and are lighter than VMs. [Docker](https://www.docker.com/products/container-runtime) can be used as container runtime. \n\n![Benefits of Containerization](https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/images/Benefits%20of%20Containerization.png?raw=true)\n# Enter Kubernetes\n\nEach app/service nows runs in a container, thus there can be separation of concerns. Services need not be intertwined with each other and a microservices architecture would work best with containerization. We have established why the world is moving towards containers, but who is going to manage these containers, how to do you rollout a release? How do you run health checks against your services, and get them back up if they are failing? Kubernetes does it all for you. It automates all of this. You can easily scale up and scale down your services with Kubernetes. \n\n![Kubernetes Benefits](https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/images/Kubernetes%20Benefits.png?raw=true)\n\nYou could use kubernetes anywhere for on-premise deployments or even hybrid clouds. For instance, you could have your cluster on GCE, AWS, Azure any cloud providers. For this tutorial, let's create a kubernetes cluster on AWS.\n\nYou can read more about the benefits of containerization and container orchestration with Kubernetes [here](https://cloud.google.com/containers). This is a really enthralling space, especially for folks interested in DevOps.\n\n\n# Creating a Kubernetes cluster\nAssuming you have followed the steps in the prerequisites section, you should have eksctl installed. \nLet's try out the following command to check if eksctl can successfully access the AWS account and list existing clusters if any.\n```\neksctl get cluster --region us-east-1\n```\nIn case this command fails, you may want to make sure your credentials are set up correctly as mentioned [here](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html).\n\nNext, we must create a cluster and assign some resources to it. The [cluster.yaml](https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/cluster.yaml) is present in the github project we cloned as mentioned in the prerequisites.\n\nYou can customise the configuration for the cluster based on the resources you want to assign to your cluster. You could choose a different region, maybe add more nodes or also a different instance type. For the purpose of this tutorial, we do not need as much CPU or memory. \n\n```\napiVersion: eksctl.io/v1alpha5\nkind: ClusterConfig\n\nmetadata:\n  name: playground\n  region: us-east-1\n\nnodeGroups:\n  - name: ng-1\n    instanceType: t2.small\n    desiredCapacity: 2\n```\nYou could choose a different region, may be add more nodes or also a different instance type. For the purpose of this tutorial, we do not need as much CPU or memory. \n\n**A word of caution**: The pricing for larger instances and more number of nodes would be more. \n\nUse the following command to create the cluster:\n```\neksctl create cluster -f cluster.yaml\n```\n\nIt may take a while for the set up. Once this command succeeds, assuming you have kubectl installed, the configuration for kubectl to access the cluster would be stored in `~/.kube/config`. Try fetching the nodes on the cluster using kubectl.\n\n```\nkubectl get nodes\n```\nYou should be able to see the two nodes. \n\n# Accessing the Kubernetes API from Postman\nNext, we require a service account to communicate with the Kubernetes API. The service account is authorised to perform certain actions eg. creating deployments, listing services by attaching it to a cluster role. \n\nRun the following command to create a service account.\n\n```\nkubectl create serviceaccount postman\n```\nWe must create a role definition for the service account. This role definition specifies all actions that are permitted on the resources mentioned. The [role.yaml](https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/role.yaml) is present in the github project we cloned as mentioned in the prerequisites.\n```\nrole.yaml\nkind: ClusterRole\napiVersion: rbac.authorization.k8s.io/v1beta1\nmetadata:\n  name: postman-role\nrules:\n- apiGroups: [\"apps\", \"\"] # \"\" indicates the core API group\n  resources: [\"pods\", \"services\", \"deployments\"]\n  verbs: [\"get\", \"watch\", \"list\", \"create\", \"update\", \"delete\"]\n```\nWe are configuring actions that can be performed on resources. We'll look at what these resources mean and how to create them in the next steps.\n\nRun the following command to create the role.\n```\nkubectl apply -f role.yaml\n```\n\nWe must assign the role to the service account by creating a role-binding.\n\n```\nkubectl create rolebinding postman:postman-role --clusterrole postman-role --serviceaccount default:postman\n```\n\nFor every service account created there is a secret token. Finally, we must extract the following from the token created for the service account:\n- API server URL\n- Bearer Token\n- CA Certificate\n\n```\nkubectl describe serviceaccount postman\n```\nThis command should reveal the secret eg. postman-token-9lxcc\n\nNext, we must describe the secret.\n\n`kubectl get secret <secret-token> -o json`\n\nThis command should reveal the ca.crt and the token inside a data object. We need to decode these to base64 and use them. This could be simplified using [jq](https://stedolan.github.io/jq/download/) command line utility.\n\n```\n# Extract the token from the Secret and decode \nTOKEN=$(kubectl get secret <secret-token> -o json | jq -Mr '.data.token' | base64 -d)\n# Extract, decode and write the ca.crt to a file\nkubectl get secret <secret-token> -o json | jq -Mr '.data[\"ca.crt\"]' | base64 -d > ca.crt\n```\n\nYou must get the API server URL from Amazon EKS. If you log into your Amazon account and see the cluster details for the `playground` cluster we created, you should find an **API server endpoint**. That is the URL for the API server that we are going to be hitting via Postman.\n\n![API Server Endpoint on AWS cluster](https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/images/AWS-endpoint.png?raw=true)\n\n# Authorising Postman Collection \nImport the collection into Postman and select the Manage Environments button on the top right and edit the following:\n\n![Edit AWS Environment](https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/images/Edit%20AWS%20Environment.png?raw=true)\n\nPaste the API Server Endpoint into the *CURRENT VALUE* for kube-api-server and the token into auth-token *CURRENT VALUE*. Click on *Update* \n\n**Tip**: The current value is never shared while sharing the Postman collection. Also, since these variables have sensitive information, it is best to add them to the environment variables. We could use the same collection and run it on a different environments eg. GCP, Minikube.\n\nNext, add *Authorization* to the collection. Adding *Authorization* at the collection level will ensure all the requests will be authorised with the same token/credentials. \n\nClick on *Edit* for the collection and under the *Authorization* see how the Bearer token will be passed in the Request Headers for each request.\n\n![Edit Authorization](https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/images/Collection%20Authorization.png?raw=true)\n\n\nAlmost there! The last step to get our collection ready is adding the CA Certificate. This can simply be done by clicking on Settings for Postman and under Certificates, turn on the CA Certificate toggle and upload the ca.crt file we created. Alternatively you could disable certificate verification, but that is not recommended.\n\n![Upload CA Certificate](https://github.com/meenakshi-dhanani/k8s-postman-tutorial/blob/main/images/Upload%20CA%20Certificate.png?raw=true)","schema":"https://schema.getpostman.com/json/collection/v2.0.0/collection.json","isPublicCollection":true,"owner":"13059338","team":6029,"collectionId":"789c6766-7a97-47e3-ab94-d59a99f9bd5b","publishedId":"TVmLCyNi","public":true,"publicUrl":"https://documenter-api.postman.tech/view/13059338/TVmLCyNi","privateUrl":"https://go.postman.co/documentation/13059338-789c6766-7a97-47e3-ab94-d59a99f9bd5b","customColor":{"top-bar":"FFFFFF","right-sidebar":"303030","highlight":"EF5B25"},"documentationLayout":"classic-single-column","customisation":null,"version":"8.10.1","publishDate":"2020-12-01T15:54:05.000Z","activeVersionTag":"latest","documentationTheme":"light","metaTags":{},"logos":{}},"statusCode":200},"environments":[{"name":"AWS","id":"c892aa80-aa3b-4d75-931d-b0e4630900ed","owner":"13059338","values":[{"key":"kube-api-server","value":"<API Server Endpoint>","enabled":true},{"key":"auth-token","value":"<Bearer Token>","enabled":true}],"published":true}],"user":{"authenticated":false,"permissions":{"publish":false}},"run":{"button":{"js":"https://run.pstmn.io/button.js","css":"https://run.pstmn.io/button.css"}},"web":"https://www.getpostman.com/","team":{"logo":"https://res.cloudinary.com/postman/image/upload/t_team_logo_pubdoc/v1/team/2893aede23f01bfcbd2319326bc96a6ed0524eba759745ed6d73405a3a8b67a8","favicon":"https://res.cloudinary.com/postman/image/upload/v1602695501/team/xxbaetptrvdhhptsqvnh.ico"},"isEnvFetchError":false,"languages":"[{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"HttpClient\"},{\"key\":\"csharp\",\"label\":\"C#\",\"variant\":\"RestSharp\"},{\"key\":\"curl\",\"label\":\"cURL\",\"variant\":\"cURL\"},{\"key\":\"dart\",\"label\":\"Dart\",\"variant\":\"http\"},{\"key\":\"go\",\"label\":\"Go\",\"variant\":\"Native\"},{\"key\":\"http\",\"label\":\"HTTP\",\"variant\":\"HTTP\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"OkHttp\"},{\"key\":\"java\",\"label\":\"Java\",\"variant\":\"Unirest\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"Fetch\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"jQuery\"},{\"key\":\"javascript\",\"label\":\"JavaScript\",\"variant\":\"XHR\"},{\"key\":\"c\",\"label\":\"C\",\"variant\":\"libcurl\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Axios\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Native\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Request\"},{\"key\":\"nodejs\",\"label\":\"NodeJs\",\"variant\":\"Unirest\"},{\"key\":\"objective-c\",\"label\":\"Objective-C\",\"variant\":\"NSURLSession\"},{\"key\":\"ocaml\",\"label\":\"OCaml\",\"variant\":\"Cohttp\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"cURL\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"Guzzle\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"HTTP_Request2\"},{\"key\":\"php\",\"label\":\"PHP\",\"variant\":\"pecl_http\"},{\"key\":\"powershell\",\"label\":\"PowerShell\",\"variant\":\"RestMethod\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"http.client\"},{\"key\":\"python\",\"label\":\"Python\",\"variant\":\"Requests\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"httr\"},{\"key\":\"r\",\"label\":\"R\",\"variant\":\"RCurl\"},{\"key\":\"ruby\",\"label\":\"Ruby\",\"variant\":\"Net::HTTP\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"Httpie\"},{\"key\":\"shell\",\"label\":\"Shell\",\"variant\":\"wget\"},{\"key\":\"swift\",\"label\":\"Swift\",\"variant\":\"URLSession\"}]","languageSettings":[{"key":"csharp","label":"C#","variant":"HttpClient"},{"key":"csharp","label":"C#","variant":"RestSharp"},{"key":"curl","label":"cURL","variant":"cURL"},{"key":"dart","label":"Dart","variant":"http"},{"key":"go","label":"Go","variant":"Native"},{"key":"http","label":"HTTP","variant":"HTTP"},{"key":"java","label":"Java","variant":"OkHttp"},{"key":"java","label":"Java","variant":"Unirest"},{"key":"javascript","label":"JavaScript","variant":"Fetch"},{"key":"javascript","label":"JavaScript","variant":"jQuery"},{"key":"javascript","label":"JavaScript","variant":"XHR"},{"key":"c","label":"C","variant":"libcurl"},{"key":"nodejs","label":"NodeJs","variant":"Axios"},{"key":"nodejs","label":"NodeJs","variant":"Native"},{"key":"nodejs","label":"NodeJs","variant":"Request"},{"key":"nodejs","label":"NodeJs","variant":"Unirest"},{"key":"objective-c","label":"Objective-C","variant":"NSURLSession"},{"key":"ocaml","label":"OCaml","variant":"Cohttp"},{"key":"php","label":"PHP","variant":"cURL"},{"key":"php","label":"PHP","variant":"Guzzle"},{"key":"php","label":"PHP","variant":"HTTP_Request2"},{"key":"php","label":"PHP","variant":"pecl_http"},{"key":"powershell","label":"PowerShell","variant":"RestMethod"},{"key":"python","label":"Python","variant":"http.client"},{"key":"python","label":"Python","variant":"Requests"},{"key":"r","label":"R","variant":"httr"},{"key":"r","label":"R","variant":"RCurl"},{"key":"ruby","label":"Ruby","variant":"Net::HTTP"},{"key":"shell","label":"Shell","variant":"Httpie"},{"key":"shell","label":"Shell","variant":"wget"},{"key":"swift","label":"Swift","variant":"URLSession"}],"languageOptions":[{"label":"C# - HttpClient","value":"csharp - HttpClient - C#"},{"label":"C# - RestSharp","value":"csharp - RestSharp - C#"},{"label":"cURL - cURL","value":"curl - cURL - cURL"},{"label":"Dart - http","value":"dart - http - Dart"},{"label":"Go - Native","value":"go - Native - Go"},{"label":"HTTP - HTTP","value":"http - HTTP - HTTP"},{"label":"Java - OkHttp","value":"java - OkHttp - Java"},{"label":"Java - Unirest","value":"java - Unirest - Java"},{"label":"JavaScript - Fetch","value":"javascript - Fetch - JavaScript"},{"label":"JavaScript - jQuery","value":"javascript - jQuery - JavaScript"},{"label":"JavaScript - XHR","value":"javascript - XHR - JavaScript"},{"label":"C - libcurl","value":"c - libcurl - C"},{"label":"NodeJs - Axios","value":"nodejs - Axios - NodeJs"},{"label":"NodeJs - Native","value":"nodejs - Native - NodeJs"},{"label":"NodeJs - Request","value":"nodejs - Request - NodeJs"},{"label":"NodeJs - Unirest","value":"nodejs - Unirest - NodeJs"},{"label":"Objective-C - NSURLSession","value":"objective-c - NSURLSession - Objective-C"},{"label":"OCaml - Cohttp","value":"ocaml - Cohttp - OCaml"},{"label":"PHP - cURL","value":"php - cURL - PHP"},{"label":"PHP - Guzzle","value":"php - Guzzle - PHP"},{"label":"PHP - HTTP_Request2","value":"php - HTTP_Request2 - PHP"},{"label":"PHP - pecl_http","value":"php - pecl_http - PHP"},{"label":"PowerShell - RestMethod","value":"powershell - RestMethod - PowerShell"},{"label":"Python - http.client","value":"python - http.client - Python"},{"label":"Python - Requests","value":"python - Requests - Python"},{"label":"R - httr","value":"r - httr - R"},{"label":"R - RCurl","value":"r - RCurl - R"},{"label":"Ruby - Net::HTTP","value":"ruby - Net::HTTP - Ruby"},{"label":"Shell - Httpie","value":"shell - Httpie - Shell"},{"label":"Shell - wget","value":"shell - wget - Shell"},{"label":"Swift - URLSession","value":"swift - URLSession - Swift"}],"layoutOptions":[{"value":"classic-single-column","label":"Single Column"},{"value":"classic-double-column","label":"Double Column"}],"versionOptions":[],"environmentOptions":[{"value":"0","label":"No Environment"},{"label":"AWS","value":"13059338-c892aa80-aa3b-4d75-931d-b0e4630900ed"}],"canonicalUrl":"https://documenter.gw.postman.com/view/metadata/TVmLCyNi"}