{"id":26197,"date":"2024-02-29T18:02:39","date_gmt":"2024-02-29T17:02:39","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=26197"},"modified":"2024-02-29T18:02:41","modified_gmt":"2024-02-29T17:02:41","slug":"terraform-x-go-challenges-when-interacting-with-terraform-through-go","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/29\/terraform-x-go-challenges-when-interacting-with-terraform-through-go\/","title":{"rendered":"Terraform x Go: Challenges when interacting with Terraform through Go"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction<\/h2>\n\n\n\n<div class=\"wp-block-cover\" style=\"min-height:347px;aspect-ratio:unset;\"><span aria-hidden=\"true\" class=\"wp-block-cover__background has-background-dim\"><\/span><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"905\" data-attachment-id=\"26198\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/29\/terraform-x-go-challenges-when-interacting-with-terraform-through-go\/untitled-project\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Untitled-Project.png\" data-orig-size=\"1061,938\" data-comments-opened=\"1\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}\" data-image-title=\"Untitled-Project\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Untitled-Project-1024x905.png\" class=\"wp-block-cover__image-background wp-image-26198\" alt=\"\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Untitled-Project-1024x905.png\" data-object-fit=\"cover\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Untitled-Project-1024x905.png 1024w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Untitled-Project-300x265.png 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Untitled-Project-768x679.png 768w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Untitled-Project.png 1061w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><div class=\"wp-block-cover__inner-container is-layout-flow wp-block-cover-is-layout-flow\">\n<p class=\"has-text-align-center has-large-font-size\">goTerra<\/p>\n<\/div><\/div>\n\n\n\n<p>In a recent project, some of my fellow students and I developed a basic hosting provider that allows a user to spin up Docker containers on a remote server, which is realized by using Terraform locally on the server.<\/p>\n\n\n\n<p>During this project, we developed a Go-based backend service that provided a REST API to the client and handled the connection to Terraform via RabbitMQ, authentication via Keycloak and data persistence with DynamoDB. As mentioned earlier, Terraform runs locally on the remote server and is fully automated by Go&#8217;s power. This sometimes became a challenge. This blog post briefly describes how we interacted with Terraform using Go and the problems we have encountered and those we have identified but not yet resolved, while working with Terraform.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Terraform<\/h3>\n\n\n\n<p>Terraform, an open-source tool created by HashiCorp for provisioning cloud infrastructure, allows describing infrastructure as code (IaC) in a simple, human-readable language called HCL (HashiCorp Configuration Language). This approach provides version-controllable, reusable, and collaborative means to manage infrastructure.<\/p>\n\n\n\n<p>Traditionally, managing Terraform involves writing HCL files, running terraform init to initialize the Terraform working directory, terraform plan to create an execution plan, and terraform apply to apply the desired changes. This process, while straightforward, can become complex and time-consuming as your infrastructure grows.<\/p>\n\n\n\n<p>This is where Go comes into play. In this blog post, I will share my experience of leveraging Go\u2019s features to automate the process of managing Terraform through HashiCorp&#8217;s <a href=\"https:\/\/pkg.go.dev\/github.com\/hashicorp\/terraform\">Terraform Go package<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Go: How to Interact with Terraform<\/h2>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Through HashiCorp&#8217;s <a href=\"https:\/\/pkg.go.dev\/github.com\/hashicorp\/terraform\">Terraform go package<\/a>, no direct interaction with the binary with OS commands is necessary.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">Avoidance of requiring the provision of binaries<\/h3>\n\n\n\n<p>Terraform thought about that as well and does supply a procedure to download the required binaries through the code.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code class=\"\" data-line=\"\">import (\n    &quot;context&quot;\n\n    version &quot;github.com\/hashicorp\/go-version&quot;\n    product &quot;github.com\/hashicorp\/hc-install\/product&quot;\n    releases &quot;github.com\/hashicorp\/hc-install\/releases&quot;\n    tfexec &quot;github.com\/hashicorp\/terraform-exec\/tfexec&quot;\n    log &quot;github.com\/rs\/zerolog\/log&quot;\n)\n\nfunc main() {\n    terraform_version := &quot;1.7.1&quot;\n    binary_install_dir := &quot;\/path\/to\/bins&quot;\n    terraform_cwd_dir := &quot;\/path\/to\/terraformFiles&quot;\n\n    \/\/ This specifies the exact version of the product, in this case Terraform, to install\n    installer := &amp;releases.ExactVersion{\n        Product:    product.Terraform,\n        Version:    version.Must(version.NewVersion(terraform_version)),\n        InstallDir: binary_install_dir,\n    }\n\n    \/\/ This installs the product and returns the path to the binary\n    \/\/ The binary will be installed in the directory specified by InstallDir \/ binary_install_dir\n    execPath, err := installer.Install(context.TODO())\n    if err != nil { log.Error().Msgf(&quot;Error occured %s&quot;, err) }\n\n    \/\/ This ensures that the binary is installed and returns a Terraform struct\n    \/\/ The Terraform struct is used to interact with the Terraform binary\n    tf, err := tfexec.NewTerraform(terraform_cwd_dir, execPath)\n    if err != nil { log.Error().Msgf(&quot;Error occured %s&quot;, err) }\n\n    \/\/ This returns the version of the installed Terraform binary\n    tfVersion, _, err := tf.Version(context.TODO(), true)\n    if err != nil { log.Error().Msgf(&quot;Error occured %s&quot;, err) }\n\n    log.Debug().Msgf(&quot;Terraform installed in version: %s&quot;, tfVersion)\n}<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Invoking Terraform commands<\/h3>\n\n\n\n<p>The basic command palette of Terraform, e.g. init, plan, apply, and destroy, is easily accessible. As shown in the code example below, which extends the code above, this is made very easy.<\/p>\n\n\n\n<pre class=\"wp-block-code has-small-font-size\"><code class=\"\" data-line=\"\">    var varFiles &#091;]string = &#091;]string{\n        &quot;\/path\/to\/terraform.tfvars.json&quot;,\n    }\n\n    \/\/ This runs the Terraform plan command, with the specified varFiles\n    \/\/ Sadly, there exists no generic PlanOption, so we have to create one for every Terraform command\n    tfPlanOpts := &#091;]tfexec.PlanOption{}\n    for _, varFile := range varFiles {\n        varFileOpt := tfexec.VarFile(varFile)\n        tfPlanOpts = append(tfPlanOpts, varFileOpt)\n    }\n\n    \/\/ This plans the Terraform configuration, which is the equivalent of running terraform plan\n    \/\/ This returns a boolean indicating whether the Terraform plan has a difference between the current state and the plan\n    plan_diff, err := tf.Plan(context.TODO(), tfPlanOpts...)\n    if err != nil { log.Error().Msgf(&quot;Error occured %s&quot;, err) }\n\n    if plan_diff {\n        log.Info().Msg(&quot;Terraform plan has a difference between the current state and the plan&quot;)\n    } else {\n        log.Info().Msg(&quot;Terraform plan has no difference between the current state and the plan&quot;)\n    }\n\n    tfApplyOpts := &#091;]tfexec.ApplyOption{}\n    for _, varFile := range varFiles {\n        varFileOpt := tfexec.VarFile(varFile)\n        tfApplyOpts = append(tfApplyOpts, varFileOpt)\n    }\n\n    \/\/ This applies the Terraform plan, which is the equivalent of running terraform apply\n    err = tf.Apply(context.TODO(), tfApplyOpts...)\n    if err != nil { log.Error().Msgf(&quot;Error occured %s&quot;, err) }\n\n    \/\/ This shows the Terraform state, which is the equivalent of running terraform show\n    state, err := tf.Show(context.TODO())\n    if err != nil { log.Error().Msgf(&quot;Error occured %s&quot;, err) }\n\n    log.Info().Msgf(&quot;New Terraform state %v&quot;, state)<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Problems I encountered<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">No dependency for binaries<\/h3>\n\n\n\n<p>As already mentioned in &#8220;Avoidance of requiring the provision of binaries&#8221;, Terraform supplies a solution to automate the process of downloading the necessary binaries. This can also be done through HashiCorp&#8217;s tool, <a href=\"https:\/\/github.com\/hashicorp\/hc-install\">hc-install<\/a>, available on GitHub.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Handling multiple Terraform states<\/h3>\n\n\n\n<p>When managing changes within the same environment concurrently in Terraform, consider using Terraform modules or leveraging multiple Terraform workspaces. Modules allow you to encapsulate and reuse configurations, promoting consistency and collaboration. Workspaces provide environmental isolation, making it easy to switch between different states. Additionally, changing the working directory dynamically using variables can help manage distinct environments effectively. Code-wise, this is easily appliable through changing Terraform&#8217;s current working directory, or, as can be seen in the code example, the value of the variable <code class=\"\" data-line=\"\">terraform_cwd_dir<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Clear text credentials in Terraform files<\/h3>\n\n\n\n<p>When working with Terraform, you often need to define sensitive information such as passwords, API keys, or access tokens. However, storing these secrets directly in your Terraform configuration or environment files is not a best practice.<\/p>\n\n\n\n<p>With the use of Terraform Vault, which is a secrets&#8217; management tool that securely stores and manages sensitive data. Credentials can be dynamically accessed by defining placeholders (references) in the Terraform configuration. During runtime, Terraform communicates with the Vault to dynamically generate short-lived based on policies and roles or access existing credentials.<\/p>\n\n\n\n<p>When retrieving secrets from the Vault, the data is still written in clear text to the following artifacts:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>State File: The state file generated by Terraform contains the secrets in plain text.<\/li>\n\n\n\n<li>Console Output: When Terraform runs, the secrets appear in the console output.<\/li>\n<\/ul>\n\n\n\n<p>However, the issue of clear text credentials in the state file cannot be easily fixed.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<p>To learn more about our project check out the following links:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>GitHub Repository: <a href=\"https:\/\/github.com\/incompetent-hosting-provider\/monorepo\" title=\"\">https:\/\/github.com\/incompetent-hosting-provider\/monorepo<\/a><\/li>\n\n\n\n<li>Blog post about monitoring with Prometheus: <a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/29\/why-system-monitoring-is-important-and-how-we-approached-it\/\" title=\"\">https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/29\/why-system-monitoring-is-important-and-how-we-approached-it\/<\/a><\/li>\n\n\n\n<li>Blog post about collections logs with Loki: <a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/29\/combining-zerolog-loki\/\" title=\"\">https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/29\/combining-zerolog-loki\/<\/a><\/li>\n\n\n\n<li>Blog post about using Keycloak as an auth provider with Go: <a href=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/29\/using-keycloak-as-iam-for-our-hosting-provider-service\/\" title=\"\">https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/29\/using-keycloak-as-iam-for-our-hosting-provider-service\/<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Introduction In a recent project, some of my fellow students and I developed a basic hosting provider that allows a user to spin up Docker containers on a remote server, which is realized by using Terraform locally on the server. During this project, we developed a Go-based backend service that provided a REST API to [&hellip;]<\/p>\n","protected":false},"author":1194,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1],"tags":[332,1016,424,514],"ppma_author":[1018],"class_list":["post-26197","post","type-post","status-publish","format-standard","hentry","category-allgemein","tag-go","tag-ihp","tag-system-engineering-and-management","tag-terraform"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":6338,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/03\/15\/kubernetesk8s-everywhere-but-how\/","url_meta":{"origin":26197,"position":0},"title":"Kubernetes (K8S) everywhere, but how?","author":"Immanuel Haag","date":"15. March 2019","format":false,"excerpt":"In the last months, nearly everybody has been talking about Kubernetes. It\u2019s incredible! This semester the Stuttgart Media University even held a training course on this topic. For DevOps or \u201ccloud-computing specialist\u201d mastering Kubernetes and the concepts around it is becoming more and more important. This blog post won\u2019t explain\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/up-and-running-with-kubernetes-13-638.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/up-and-running-with-kubernetes-13-638.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/up-and-running-with-kubernetes-13-638.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":21163,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/09\/15\/cloud-basierter-password-manager\/","url_meta":{"origin":26197,"position":1},"title":"Cloud basierter Password Manager","author":"bs103","date":"15. September 2021","format":false,"excerpt":"von Benjamin Schweizer (bs103) und Max Eichinger (me110) Abstract K\u00f6nnen Passwort Manager Anbieter meine Passw\u00f6rter lesen? Wir wollten auf Nummer sichergehen und haben unseren Eigenen entwickelt. Dieser Artikel zeigt auf welche Schritte wir hierf\u00fcr unternehmen mussten.Dabei haben wir unser Frontend mittels Flutter und unser Backend in AWS umgesetzt. Au\u00dferdem gehen\u2026","rel":"","context":"In &quot;Cloud Technologies&quot;","block_context":{"text":"Cloud Technologies","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/cloud-technologies\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/09\/image0-4-150x150.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/09\/image0-4-150x150.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/09\/image0-4-150x150.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/09\/image0-4-150x150.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2021\/09\/image0-4-150x150.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":26208,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/02\/29\/die-meere-der-systemtechnik-navigieren-eine-reise-durch-die-bereitstellung-einer-aktien-webanwendung-in-der-cloud\/","url_meta":{"origin":26197,"position":2},"title":"Die Meere der Systemtechnik navigieren: Eine Reise durch die Bereitstellung einer Aktien-Webanwendung in der Cloud","author":"mk306","date":"29. February 2024","format":false,"excerpt":"Auf zu neuen Ufern: Einleitung Die Cloud-Computing-Technologie hat die Art und Weise, wie Unternehmen Anwendungen entwickeln, bereitstellen und skalieren, revolutioniert. In diesem Beitrag, der im Rahmen der Vorlesung \u201c143101a System Engineering und Management\u201d entstanden ist, werden wir uns darauf konzentrieren, wie eine bereits bestehende Webanwendung zur Visualisierung und Filterung von\u2026","rel":"","context":"In &quot;Cloud Technologies&quot;","block_context":{"text":"Cloud Technologies","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/cloud-technologies\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Dashboard2-Kopie-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Dashboard2-Kopie-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Dashboard2-Kopie-1.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Dashboard2-Kopie-1.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Dashboard2-Kopie-1.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/02\/Dashboard2-Kopie-1.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":26265,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2024\/08\/30\/todogrow\/","url_meta":{"origin":26197,"position":3},"title":"TODO:Grow \u2014 A Cloud Sandbox for Aspiring Coders","author":"Dominik Mezler","date":"30. August 2024","format":false,"excerpt":"Give someone a program; you frustrate them for a day; teach them how to program, and you frustrate them for a lifetime. David Leinweber The following project was created within\/for the lecture \"Software Development for Cloud Computing\" (113479A) in the summer semester of 2024. I never worked with any ...\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/08\/architecture-2.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/08\/architecture-2.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/08\/architecture-2.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2024\/08\/architecture-2.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":23412,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2022\/08\/22\/migration-einer-rest-api-in-die-cloud\/","url_meta":{"origin":26197,"position":4},"title":"Migration einer REST API in die Cloud","author":"Raphael Kienh\u00f6fer","date":"22. August 2022","format":false,"excerpt":"Im Rahmen der Vorlesung \"Software Development f\u00fcr Cloud Computing\" haben wir uns zum Ziel gesetzt, eine bereits bestehende REST API in die Cloud zu migrieren.","rel":"","context":"In &quot;Cloud Technologies&quot;","block_context":{"text":"Cloud Technologies","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/cloud-technologies\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/08\/OnPrem.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/08\/OnPrem.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/08\/OnPrem.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2022\/08\/OnPrem.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":23679,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2022\/08\/31\/jobsuche-portal\/","url_meta":{"origin":26197,"position":5},"title":"Jobsuche Portal","author":"ag164","date":"31. August 2022","format":false,"excerpt":"SS22 - Dev4Cloud Projekt - von Robin H\u00e4rle und Anton Gerdts Ideenfindung \u00a0\u00a0\u00a0 Zu Beginn der Ideenfindungsphase f\u00fcr unser Projekt sahen wir uns die verschiedenen Apis auf Bund.dev an, um uns von der Thematik der verf\u00fcgbaren Daten inspirieren zu lassen. Wir entschieden uns ohne lange abzuw\u00e4gen daf\u00fcr ein Jobsuche-Portal mit\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":1018,"user_id":1194,"is_guest":0,"slug":"maximilian_tellmann","display_name":"Maximilian Tellmann","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/c50c5c72d3917abd292ee893cd012b2e903fdd7dcd909a6a41517a8ef59a5c76?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/26197","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/1194"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=26197"}],"version-history":[{"count":2,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/26197\/revisions"}],"predecessor-version":[{"id":26203,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/26197\/revisions\/26203"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=26197"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=26197"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=26197"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=26197"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}