{"id":33123,"date":"2019-10-31T21:50:52","date_gmt":"2019-10-31T18:50:52","guid":{"rendered":"https:\/\/prohoster.info\/blog\/terraformer-infrastructure-to-code\/"},"modified":"2019-10-31T21:50:52","modified_gmt":"2019-10-31T18:50:52","slug":"terraformer-infrastructure-to-code","status":"publish","type":"post","link":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/terraformer-infrastructure-to-code","title":{"rendered":"Terraformer \u2014 Infraestructura como C\u00f3digo","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Terraformer \u2014 Infraestructura como C\u00f3digo\" src=\"\/wp-content\/uploads\/2019\/05\/d97414f6b4608dbb4ec7f582b7001773.jpg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\nMe gustar\u00eda hablar sobre una nueva herramienta CLI que he desarrollado para resolver un viejo problema. <\/p>\n<h3>Problema<\/h3>\n<p>\nTerraform se ha convertido en un est\u00e1ndar en la comunidad DevOps\/Cloud\/IT desde hace tiempo. Es una herramienta muy conveniente y \u00fatil para gestionar infraestructura como c\u00f3digo. Hay muchas ventajas en Terraform, as\u00ed como muchos baches y peros. <br \/>\nCon Terraform es muy f\u00e1cil crear cosas nuevas y luego gestionarlas, modificarlas o eliminarlas. Pero, \u00bfqu\u00e9 hacer con aquellos que tienen una gran infraestructura en la nube que no fue creada a trav\u00e9s de Terraform? Reescribir y recrear toda la nube resulta costoso y poco seguro. <br \/>\nHe enfrentado este problema en dos trabajos, el ejemplo m\u00e1s simple es querer que todo est\u00e9 en Git en forma de archivos Terraform, y tienes m\u00e1s de 250 buckets, escribirlos a mano para Terraform resulta excesivo. <br \/>\nHay <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/hashicorp\/terraform\/issues\/581\">problema<\/a><\/noindex> desde 2014 existe un issue en Terraform que fue cerrado en 2016 con la esperanza de que se implementara la opci\u00f3n de importaci\u00f3n.<\/p>\n<p>En general, todo es como se muestra en la imagen, pero de derecha a izquierda.<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>Advertencia: El autor no vive en Rusia desde hace medio vida y escribe poco en ruso. Cuidado con los errores ortogr\u00e1ficos.<\/p>\n<h3>Soluciones<\/h3>\n<p>\n1. Hay soluciones antiguas y ya existentes para AWS <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dtan4\/terraforming\">terraforming<\/a><\/noindex>. Cuando intent\u00e9 obtener mis m\u00e1s de 250 buckets a trav\u00e9s de \u00e9l, me di cuenta de que estaba lleno de problemas. AWS ha introducido muchas nuevas opciones desde entonces, y terraforming no las conoce, adem\u00e1s, usa ruby. <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dtan4\/terraforming\/blob\/master\/lib\/terraforming\/template\/tf\/s3.erb\">los templates se ven escu\u00e1lidos<\/a><\/noindex>. Despu\u00e9s de dos noches, envi\u00e9 <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/dtan4\/terraforming\/pull\/396\">una solicitud de extracci\u00f3n<\/a><\/noindex> para a\u00f1adir m\u00e1s funcionalidades y entend\u00ed que este enfoque no era adecuado en absoluto. <br \/>\nC\u00f3mo funciona terraforming: toma datos del SDK de AWS y genera tf y tfstate a trav\u00e9s de un template. <br \/>\nAqu\u00ed hay 3 problemas:<br \/>\n1. Siempre habr\u00e1 retrasos en las actualizaciones<br \/>\n2. Los archivos tf a veces est\u00e1n da\u00f1ados <br \/>\n3. tfstate se genera por separado de tf y no siempre coinciden<br \/>\nEn general, es complicado obtener un resultado donde `terraform plan` indique que no hay cambios<\/p>\n<p>2. `terraform import` \u2014 es un comando incorporado en terraform. \u00bfC\u00f3mo funciona? <br \/>\nEscribes un archivo TF vac\u00edo con el nombre y tipo de recurso, luego ejecutas `terraform import` y pasas el ID del recurso. Terraform se comunica con el proveedor, obtiene los datos y crea el archivo tfstate. <br \/>\nAqu\u00ed hay 3 problemas:<br \/>\n1. Solo obtenemos el archivo tfstate, mientras que el tf est\u00e1 vac\u00edo y hay que escribirlo a mano o convertirlo desde el tfstate.<br \/>\n2. Solo puede trabajar con un recurso a la vez y no soporta todos los recursos. \u00bfY qu\u00e9 debo hacer de nuevo con m\u00e1s de 250 buckets?<br \/>\n3. Hay que conocer el ID de los recursos, es decir, hay que envolverlo en un c\u00f3digo que obtenga la lista de recursos.<br \/>\nEn general, el resultado es parcial y no escala bien.<\/p>\n<h3>Mis decisiones<br \/>\n<\/h3>\n<p>Requisitos:<br \/>\n1. Capacidad para crear archivos tf y tfstate a partir de recursos. Por ejemplo, descargar todos los buckets \/ grupos de seguridad \/ balanceadores de carga y que 'terraform plan' devuelva que no hay cambios<br \/>\n2. Necesito 2 nubes GCP + AWS<br \/>\n3. Una soluci\u00f3n global que sea f\u00e1cil de actualizar cada vez y que no requiera dedicar 3 d\u00edas de trabajo a cada recurso<br \/>\n4. Hacerlo de c\u00f3digo abierto \u2014 es un problema que todos tienen<\/p>\n<p>Lenguaje Go \u2014 por eso lo amo, y hay una biblioteca para crear archivos HCL que se utiliza en terraform + mucho c\u00f3digo en terraform que puede ser \u00fatil<\/p>\n<h3>Ruta<\/h3>\n<p>\nPrimer intento<br \/>\nComenc\u00e9 con una opci\u00f3n simple. Acceder a la nube a trav\u00e9s de SDK para obtener el recurso necesario y convertirlo en campos para terraform. El intento fracas\u00f3 de inmediato con el grupo de seguridad porque no me gust\u00f3 pasar 1.5 d\u00edas convirtiendo solo el grupo de seguridad (hay muchos recursos). Es largo y luego los campos pueden cambiar \/ a\u00f1adirse<\/p>\n<p>Segundo intento<br \/>\nBasado en la idea descrita <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/hashicorp\/terraform\/issues\/15608\">aqu\u00ed<\/a><\/noindex>. Simplemente tomar y convertir tfstate a tf. Todos los datos est\u00e1n ah\u00ed y los campos son los mismos. \u00bfC\u00f3mo obtener un tfstate completo para muchos recursos? Aqu\u00ed la ayuda vino del comando 'terraform refresh'. Terraform toma todos los recursos en tfstate y, por ID, extrae los datos de ellos y los escribe en tfstate. Es decir, crear un tfstate vac\u00edo solo con los nombres y ID, ejecutar 'terraform refresh' y obtenemos tfstate completo. \u00a1Hurra!<br \/>\nAhora nos ocuparemos de la escritura recursiva de un convertidor para tfstate a tf. Para aquellos que nunca han le\u00eddo tfstate, esto es JSON, pero especial. <br \/>\nAqu\u00ed est\u00e1 su parte importante attributes<\/p>\n<pre><code class=\"javascript\"> \"attributes\": {\n                            \"id\": \"default\/backend-logging-load-deployment\",\n                            \"metadata.#\": \"1\",\n                            \"metadata.0.annotations.%\": \"0\",\n                            \"metadata.0.generate_name\": \"\",\n                            \"metadata.0.generation\": \"24\",\n                            \"metadata.0.labels.%\": \"1\",\n                            \"metadata.0.labels.app\": \"backend-logging\",\n                            \"metadata.0.name\": \"backend-logging-load-deployment\",\n                            \"metadata.0.namespace\": \"default\",\n                            \"metadata.0.resource_version\": \"109317427\",\n                            \"metadata.0.self_link\": \"\/apis\/apps\/v1\/namespaces\/default\/deployments\/backend-logging-load-deployment\",\n                            \"metadata.0.uid\": \"300ecda1-4138-11e9-9d5d-42010a8400b5\",\n                            \"spec.#\": \"1\",\n                            \"spec.0.min_ready_seconds\": \"0\",\n                            \"spec.0.paused\": \"false\",\n                            \"spec.0.progress_deadline_seconds\": \"600\",\n                            \"spec.0.replicas\": \"1\",\n                            \"spec.0.revision_history_limit\": \"10\",\n                            \"spec.0.selector.#\": \"1\",\n<\/code><\/pre>\n<p>\nAqu\u00ed hay:<br \/>\n1. id \u2014 cadena<br \/>\n2. metadata \u2014 array de tama\u00f1o 1 y contiene un objeto con los campos que se describen a continuaci\u00f3n<br \/>\n3. spec \u2014 hash de tama\u00f1o 1 y contiene key,value<br \/>\nEn resumen, es un formato divertido, todo puede ser en profundidad tambi\u00e9n a varios niveles.<\/p>\n<pre><code class=\"javascript\">                   \"spec.#\": \"1\",\n                            \"spec.0.min_ready_seconds\": \"0\",\n                            \"spec.0.paused\": \"false\",\n                            \"spec.0.progress_deadline_seconds\": \"600\",\n                            \"spec.0.replicas\": \"1\",\n                            \"spec.0.revision_history_limit\": \"10\",\n                            \"spec.0.selector.#\": \"1\",\n                            \"spec.0.selector.0.match_expressions.#\": \"0\",\n                            \"spec.0.selector.0.match_labels.%\": \"1\",\n                            \"spec.0.selector.0.match_labels.app\": \"backend-logging-load\",\n                            \"spec.0.strategy.#\": \"0\",\n                            \"spec.0.template.#\": \"1\",\n                            \"spec.0.template.0.metadata.#\": \"1\",\n                            \"spec.0.template.0.metadata.0.annotations.%\": \"0\",\n                            \"spec.0.template.0.metadata.0.generate_name\": \"\",\n                            \"spec.0.template.0.metadata.0.generation\": \"0\",\n                            \"spec.0.template.0.metadata.0.labels.%\": \"1\",\n                            \"spec.0.template.0.metadata.0.labels.app\": \"backend-logging-load\",\n                            \"spec.0.template.0.metadata.0.name\": \"\",\n                            \"spec.0.template.0.metadata.0.namespace\": \"\",\n                            \"spec.0.template.0.metadata.0.resource_version\": \"\",\n                            \"spec.0.template.0.metadata.0.self_link\": \"\",\n                            \"spec.0.template.0.metadata.0.uid\": \"\",\n                            \"spec.0.template.0.spec.#\": \"1\",\n                            \"spec.0.template.0.spec.0.active_deadline_seconds\": \"0\",\n                            \"spec.0.template.0.spec.0.container.#\": \"1\",\n                            \"spec.0.template.0.spec.0.container.0.args.#\": \"3\",<\/code><\/pre>\n<p>\nEn general, si alguien quiere un problema de programaci\u00f3n para la entrevista, simplemente p\u00eddanle que escriba un parser para esto \ud83d\ude42.<br \/>\nDespu\u00e9s de muchos intentos de escribir un parser sin errores, encontr\u00e9 parte de \u00e9l en el c\u00f3digo de terraform, y de hecho, la parte m\u00e1s importante. Y todo parec\u00eda funcionar bien.<\/p>\n<p>Intento tres.<br \/>\nUn proveedor de terraform es un binario que contiene c\u00f3digo con todos los recursos y la l\u00f3gica para trabajar con las API de nubes. Cada nube tiene su propio proveedor y terraform simplemente los llama a trav\u00e9s de su protocolo RPC entre dos procesos.<br \/>\nAhora decid\u00ed llamar directamente a los proveedores de terraform a trav\u00e9s de llamadas RPC. As\u00ed sali\u00f3 bonito y permiti\u00f3 cambiar los proveedores de terraform por versiones m\u00e1s nuevas y obtener nuevas funcionalidades sin cambiar el c\u00f3digo. Tambi\u00e9n result\u00f3 que no todos los campos en tfstate deben estar en tf, \u00bfy c\u00f3mo saberlo? Solo preguntando al proveedor sobre ello. Luego comenz\u00f3 otra pornograf\u00eda recursiva sobre la construcci\u00f3n de expresiones regulares con el l\u00edo de buscar campos dentro de tfstate en todos los niveles en profundidad.<\/p>\n<p>Al final, result\u00f3 ser una herramienta CLI \u00fatil que tiene una infraestructura com\u00fan para todos los proveedores de terraform y se puede agregar f\u00e1cilmente uno nuevo. Tambi\u00e9n, la adici\u00f3n de recursos requiere poco c\u00f3digo. Adem\u00e1s, hay ventajas como la conexi\u00f3n entre recursos. Por supuesto, hubo muchos problemas diferentes que no se pueden describir todos.<br \/>\nLlam\u00e9 a la herramienta Terrafomer. <\/p>\n<h3>Intent\u00e9 no escribir mucho, pero a\u00fan as\u00ed me parece que la entrada result\u00f3 bastante larga. Las dem\u00e1s caracter\u00edsticas de unRAID son bastante simples de configurar, sobre todo porque todo se configura con el rat\u00f3n.<\/h3>\n<p>\nCon Terrafomer generamos de 500,000 a 700,000 l\u00edneas de c\u00f3digo tf + tfstate en dos nubes. Pudimos tomar cosas heredadas y empezar a trabajarlas solo a trav\u00e9s de terraform, como en las mejores ideas de infraestructura como c\u00f3digo. Es pura magia cuando tomas una nube enorme y obtienes, con un comando, su representaci\u00f3n en archivos terraform. Luego, solo grep\/replace\/git y as\u00ed sucesivamente.<\/p>\n<p>Analic\u00e9 y orden\u00e9, obtuve permisos. Lo publiqu\u00e9 en GitHub para todos el jueves (02.05.19). <noindex><a rel=\"nofollow\" href=\"https:\/\/github.com\/GoogleCloudPlatform\/terraformer\">github.com\/GoogleCloudPlatform\/terraformer<\/a><\/noindex><br \/>\nYa obtuvo 600 estrellas, 2 pull requests agregando soporte para openstack y kubernetes. Buenos comentarios. En general, es un proyecto \u00fatil para la gente.<br \/>\nSe lo recomiendo a todos los que quieran empezar a trabajar con Terraform y no quieran reescribir todo para ello. <br \/>\nEstar\u00e9 encantado de recibir pull requests, issues, estrellas.<\/p>\n<p>Demo<br \/>\n<noindex><img decoding=\"async\" alt=\"Terraformer \u2014 Infraestructura como C\u00f3digo\" src=\"\/wp-content\/uploads\/2019\/05\/76f10055b9106590f72c4e22e4d4e6d5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/noindex><br \/>\n<br \/>Fuente: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/450410\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u0425\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u043d\u043e\u0432\u044b\u0439 CLI tool \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b \u0434\u043b\u044f \u0440\u0435\u0448\u0435\u043d\u0438\u044f \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0430\u0440\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b. \u041f\u0440\u043e\u0431\u043b\u0435\u043c\u0430 Terraform \u0443\u0436\u0435 \u0434\u0430\u0432\u043d\u043e \u0441\u0442\u0430\u043b \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043e\u043c \u0432 Devops\/Cloud\/IT \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435. \u0412\u0435\u0449\u044c \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u0430\u044f \u0438 \u043f\u043e\u043b\u0435\u0437\u043d\u0430\u044f \u0447\u0442\u043e\u0431 \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u0441\u044f infrastructure as code. \u0415\u0441\u0442\u044c \u043c\u043d\u043e\u0433\u043e \u043f\u0440\u0435\u043b\u0435\u0441\u0442\u0435\u0439 \u0432 Terraform \u0430 \u0442\u0430\u043a \u0436\u0435 \u043c\u043d\u043e\u0433\u043e \u0432\u0438\u043b\u043e\u043a, \u043e\u0441\u0442\u0440\u044b\u0445 \u043d\u043e\u0436\u0435\u0439 \u0438 \u0433\u0440\u0430\u0431\u043b\u0435\u0439. \u0421 Terraform \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0432\u0435\u0449\u0438 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24869,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-33123","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.2 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u0425\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u043d\u043e\u0432\u044b\u0439 CLI tool \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/terraformer-infrastructure-to-code\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.2\" \/>\n\t\t<meta property=\"og:locale\" content=\"es_ES\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Terraformer \u2014 Infrastructure To Code | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u0425\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u043d\u043e\u0432\u044b\u0439 CLI tool \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/terraformer-infrastructure-to-code\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:50:52+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-10-31T18:50:52+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Terraformer \u2014 Infrastructure To Code | ProHoster","description":"Me gustar\u00eda hablar sobre la nueva herramienta CLI que escrib\u00ed.","canonical_url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/terraformer-infrastructure-to-code","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"es_ES","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Terraformer \u2014 Infrastructure To Code | ProHoster","og:description":"\u0425\u043e\u0442\u0435\u043b \u0431\u044b \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u0440\u043e \u043d\u043e\u0432\u044b\u0439 CLI tool \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043d\u0430\u043f\u0438\u0441\u0430\u043b.","og:url":"https:\/\/prohoster.info\/es\/blog\/administrirovanie\/terraformer-infrastructure-to-code","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:50:52+00:00","article:modified_time":"2019-10-31T18:50:52+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"33123","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 14:02:48","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:46:23","updated":"2026-01-21 14:02:48","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/33123","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/comments?post=33123"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/posts\/33123\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media\/24869"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/media?parent=33123"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/categories?post=33123"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/es\/wp-json\/wp\/v2\/tags?post=33123"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}