{"id":2634,"date":"2019-03-17T19:23:19","date_gmt":"2019-03-17T13:53:19","guid":{"rendered":"http:\/\/navveenbalani.dev\/?p=2634"},"modified":"2019-12-17T21:02:37","modified_gmt":"2019-12-17T15:32:37","slug":"building-production-topology-with-google-cloud-part-3","status":"publish","type":"post","link":"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/","title":{"rendered":"Building Production Topology with Google Cloud &#8211; Part 3"},"content":{"rendered":"\n<p>In this article, we would deploy the endpoint configuration for our microservices application. As mentioned earlier, we are using Cloud Endpoints for API management to secure, monitor, analyze, and set quotas on our APIs. <\/p>\n\n\n\n<p>Endpoints support version 2 of the <a href=\"https:\/\/github.com\/OAI\/OpenAPI-Specification\/blob\/master\/versions\/2.0.md\">OpenAPI\nSpecification<\/a>.&nbsp;\nFor more details, refer to <a href=\"https:\/\/cloud.google.com\/endpoints\/docs\/openapi\/\">https:\/\/cloud.google.com\/endpoints\/docs\/openapi\/<\/a>.<\/p>\n\n\n\n<p>The OpenAPI configuration file of\nour microservice project is provided in script\/kube-openapi-backend.yaml.<\/p>\n\n\n\n<p>Open kube-openapi-backend.yaml and replace the host \u201capis.navveenbalani.dev\u201d with the hostname where your API would be available. My APIs are available at apis.navveenbalani.dev. If you don\u2019t have a host readily available, you can use &lt;api-name&gt;.endpoints.&lt;YOUR-PROJECT-ID&gt;.cloud.goog in host name, replace api-name with the name for your api and YOUR-PROJECT-ID with your google project id. You can later use the host name and map it to the IP address in your DNS settings and use the host name to invoke your service.&nbsp; For more details, refer to Configuring DNS for Endpoints section at <a href=\"https:\/\/cloud.google.com\/endpoints\/docs\/openapi\/get-started-kubernetes#configuring-endpoints-dns.\">https:\/\/cloud.google.com\/endpoints\/docs\/openapi\/get-started-kubernetes#configuring-endpoints-dns.<\/a><\/p>\n\n\n\n<p>Next, we would deploy the endpoints for the application\nby following the steps below:<\/p>\n\n\n\n<ul><li>Install Google Cloud SDK (if you haven\u2019t already)\nfrom <a href=\"https:\/\/cloud.google.com\/sdk\/\">https:\/\/cloud.google.com\/sdk\/<\/a>) on your local machine.<\/li><li>With Google SDK installed, open a command prompt\nand set the project. Replace navveen-api with your project id.<\/li><\/ul>\n\n\n\n<p>&gt; gcloud config set project\nnavveen-api<\/p>\n\n\n\n<ul><li>Go to scripts folder. Deploy the endpoint\nconfiguration by running the following command: &#8211;<\/li><\/ul>\n\n\n\n<p>&gt; gcloud endpoints services deploy\nkube-openapi-backend.yaml<\/p>\n\n\n\n<p>You should see similar messages being printed on\nthe console and a URL being provided at the end to manage your APIs.<\/p>\n\n\n\n<p><em>Figure 17 \u2013 Output of&nbsp; endpoint deployment<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"342\" height=\"256\" src=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-43.png\" alt=\"\" class=\"wp-image-2674\" srcset=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-43.png 342w, https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-43-300x225.png 300w\" sizes=\"(max-width: 342px) 100vw, 342px\" \/><\/figure>\n\n\n\n<ul><li>Next, create an API key to access the Endpoint.\nGo to <a href=\"https:\/\/console.cloud.google.com\/apis\/credentials\">https:\/\/console.cloud.google.com\/apis\/credentials<\/a> and select your GCP project.<\/li><li>Click Create credentials, and then\nselect API key,<\/li><li>Copy the key to the clipboard. We\nwill use the API key later when calling our endpoint.<\/li><li>You\ncan further apply restrictions on the API key (like HTTP Referrer, IP address,\ndevices etc.) on who can invoke your endpoint based on your application needs. For\ninstance, if you want to ensure your application can be invoked by specific IP\naddresses only, you can specify the list of IP addresses by clicking on the IP\naddress option.<\/li><\/ul>\n\n\n\n<h2>Create Workload, Service and\nIngress <\/h2>\n\n\n\n<p>In this section,\nwe would create the workload, service, and Ingress for our application. Go to\nthe scripts folder of google-cloud-kubernetes-secure-e2e\/scripts project and\nrun the following commands in google cloud sdk\/shell. <\/p>\n\n\n\n<ol><li>Set the project. Replace Navveen-api by your\nproject id.<\/li><\/ol>\n\n\n\n<p>&gt; gcloud config set project\nnavveen-api<\/p>\n\n\n\n<ul><li>Connect to backend-custer<\/li><\/ul>\n\n\n\n<p>&gt; gcloud container clusters\nget-credentials backend-cluster &nbsp;&nbsp;&#8211;zone\nus-east1-b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; The backend-cluster is the kubernetes\ncluster and zone is us-east1-b where our cluster is running.<\/p>\n\n\n\n<ul><li>Deploying the workload (backend)<ul><li>The kube-backend-deployment-gcp.yaml deploys our microservices container (kube-e2e-service) and kube-esp (google endpoint runtime container) as shown below.<\/li><\/ul><\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>containers:\n      - name: kube-e2e-service\n        image: gcr.io\/navveen-api\/kube-e2e-solution:v1\n        ports:\n          - containerPort: 8080\n      - name: kube-esp\n        image: gcr.io\/endpoints-release\/endpoints-runtime:1\n        args: [\n          \"--http_port\", \"8081\",\n          \"--backend\", \"127.0.0.1:8080\",\n          \"--service\", \"apis.navveenbalani.dev\",\n          \"--rollout_strategy\", \"managed\",\n        ]\n        readinessProbe:\n         httpGet:\n          path: \/healthz?key=AIzaSyC0m7d4cc-\n          jOwJIzymv9ntObF1ukIMrTc-\n          port: 8081\n         initialDelaySeconds: 60\n        livenessProbe:\n         httpGet:\n          path: \/healthz?key=AIzaSyC0m7d4cc-\n          jOwJIzymv9ntObF1ukIMrTc-\n          port: 8081\n         initialDelaySeconds: 60\n        ports:\n          - containerPort: 8081\n\n<\/code><\/pre>\n\n\n\n<p>All incoming requests would first be intercepted by the google endpoint container (kube-esp) which would will direct them to the microservices container (kube-e2e-service). The google endpoint container checks the API key and any rule that you have applied on the API key (quotas, IP address restriction, device restrictions etc.) and then forwards the request to respective endpoints in the microservices container. <\/p>\n\n\n\n<ul><li>Open the\nkube-backend-deployment-gcp.yaml and replace \u201capis.navveenbalani.dev\u201d with the\nhostname you provided in Step 7 while configuring the endpoint. The service\nname determines which endpoint configuration should be called.<\/li><\/ul>\n\n\n\n<ul><li>&nbsp;Replace\nAIzaSyC0m7d4cc-jOwJIzymv9ntObF1ukIMrTc- with the endpoint API key that you\ngenerated in earlier step.<\/li><\/ul>\n\n\n\n<ul><li>The\nreadinessProbe and livenessProbe defines the health check URL for our service.\nOnce the container is started, the path mentioned in the URL would be invoked,\nand if the response is 200, the container would be in ready state and should\nstart serving requests. Note, this would test the endpoint configuration, as\nwell as the actual microservice endpoint. We had discussed health check URLs in\nStep 4 earlier, and through this configuration, we decide which service to\ninvoke for a health check.<\/li><\/ul>\n\n\n\n<ul><li>Deploy the\nworkload by running the following command.<\/li><\/ul>\n\n\n\n<p>&gt;\nkubectl apply -f kube-backend-deployment-gcp.yaml<\/p>\n\n\n\n<ul><li>Navigate to\nKubernetes Engine -&gt; Workload and you should see the status as green in a\nfew minutes as shown below once the heath check is done.<\/li><\/ul>\n\n\n\n<p><em>Figure 18 \u2013 Status of workloads<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"346\" height=\"230\" src=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-19.png\" alt=\"\" class=\"wp-image-2636\" srcset=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-19.png 346w, https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-19-300x199.png 300w\" sizes=\"(max-width: 346px) 100vw, 346px\" \/><\/figure>\n\n\n\n<ul><li>Deploying the service<ul><li>The kube-backend-service-node-gcp.yaml       exposes the service on each Node IP at a static port (using NodePort       type). The port:8081 is the static port and targetPort:8081 is the port       where the request needs to be sent, which is the kube-esp container that       we discussed earlier.<\/li><\/ul><\/li><\/ul>\n\n\n\n<p>&nbsp;&nbsp;<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>spec:\n  type: NodePort\n  selector:\n    apps: backend-gcp\n  ports:\n  - port: 8081\n    targetPort: 8081<\/code><\/pre>\n\n\n\n<ul><li>Create the service by running the following  command.<\/li><\/ul>\n\n\n\n<p>&gt; kubectl apply -f\nkube-backend-service-node-gcp.yaml <\/p>\n\n\n\n<ul><li>Creating Ingress<\/li><\/ul>\n\n\n\n<p>In Kubernetes, an Ingress is a resource\nthat allows access to your services from outside the Kubernetes cluster.\nIngress resource consists of two components &#8211; a set of rules and an Ingress\nController. <\/p>\n\n\n\n<p>The set of rules allows inbound\nconnections to be directed to specific services in Kubernetes. An Ingress\ncontroller, which is typically configured as an HTTP Load Balancer implements\nthe rules and direct connections to the respective services.<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Follow the steps below to create\nIngress for our application.<\/p>\n\n\n\n<ul><li>First, we would create a static IP for Http  Load balancer. Go to VPC Network &#8211; External IP addresses -&gt; Reserve Static Address.&nbsp; Enter a name for  IP (copy it, as we will use this later) and select type as Global. LoadBalancer       works only with Global Type.<\/li><\/ul>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <em>Figure 20 \u2013 Create&nbsp; Static IP address <\/em>&nbsp;&nbsp;<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"253\" height=\"233\" src=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-20.png\" alt=\"\" class=\"wp-image-2637\"\/><\/figure>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;      <\/p>\n\n\n\n<ul><li>Click Reserve and note the IP address. This       is our external IP address where the service would be exposed. I have       mapped this IP to my host api.navveenbalani.dev (in DNS). You can map       this IP to your host name where apis would be available.<\/li><\/ul>\n\n\n\n<ul><li>Our services would be exposed over HTTPS (i.e.\nfor my configuration it\u2019s as https:\/\/api.naveenbalani.dev).<\/li><\/ul>\n\n\n\n<p>Next, we would\ncreate the SSL secret configuration, which consists of certificate and key for your\ndomain. This assumes that you already have the SSL certificates, otherwise you\ncan generate one using third party SSL provides like letsencrypt. Run the\nfollowing command<\/p>\n\n\n\n<p>kubectl create secret tls kube-api-ssl-secret \\ &#8211;cert \/Users\/naveenbalani\/Downloads\/api-naveenbalani-dev-ssl\/certificate-merged.crt &#8211;key \/Users\/naveenbalani\/Downloads\/api-naveenbalani-dev-ssl\/private.key<\/p>\n\n\n\n<p>Where\n\/Users\/naveenbalani\/Downloads\/api-naveenbalani-dev-ssl\/certificate-merged.crt\nis path to the certificate and\n\/Users\/naveenbalani\/Downloads\/api-naveenbalani-dev-ssl\/private.key is the path\nto the private key<\/p>\n\n\n\n<ul><li>Next, we will deploy the Ingress. Ingress configuration is provided in the kube-backend-ingress-ssl-gcp.yaml file. Open the file and replace \u201cnavveen-api-ip\u201d with the static IP address name that we created in earlier step.&nbsp; Also replace apis.navveenbalani.dev with your host name. We also reference the SSL secret \u201ckube-api-ssl-secret\u201d that we created earlier for the host apis.navveenbalani.dev. We also define a rule, that all request to apis.navveenbalani.dev would be directed to kube-node-service-gcp (i.e. NodePort) that we created in Deploying the service section earlier.<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>kind: Ingress\nmetadata:\n  name: kube-ingress-gcp\n  annotations:\n     kubernetes.io\/ingress.allow-http: \"true\"\n     kubernetes.io\/ingress.global-static-ip-name: navveen-api-ip\t\nspec:\n  tls:\n  - hosts:\n    - apis.navveenbalani.dev\n    secretName: kube-api-ssl-secret\n  rules:\n  - host: apis.navveenbalani.dev\n    http:\n      paths:\n      - backend:\n            serviceName: kube-node-service-gcp\t\t\n            servicePort: 8081\n<\/code><\/pre>\n\n\n\n<ul><li>Run the\nfollowing command to create Ingress.<\/li><\/ul>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &gt;\nkubectl apply -f kube-backend-ingress-ssl-gcp.yaml <\/p>\n\n\n\n<ul><li>Go to Kubernetes\nEngine &#8211; &gt; Services and Ingress in Google cloud console and inspect the\nIngress configuration.&nbsp; You should see\nthe status of \u201ckube-ingress-gcp\u201d green in some time.<\/li><\/ul>\n\n\n\n<p><em>Figure 22 \u2013 Status of Services &amp; Ingress<\/em>   <\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"351\" height=\"211\" src=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-21.png\" alt=\"\" class=\"wp-image-2638\" srcset=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-21.png 351w, https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-21-300x180.png 300w, https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-21-350x211.png 350w\" sizes=\"(max-width: 351px) 100vw, 351px\" \/><\/figure>\n\n\n\n<p>  <\/p>\n\n\n\n<ul><li>Click\non kube-ingress gcp. Click on the backend services and select the backend\nservice where service port is 8081.<\/li><\/ul>\n\n\n\n<p><em>Figure 23 \u2013 Ingress Detail<\/em>&nbsp;&nbsp;&nbsp; <\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"351\" height=\"201\" src=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-22.png\" alt=\"\" class=\"wp-image-2639\" srcset=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-22.png 351w, https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-22-300x172.png 300w, https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-22-350x201.png 350w\" sizes=\"(max-width: 351px) 100vw, 351px\" \/><\/figure>\n\n\n\n<p><em>Figure 24 \u2013 Ingress Detail -&gt; Backend:&nbsp; Port 8081<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"342\" height=\"158\" src=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-23.png\" alt=\"\" class=\"wp-image-2640\" srcset=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-23.png 342w, https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-23-300x139.png 300w\" sizes=\"(max-width: 342px) 100vw, 342px\" \/><\/figure>\n\n\n\n<ul><li>Next, click on the Health check link and on\n     the Heath check page you, should see the path (i.e look for Path variable)\n     that we have specified in the workload deployment file being used for the\n     health check.<\/li><\/ul>\n\n\n\n<p><em>Figure 25 \u2013 Ingress Backend Service &#8211; &gt; Heath Check<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"351\" height=\"160\" src=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-24.png\" alt=\"\" class=\"wp-image-2641\" srcset=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-24.png 351w, https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-24-300x137.png 300w, https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-24-350x160.png 350w\" sizes=\"(max-width: 351px) 100vw, 351px\" \/><\/figure>\n\n\n\n<p><em>Figure 26 \u2013 Ingress Backend Service &#8211; &gt; Heath Check -&gt; Path<\/em><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" width=\"294\" height=\"139\" src=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/12\/image-25.png\" alt=\"\" class=\"wp-image-2642\"\/><\/figure>\n\n\n\n<p>With this, we have setup the Ingress. <a href=\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-4\/\">Next, we would invoke our micro service.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we would deploy the endpoint configuration for our microservices application. As mentioned earlier, we are using Cloud Endpoints for API management to secure, monitor, analyze, and set quotas on our APIs. Endpoints support version 2 of the OpenAPI Specification.&nbsp; For more details, refer to https:\/\/cloud.google.com\/endpoints\/docs\/openapi\/. The OpenAPI configuration file of our microservice [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":2128,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":[],"categories":[3,79],"tags":[285],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v16.0.2 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Building Production Topology with Google Cloud - Part 3 - Current and Future Technology Trends by Navveen Balani<\/title>\n<meta name=\"description\" content=\"Building Production Topology with Google Cloud - Part 3 - Articles\" \/>\n<link rel=\"canonical\" href=\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Building Production Topology with Google Cloud - Part 3 - Current and Future Technology Trends by Navveen Balani\" \/>\n<meta property=\"og:description\" content=\"Building Production Topology with Google Cloud - Part 3 - Articles\" \/>\n<meta property=\"og:url\" content=\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/\" \/>\n<meta property=\"og:site_name\" content=\"Current and Future Technology Trends by Navveen Balani\" \/>\n<meta property=\"article:published_time\" content=\"2019-03-17T13:53:19+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-12-17T15:32:37+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2016\/09\/bk6.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"450\" \/>\n\t<meta property=\"og:image:height\" content=\"374\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Est. reading time\">\n\t<meta name=\"twitter:data1\" content=\"8 minutes\">\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebSite\",\"@id\":\"https:\/\/navveenbalani.dev\/#website\",\"url\":\"https:\/\/navveenbalani.dev\/\",\"name\":\"Current and Future Technology Trends by Navveen Balani\",\"description\":\"Current and Future Technology Trends by Navveen Balani\",\"publisher\":{\"@id\":\"https:\/\/navveenbalani.dev\/#\/schema\/person\/51f7ab14b20611d95e3c7fd4ea0950bf\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":\"https:\/\/navveenbalani.dev\/?s={search_term_string}\",\"query-input\":\"required name=search_term_string\"}],\"inLanguage\":\"en-US\"},{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/#primaryimage\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2016\/09\/bk6.jpg\",\"width\":450,\"height\":374},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/#webpage\",\"url\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/\",\"name\":\"Building Production Topology with Google Cloud - Part 3 - Current and Future Technology Trends by Navveen Balani\",\"isPartOf\":{\"@id\":\"https:\/\/navveenbalani.dev\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/#primaryimage\"},\"datePublished\":\"2019-03-17T13:53:19+00:00\",\"dateModified\":\"2019-12-17T15:32:37+00:00\",\"description\":\"Building Production Topology with Google Cloud - Part 3 - Articles\",\"breadcrumb\":{\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/navveenbalani.dev\/\",\"url\":\"https:\/\/navveenbalani.dev\/\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"position\":2,\"item\":{\"@type\":\"WebPage\",\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/\",\"url\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/\",\"name\":\"Building Production Topology with Google Cloud &#8211; Part 3\"}}]},{\"@type\":\"Article\",\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/#webpage\"},\"author\":{\"@id\":\"https:\/\/navveenbalani.dev\/#\/schema\/person\/51f7ab14b20611d95e3c7fd4ea0950bf\"},\"headline\":\"Building Production Topology with Google Cloud &#8211; Part 3\",\"datePublished\":\"2019-03-17T13:53:19+00:00\",\"dateModified\":\"2019-12-17T15:32:37+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/#webpage\"},\"publisher\":{\"@id\":\"https:\/\/navveenbalani.dev\/#\/schema\/person\/51f7ab14b20611d95e3c7fd4ea0950bf\"},\"image\":{\"@id\":\"https:\/\/navveenbalani.dev\/index.php\/articles\/building-production-topology-with-google-cloud-part-3\/#primaryimage\"},\"keywords\":\"google-cloud\",\"articleSection\":\"Articles,Cloud Computing\",\"inLanguage\":\"en-US\"},{\"@type\":[\"Person\",\"Organization\"],\"@id\":\"https:\/\/navveenbalani.dev\/#\/schema\/person\/51f7ab14b20611d95e3c7fd4ea0950bf\",\"name\":\"Navveen\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\/\/navveenbalani.dev\/#personlogo\",\"inLanguage\":\"en-US\",\"url\":\"https:\/\/navveenbalani.dev\/wp-content\/uploads\/2019\/07\/navveen_balani.jpeg\",\"width\":200,\"height\":200,\"caption\":\"Navveen\"},\"logo\":{\"@id\":\"https:\/\/navveenbalani.dev\/#personlogo\"},\"sameAs\":[\"http:\/\/naveenbalani.com\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","_links":{"self":[{"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/posts\/2634"}],"collection":[{"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/comments?post=2634"}],"version-history":[{"count":3,"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/posts\/2634\/revisions"}],"predecessor-version":[{"id":2676,"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/posts\/2634\/revisions\/2676"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/media\/2128"}],"wp:attachment":[{"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/media?parent=2634"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/categories?post=2634"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/navveenbalani.dev\/index.php\/wp-json\/wp\/v2\/tags?post=2634"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}