{"id":171,"date":"2024-03-17T08:58:57","date_gmt":"2024-03-17T08:58:57","guid":{"rendered":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2024\/03\/17\/build-secure-ai-applications-on-azure-with-hashicorp-terraform-and-vault\/"},"modified":"2024-03-17T18:34:32","modified_gmt":"2024-03-17T18:34:32","slug":"build-secure-ai-applications-on-azure-with-hashicorp-terraform-and-vault","status":"publish","type":"post","link":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/2024\/03\/17\/build-secure-ai-applications-on-azure-with-hashicorp-terraform-and-vault\/","title":{"rendered":"Build secure AI applications on Azure with HashiCorp Terraform and Vault"},"content":{"rendered":"<p>HashiCorp and Microsoft have partnered to create <a href=\"https:\/\/developer.hashicorp.com\/terraform\/tutorials\/modules\/module\">Terraform modules<\/a> that follow Microsoft&#8217;s <a href=\"https:\/\/learn.microsoft.com\/en-us\/azure\/architecture\/framework\/\">Azure Well-Architected Framework<\/a> and best practices. In a previous blog post, we demonstrated how to <a href=\"https:\/\/www.hashicorp.com\/blog\/accelerating-ai-adoption-on-azure-with-terraform\">accelerate AI adoption on Azure with Terraform<\/a>. This post covers how to use a simple three-step process to build, secure, and enable OpenAI applications on Azure with HashiCorp Terraform and Vault. <\/p>\n<p>The code for this demo can be found on <a href=\"https:\/\/github.com\/dawright22\/azure-ai-demo.git\">GitHub<\/a>. You can leverage the Microsoft application outlined in this post and the Microsoft Azure Kubernetes Service (AKS) to integrate with OpenAI. You can also read more about how to <a href=\"https:\/\/learn.microsoft.com\/en-gb\/azure\/aks\/open-ai-quickstart?tabs=aoai\">deploy an application that uses OpenAI on AKS<\/a> on the Microsoft website.<\/p>\n<h2>Key considerations of AI<\/h2>\n<p>The rise in AI workloads is driving an expansion of cloud operations. <a href=\"https:\/\/www.gartner.com\/en\/newsroom\/press-releases\/11-13-2023-gartner-forecasts-worldwide-public-cloud-end-user-spending-to-reach-679-billion-in-20240#:~:text=Infrastructure-as-a-service,%25%20(see%20Table%201).\">Gartner predicts<\/a> that cloud infrastructure will grow 26.6% in 2024, as organizations deploying generative AI (GenAI) services look to the public cloud. To create a successful AI environment, orchestrating the seamless integration of artificial intelligence and operations demands a focus on security, efficiency, and cost control. <\/p>\n<h3>Security<\/h3>\n<p>Data integration, the bedrock of AI, not only requires the harmonious assimilation of diverse data sources but must also include a process to safeguard sensitive information. In this complex landscape, the deployment of p<a href=\"https:\/\/www.hashicorp.com\/blog\/what-is-public-key-infrastructure-pki\">ublic key infrastructure (PKI)<\/a> and <a href=\"https:\/\/www.hashicorp.com\/resources\/5-best-practices-for-secrets-management\">robust secrets management<\/a> becomes indispensable, adding cryptographic resilience to data transactions and ensuring the secure handling of sensitive information. For more information on the HashiCorp Vault solution, see our <a href=\"https:\/\/www.vaultproject.io\/use-cases\/automated-pki-infrastructure\">use-case page on Automated PKI infrastructure<\/a><\/p>\n<p>Machine learning models, pivotal in anomaly detection, predictive analytics, and root-cause analysis, not only provide operational efficiency but also serve as sentinels against potential security threats. Automation and orchestration, facilitated by tools like HashiCorp Terraform, extend beyond efficiency to become critical components in fortifying against security vulnerabilities. Scalability and performance, guided by resilient architectures and vigilant monitoring, ensure adaptability to evolving workloads without compromising on security protocols.<\/p>\n<h3>Efficiency and cost control<\/h3>\n<p>In response, platform teams are increasingly adopting infrastructure as code (IaC) to enhance efficiency and help control cloud costs. HashiCorp products underpin some of today\u2019s largest AI workloads, using infrastructure as code to help eliminate idle resources and overprovisioning, and reduce infrastructure risk.<\/p>\n<h3>Automation with Terraform<\/h3>\n<p>This post delves into specific Terraform configurations tailored for application deployment within a containerized environment. The first step looks at using IaC principles to deploy infrastructure to efficiently scale AI workloads, reduce manual intervention, and foster a more agile and collaborative AI development lifecycle on the Azure platform. The second step focuses on how to build security and compliance into an AI workflow. The final step shows how to manage application deployment on the newly created resources. <\/p>\n<h2>Prerequisites<\/h2>\n<p>For this demo, you can use either Azure OpenAI service or OpenAI service:<\/p>\n<p>To use Azure OpenAI service, enable it on your Azure subscription using the <a href=\"https:\/\/aka.ms\/oai\/access\">Request Access to Azure OpenAI Service form<\/a>.<br \/>\nTo use OpenAI, sign up on the <a href=\"https:\/\/openai.com\/\">OpenAI website<\/a>.<\/p>\n<h3>Step one: Build<\/h3>\n<p>First let&#8217;s look at the <a href=\"https:\/\/registry.terraform.io\/providers\/hashicorp\/helm\/latest\/docs\">Helm provider<\/a> block in <a href=\"https:\/\/github.com\/dawright22\/azure-ai-demo\/blob\/main\/main.tf\">main.tf<\/a>:<\/p>\n<p>provider &#8220;helm&#8221; {<br \/>\n  kubernetes {<br \/>\n  host                   = azurerm_kubernetes_cluster.tf-ai-demo.kube_config.0.host<br \/>\n  username               = azurerm_kubernetes_cluster.tf-ai-demo.kube_config.0.username<br \/>\n  password               = azurerm_kubernetes_cluster.tf-ai-demo.kube_config.0.password<br \/>\n  client_certificate     = base64decode(azurerm_kubernetes_cluster.tf-ai-demo.kube_config.0.client_certificate)<br \/>\n  client_key             = base64decode(azurerm_kubernetes_cluster.tf-ai-demo.kube_config.0.client_key)<br \/>\n  cluster_ca_certificate = base64decode(azurerm_kubernetes_cluster.tf-ai-demo.kube_config.0.cluster_ca_certificate)<br \/>\n  }<br \/>\n}<\/p>\n<p>This code uses information from the AKS resource to populate the details in the <a href=\"https:\/\/helm.sh\/\">Helm<\/a> provider, letting you deploy resources into AKS pods using native Helm charts. <\/p>\n<p>With this Helm chart method, you deploy multiple resources using Terraform in the helm_release.tf file. This file sets up HashiCorp Vault, cert-manager, and Traefik Labs\u2019 ingress controller within the pods. The Vault configuration shows the Helm set functionality to customize the deployment:<\/p>\n<p>resource &#8220;helm_release&#8221; &#8220;vault&#8221; {<br \/>\n name       = &#8220;vault&#8221;<br \/>\n chart      = &#8220;hashicorp\/vault&#8221;<\/p>\n<p> set {<br \/>\n   name = &#8220;server.dev.enabled&#8221;<br \/>\n   value = &#8220;true&#8221;<br \/>\n }<br \/>\n set {<br \/>\n   name = &#8220;server.dev.devRootToken&#8221;<br \/>\n   value = &#8220;AzureA!dem0&#8221;<br \/>\n }<br \/>\n set {<br \/>\n   name = &#8220;ui.enabled&#8221;<br \/>\n   value = &#8220;true&#8221;<br \/>\n }<br \/>\n set {<br \/>\n   name = &#8220;ui.serviceType&#8221;<br \/>\n   value = &#8220;LoadBalancer&#8221;<br \/>\n }<br \/>\nset {<br \/>\n name = &#8220;ui.serviceNodePort&#8221;<br \/>\n value = &#8220;null&#8221;<br \/>\n}<br \/>\n set {<br \/>\n   name = &#8220;ui.externalPort&#8221;<br \/>\n   value = &#8220;8200&#8221;<br \/>\n }<br \/>\n}<\/p>\n<p>In this demo, the Vault server is customized to be in Dev Mode, have a defined root token, and enable external access to the pod via a load balancer using a specific port.<\/p>\n<p>At this stage you should have created a resource group with an AKS cluster and servicebus established. The containerized environment should look like this:<\/p>\n<p>If you want to log in to the Vault server at this stage, use the EXTERNAL-IP load balancer address with port 8200 (like this: <a href=\"http:\/\/%5Bexternal_ip%5D:8200\/\">http:\/\/[EXTERNAL_IP]:8200\/<\/a>) and log in using AzureA!dem0.<\/p>\n<h3>Step two: Secure<\/h3>\n<p>Now that you have established a base infrastructure in the cloud and the microservices environment, you are ready to configure Vault resources to integrate PKI into your environment. This centers around the pki_build.tf.second file, which you need to rename to remove the .second extension and make it executable as a Terraform file. After performing a terraform apply, as you are adding to the current infrastructure, add the elements to set up Vault with a root certificate and issue this within the pod.<\/p>\n<p>To do this, use the <a href=\"https:\/\/registry.terraform.io\/providers\/hashicorp\/vault\/latest\/docs\">Vault provider<\/a> and configure it to define a mount point for the PKI, a root certificate, role cert URL, issuer, and policy needed to build the PKI:<\/p>\n<p>resource &#8220;vault_mount&#8221; &#8220;pki&#8221; {<br \/>\n path        = &#8220;pki&#8221;<br \/>\n type        = &#8220;pki&#8221;<br \/>\n description = &#8220;This is a PKI mount for the Azure AI demo.&#8221;<\/p>\n<p> default_lease_ttl_seconds = 86400<br \/>\n max_lease_ttl_seconds     = 315360000<br \/>\n}<\/p>\n<p>resource &#8220;vault_pki_secret_backend_root_cert&#8221; &#8220;root_2023&#8221; {<br \/>\n  backend     = vault_mount.pki.path<br \/>\n  type        = &#8220;internal&#8221;<br \/>\n  common_name = &#8220;example.com&#8221;<br \/>\n  ttl         = 315360000<br \/>\n  issuer_name = &#8220;root-2023&#8221;<br \/>\n}<\/p>\n<p>Using the same Vault provider you can also configure Kubernetes authentication to create a role named &#8220;issuer&#8221; that binds the PKI policy with a Kubernetes service account named issuer:<\/p>\n<p>resource &#8220;vault_auth_backend&#8221; &#8220;kubernetes&#8221; {<br \/>\n  type = &#8220;kubernetes&#8221;<br \/>\n}<br \/>\nresource &#8220;vault_kubernetes_auth_backend_config&#8221; &#8220;k8_auth_config&#8221; {<br \/>\n  backend           = vault_auth_backend.kubernetes.path<br \/>\n  kubernetes_host   = azurerm_kubernetes_cluster.tf-ai-demo.kube_config.0.host<br \/>\n}<\/p>\n<p>resource &#8220;vault_kubernetes_auth_backend_role&#8221; &#8220;k8_role&#8221; {<br \/>\n  backend                          = vault_auth_backend.kubernetes.path<br \/>\n  role_name                        = &#8220;issuer&#8221;<br \/>\n  bound_service_account_names      = [&#8220;issuer&#8221;]<br \/>\n  bound_service_account_namespaces = [&#8220;default&#8221;,&#8221;cert-manager&#8221;]<br \/>\n  token_policies                   = [&#8220;default&#8221;, &#8220;pki&#8221;]<br \/>\n  token_ttl                        = 60<br \/>\n  token_max_ttl                    = 120<br \/>\n}<\/p>\n<p>The role connects the Kubernetes service account, issuer, which is created in the default namespace with the PKI Vault policy. The tokens returned after authentication are valid for 60 minutes. The Kubernetes service account name, issuer, is created using the Kubernetes provider, discussed in step three, below.  These resources are used to configure the model to use HashiCorp Vault to manage the PKI certification process.<\/p>\n<p>The image below shows how HashiCorp Vault interacts with cert-manager to issue certificates to be used by the application:<\/p>\n<h3>Step three: Enable<\/h3>\n<p>The final stage requires another tf apply as you are again adding to the environment. You now use  app_build.tf.third to build an application. To do this you need to rename app_build.tf.third to remove the .third extension and make it executable as a Terraform file. <\/p>\n<p>Interestingly,  the code in app_build.tf uses the <a href=\"https:\/\/registry.terraform.io\/providers\/hashicorp\/kubernetes\/latest\">Kubernetes provider resource <\/a>kubernetes_manifest. The manifest values are the HCL (HashiCorp Configuration Language) representation of a Kubernetes YAML manifest. (We converted an existing manifest from YAML to HCL to get the code needed for this deployment. You can do this using Terraform\u2019s built-in <a href=\"https:\/\/www.terraform.io\/docs\/configuration\/functions\/yamldecode.html\">yamldecode()<\/a> function or the <a href=\"https:\/\/github.com\/jrhouston\/tfk8s\">HashiCorp tfk8s tool<\/a>.)<\/p>\n<p>The code below represents an example of a service manifest used to create a service on port 80 to allow access to the store-admin app that was converted using the tfk8s tool:<\/p>\n<p>resource &#8220;kubernetes_manifest&#8221; &#8220;service_tls_admin&#8221; {<br \/>\n manifest = {<br \/>\n   &#8220;apiVersion&#8221; = &#8220;v1&#8221;<br \/>\n   &#8220;kind&#8221; = &#8220;Service&#8221;<br \/>\n   &#8220;metadata&#8221; = {<br \/>\n     &#8220;name&#8221; = &#8220;tls-admin&#8221;<br \/>\n     &#8220;namespace&#8221; = &#8220;default&#8221;<br \/>\n   }<br \/>\n   &#8220;spec&#8221; = {<br \/>\n     &#8220;clusterIP&#8221; = &#8220;10.0.160.208&#8221;<br \/>\n     &#8220;clusterIPs&#8221; = [<br \/>\n       &#8220;10.0.160.208&#8221;,<br \/>\n     ]<br \/>\n     &#8220;internalTrafficPolicy&#8221; = &#8220;Cluster&#8221;<br \/>\n     &#8220;ipFamilies&#8221; = [<br \/>\n       &#8220;IPv4&#8221;,<br \/>\n     ]<br \/>\n     &#8220;ipFamilyPolicy&#8221; = &#8220;SingleStack&#8221;<br \/>\n     &#8220;ports&#8221; = [<br \/>\n       {<br \/>\n         &#8220;name&#8221; = &#8220;tls-admin&#8221;<br \/>\n         &#8220;port&#8221; = 80<br \/>\n         &#8220;protocol&#8221; = &#8220;TCP&#8221;<br \/>\n         &#8220;targetPort&#8221; = 8081<br \/>\n       },<br \/>\n     ]<br \/>\n     &#8220;selector&#8221; = {<br \/>\n       &#8220;app&#8221; = &#8220;store-admin&#8221;<br \/>\n     }<br \/>\n     &#8220;sessionAffinity&#8221; = &#8220;None&#8221;<br \/>\n     &#8220;type&#8221; = &#8220;ClusterIP&#8221;<br \/>\n   }<br \/>\n }<br \/>\n}<\/p>\n<h3>Putting it all together<\/h3>\n<p>Once you\u2019ve deployed all the elements and applications, you use the certificate stored in a Kubernetes secret to apply the TLS configuration to inbound HTTPS traffic. In the example below, you associate &#8220;example-com-tls&#8221; \u2014 which includes the certificate created by Vault earlier \u2014 with the inbound IngressRoute deployment using the Terraform manifest:<\/p>\n<p>resource &#8220;kubernetes_manifest&#8221; &#8220;ingressroute_admin_ing&#8221; {<br \/>\n manifest = {<br \/>\n   &#8220;apiVersion&#8221; = &#8220;traefik.containo.us\/v1alpha1&#8221;<br \/>\n   &#8220;kind&#8221; = &#8220;IngressRoute&#8221;<br \/>\n   &#8220;metadata&#8221; = {<br \/>\n     &#8220;name&#8221; = &#8220;admin-ing&#8221;<br \/>\n     &#8220;namespace&#8221; = &#8220;default&#8221;<br \/>\n   }<br \/>\n   &#8220;spec&#8221; = {<br \/>\n     &#8220;entryPoints&#8221; = [<br \/>\n       &#8220;websecure&#8221;,<br \/>\n     ]<br \/>\n     &#8220;routes&#8221; = [<br \/>\n       {<br \/>\n         &#8220;kind&#8221; = &#8220;Rule&#8221;<br \/>\n         &#8220;match&#8221; = &#8220;Host(`admin.example.com`)&#8221;<br \/>\n         &#8220;services&#8221; = [<br \/>\n           {<br \/>\n             &#8220;name&#8221; = &#8220;tls-admin&#8221;<br \/>\n             &#8220;port&#8221; = 80<br \/>\n           },<br \/>\n         ]<br \/>\n       },<br \/>\n     ]<br \/>\n     &#8220;tls&#8221; = {<br \/>\n       &#8220;secretName&#8221; = &#8220;example-com-tls&#8221;<br \/>\n     }<br \/>\n   }<br \/>\n }<br \/>\n}<\/p>\n<p>To test access to the OpenAI store-admin site, you need a domain name. You use a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fully_qualified_domain_name\">FQDN<\/a> to access the site that you are going to protect using the generated certificate and HTTPS. <\/p>\n<p>To set this up, access your AKS cluster. The Kubernetes command-line client, <a href=\"https:\/\/kubernetes.io\/docs\/reference\/kubectl\/\">kubectl<\/a>, is already installed in your Azure Cloud Shell. You enter:<\/p>\n<p>kubectl get svc<\/p>\n<p>And should get the following output:<\/p>\n<p>NAME                       TYPE           CLUSTER-IP     EXTERNAL-IP     PORT(S)                      AGE<br \/>\nhello                      LoadBalancer   10.0.23.77     20.53.189.251   443:31506\/TCP                94s<br \/>\nkubernetes                 ClusterIP      10.0.0.1                 443\/TCP                      29h<br \/>\nmakeline-service           ClusterIP      10.0.40.79               3001\/TCP                     4h45m<br \/>\nmongodb                    ClusterIP      10.0.52.32               27017\/TCP                    4h45m<br \/>\norder-service              ClusterIP      10.0.130.203             3000\/TCP                     4h45m<br \/>\nproduct-service            ClusterIP      10.0.59.127              3002\/TCP                     4h45m<br \/>\nrabbitmq                   ClusterIP      10.0.122.75              5672\/TCP,15672\/TCP           4h45m<br \/>\nstore-admin                LoadBalancer   10.0.131.76    20.28.162.45    80:30683\/TCP                 4h45m<br \/>\nstore-front                LoadBalancer   10.0.214.72    20.28.162.47    80:32462\/TCP                 4h45m<br \/>\ntraefik                    LoadBalancer   10.0.176.139   20.92.218.96    80:32240\/TCP,443:32703\/TCP   29h<br \/>\nvault                      ClusterIP      10.0.69.111              8200\/TCP,8201\/TCP            29h<br \/>\nvault-agent-injector-svc   ClusterIP      10.0.31.52               443\/TCP                      29h<br \/>\nvault-internal             ClusterIP      None                     8200\/TCP,8201\/TCP            29h<br \/>\nvault-ui                   LoadBalancer   10.0.110.159   20.92.217.182   8200:32186\/TCP               29h<\/p>\n<p>Look for the traefik entry and note the EXTERNALl-IP (yours will be different than the one shown above). Then, on your local machine, create a localhost entry for admin.example.com to resolve to the address. For example on MacOS, you can use sudo nano \/etc\/hosts. If you need more help, search \u201ccreate localhost\u201d for your machine type.<\/p>\n<p>Now you can enter <a href=\"https:\/\/admin.example.com\/\">https:\/\/admin.example.com<\/a> in your browser and examine the certificate.<\/p>\n<p>This certificate is built from a root certificate authority (CA) held in Vault (example.com) and is valid against this issuer (admin.example.com) to allow for secure access over HTTPS. To verify the right certificate is being issued, expand the detail on our browser and view the cert name and serial number:<\/p>\n<p>You can then check this in Vault and see if the common name and serial numbers match.<\/p>\n<p>Terraform has configured all of the elements using the three-step approach shown in this post. To test the OpenAI application, follow <a href=\"https:\/\/learn.microsoft.com\/en-gb\/azure\/aks\/open-ai-quickstart?tabs=aoai#test-the-application\">Microsoft\u2019s instructions<\/a>. Skip to Step 4 and use  <a href=\"https:\/\/admin.example.com\/\">https:\/\/admin.example.com<\/a> to access the store-admin and the original store-front load balancer address to access the store-front.<\/p>\n<h3>DevOps for AI app development<\/h3>\n<p>To learn more and keep up with the latest trends in DevOps for AI app development, check out this Microsoft Reactor session with HashiCorp Co-Founder and CTO Armon Dadgar: <a href=\"https:\/\/www.youtube.com\/watch?v=Yj-EsoXFz58\">Using DevOps and copilot to simplify and accelerate development of AI apps<\/a>. It covers how developers can use <a href=\"https:\/\/github.com\/features\/copilot\">GitHub Copilot<\/a> with Terraform to create code modules for faster app development. You can get started by <a href=\"https:\/\/app.terraform.io\/public\/signup\/account?_gl=1*y2k3f1*_ga*MTM4ODIxMDM5OC4xNjc3MjY1MzI4*_ga_P7S46ZYEKW*MTcwNjU1NDUwOC4yMTMuMS4xNzA2NTU1NDgyLjI0LjAuMA..&amp;ajs_aid=586a7e51-5cbc-4bc9-b0cd-190690d71f44&amp;product_intent=terraform&amp;utm_source=email&amp;utm_medium=email&amp;utm_offer=webinar&amp;utm_campaign=24Q4_AMER_VIRTUALPARTNERDAY2024%3AZEROTRUSTSECURITY_WEBINAR&amp;utm_content=DD\">signing up for a free Terraform Cloud account<\/a>.<\/p>","protected":false},"excerpt":{"rendered":"<p>HashiCorp and Microsoft have partnered to create Terraform modules that follow Microsoft&#8217;s Azure Well-Architected Framework and best practices. In a [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":158,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[6],"tags":[],"class_list":["post-171","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-terraform"],"_links":{"self":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/171","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/comments?post=171"}],"version-history":[{"count":1,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/171\/revisions"}],"predecessor-version":[{"id":244,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/posts\/171\/revisions\/244"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media\/158"}],"wp:attachment":[{"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/media?parent=171"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/categories?post=171"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/rssfeedtelegrambot.bnaya.co.il\/index.php\/wp-json\/wp\/v2\/tags?post=171"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}