{"id":6338,"date":"2019-03-15T22:02:26","date_gmt":"2019-03-15T21:02:26","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=6338"},"modified":"2023-08-06T21:47:28","modified_gmt":"2023-08-06T19:47:28","slug":"kubernetesk8s-everywhere-but-how","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/03\/15\/kubernetesk8s-everywhere-but-how\/","title":{"rendered":"Kubernetes (K8S) everywhere, but how?"},"content":{"rendered":"\n<div class=\"wp-block-cover is-light\"><span aria-hidden=\"true\" class=\"wp-block-cover__background has-background-dim-0 has-background-dim\"><\/span><img loading=\"lazy\" decoding=\"async\" width=\"6000\" height=\"3574\" data-attachment-id=\"6341\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/03\/15\/kubernetesk8s-everywhere-but-how\/articleimage-2\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/articleimage-1.jpg\" data-orig-size=\"6000,3574\" 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;1&quot;}\" data-image-title=\"articleimage\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/articleimage-1-1024x610.jpg\" class=\"wp-block-cover__image-background wp-image-6341\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/articleimage-1.jpg\" data-object-fit=\"cover\" srcset=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/articleimage-1.jpg 6000w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/articleimage-1-300x179.jpg 300w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/articleimage-1-768x457.jpg 768w, https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/articleimage-1-1024x610.jpg 1024w\" sizes=\"auto, (max-width: 6000px) 100vw, 6000px\" \/><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\"><br><\/p>\n<\/div><\/div>\n\n\n\n<p>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 K<g class=\"gr_ gr_27 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling\" id=\"27\" data-gr-id=\"27\">ubernetes<\/g> and the concepts around it is becoming more and more important. <\/p>\n\n\n\n<!--more-->\n\n\n\n<p>This blog post won\u2019t explain the nature of Kubernetes, so it&#8217;s not a tutorial. This blog post is written for people who have experience with Kubernetes. It will give you an overview of the current possibilities on how to install a K8S cluster and the most important installation types.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/www.mememaker.net\/api\/bucket?path=static\/img\/memes\/full\/2018\/Jul\/3\/6\/kuberenetes-127574.png\" alt=\"\"\/><\/figure>\n\n\n\n<p>Besides, this article is going to give a short excursion on configuration management\/infrastructure as code. Some K8S-Cluster installation tools rely on these concepts. If you are a K8S beginner &#8211; I recommend this short video that will give a good explanation:<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<span class=\"embed-youtube\" style=\"text-align:center; display: block;\"><iframe loading=\"lazy\" class=\"youtube-player\" width=\"640\" height=\"360\" src=\"https:\/\/www.youtube.com\/embed\/4ht22ReBjno?version=3&#038;rel=1&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;fs=1&#038;hl=en-US&#038;autohide=2&#038;start=18&#038;wmode=transparent\" allowfullscreen=\"true\" style=\"border:0;\" sandbox=\"allow-scripts allow-same-origin allow-popups allow-presentation allow-popups-to-escape-sandbox\"><\/iframe><\/span>\n<\/div><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>The official documentation is also very helpful. If you want to test Kubernetes the first time I recommend <a href=\"https:\/\/labs.play-with-k8s.com\/\">Play with Kubernetes<\/a> and <a href=\"https:\/\/training.play-with-kubernetes.com\/\">Play with Kubernetes Classroom<\/a> &nbsp;&#8211; these are some handy platforms which will teach you the first CLI steps with Kubernetes. <br><\/p>\n\n\n\n<p>Now I\u2019ll introduce some installation variations of Kubernetes. As a guide, I used the official documentation and my own experience as DevOps. Be prepared, I&#8217;m not able to mention all solutions out there!<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Local installations on your Device<\/strong><\/h2>\n\n\n\n<p>This Installation type only appears on your local device &#8211; let\u2019s say your laptop. So if there is more than one cluster node (It depends on the tool you use) they are not physically separated, the nodes are only logic separated units within Docker containers. &nbsp;I recommend using this type of installation if you want to try Kubernetes more extensively than the &#8216;play with Kubernetes&#8217; platform. If you will work on k8s-projects in the future, such an installation could be very helpful. <\/p>\n\n\n\n<p>The table below gives an overview by operating system, number of nodes and complexity.<\/p>\n\n\n\n<figure class=\"wp-block-table aligncenter is-style-stripes\"><table><tbody><tr><td><strong>Name<\/strong><\/td><td><strong>OS<\/strong><\/td><td><strong>Nodes<\/strong><\/td><td><strong>K8s V.<\/strong><\/td><td><strong>Features<\/strong><\/td><td><strong>Complexity &amp; Notes<\/strong><\/td><\/tr><tr><td><a href=\"https:\/\/blog.docker.com\/2018\/07\/kubernetes-is-now-available-in-docker-desktop-stable-channel\/\">Docker Desktop<\/a><\/td><td>Windows<br><br>MacOS<\/td><td>1<\/td><td>v1.10.11<br><br><\/td><td>Configurable through Docker GUI<br><br><\/td><td>very easy to install, <br>but it&#8217;s a minimalistic installation, so you have to install additional stuff like the dashboard by your own<\/td><\/tr><tr><td><a href=\"https:\/\/github.com\/kubernetes\/minikube\">Minikube<\/a><\/td><td>Linux<br>MacOS<br><br>Windows<br><br><\/td><td>1<\/td><td>v1.13.4<\/td><td>Dashboard<br><br>Multi hypervisor support (kvm, hyperkit, hyperV, VMware, VB &amp; baremetal Docker)<br><br>Addons<br><br>GPU<\/td><td>very easy to setup but a bit harder than the docker-desktop installation<\/td><\/tr><tr><td><a href=\"https:\/\/github.com\/kubernetes-sigs\/kubeadm-dind-cluster\">Kubeadm-dind<\/a> <\/td><td>Linux <br>MacOS (no IPv6-Support)<br><br><\/td><td>N<\/td><td>v1.13.x<\/td><td>Per default no additional features installed (if you want you have to maintain it by yourself)<\/td><td>Needs the most experience but multi node-setup support is available <\/td><\/tr><tr><td><a href=\"https:\/\/microk8s.io\/\">microk8s<\/a><\/td><td>Linux<\/td><td>1<\/td><td>v1.11.3<\/td><td>Dashboard<br><br>No Hypervisors needed<br><br>Metrics supported by Grafana<br><br>Istio <br><br>Addons<br><br>GPU<\/td><td>it uses a snap environment, not available on all distros. But through this, good isolation from your other installations are given <br><br>Relative new \u2192 not so matured as the other solutions. The additional features are a charm<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"has-text-align-center\">Table 1: Local installation types<\/p>\n\n\n\n<p>So it depends on what you are looking for. Most of us out there have <strong><em>Docker-Desktop<\/em><\/strong> already installed &#8211; in my opinion, it&#8217;s the<em> fastest way<\/em> to get started with a local K8S installation with this inbuilt Docker feature. If you need some <em>additional features <\/em>like the K8S-Dashboard, use <strong><em>Minikube<\/em><\/strong>. <\/p>\n\n\n\n<p>You have a Linux OS installed on your local machine? Then I recommend <strong><em>Minikube<\/em><\/strong>. If you use an <g class=\"gr_ gr_24 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del multiReplace\" id=\"24\" data-gr-id=\"24\">Ubuntu based<\/g> distribution, you should give the <strong><em>microk8s<\/em><\/strong> installation a try. <strong><em>Microk8s<\/em><\/strong> seems to have a promising future. And if you want to <g class=\"gr_ gr_7 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del\" id=\"7\" data-gr-id=\"7\">setup<\/g> and test a service mesh implementation,  the automated Istio installation is also included! <\/p>\n\n\n\n<p>If you are experienced enough and looking for a <em>multi-node Cluster<\/em> on <em>MacOS<\/em> or <em>Linux, <\/em>try installing the cluster manually. Take for example 5 docker containers, install K8S with <em>Kubeadm<\/em> and connect them together. A <em>faster and more comfortable<\/em> opportunity is the project <strong><em>Kubeadm-dind<\/em><\/strong> which is a collection of bash scripts that simplify the deployment steps.<\/p>\n\n\n\n<p>There are some other local installation solutions like <a href=\"https:\/\/docs.okd.io\/latest\/minishift\/\">Minishift<\/a> and <a href=\"https:\/\/github.com\/IBM\/deploy-ibm-cloud-private\">IBM Cloud Private-CE<\/a>. These projects install more than Kubernetes and feel like bloatware if you only want to test some Kubernetes specific tasks! Use some of the above-mentioned tools in this case.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Cloud Installation Solutions<\/h2>\n\n\n\n<div class=\"wp-block-columns has-2-columns is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/memegenerator.net\/img\/instances\/76154921\/installed-kubernetes-yet.jpg\" alt=\"\" width=\"261\" height=\"193\"\/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image is-resized\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/up-and-running-with-kubernetes-13-638.jpg\" alt=\"\" width=\"347\" height=\"196\"\/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>Going for ready-made hosted services like a cluster EKS provided by Amazon and configured ready is not considered. As already mentioned, this article is intended to show how installation and configuration can be made easier. So this paragraph won&#8217;t go into how to manually build a backbone network by booting several virtual machines, setting up a network and installing a cluster from scratch by hand. If you want to do this instead, have a look at this link: <a href=\"https:\/\/kubernetes.io\/docs\/setup\/scratch\/\">https:\/\/kubernetes.io\/docs\/setup\/scratch\/<\/a>. The focus lies on running and demonstrating reproducible and automatable solutions. It might even be considerable to integrate such a setup into CI\/CD pipelines so that developers get their own environments including clusters as soon as something is checked into the VCS. So the developers can work even closer to a productive world. <\/p>\n\n\n\n<p>Tools like <strong><em>Ansible<\/em><\/strong> or <em><strong>Terraform<\/strong><\/em> offer such automated and reproducible results. Therefore a short excursus: <\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Software-Configuration Management vs. &nbsp;Infrastructure as Code ( IaC )  <\/strong><\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>\u201cConfiguration management (CM) is a governance and systems engineering process for ensuring consistency among physical and logical assets in an operational environment. The configuration management process seeks to identify and track individual configuration items (CIs), documenting functional capabilities and interdependencies. &nbsp;Administrators, technicians and software developers can use configuration management tools to verify the effect a change to one configuration item has on other systems.\u201d <\/em><\/p>\n<cite>https:\/\/searchitoperations.techtarget.com\/definition\/configuration-management-CM <\/cite><\/blockquote>\n\n\n\n<p>\t\t\t\t\t\tVS.<br><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><em>\u201cInfrastructure as code, also referred to as IaC, is a type of IT setup wherein developers or operations teams automatically manage and provision the technology stack for an application through software, rather than using a manual process to configure discrete hardware devices and operating systems. Infrastructure as code is sometimes referred to as programmable or software-defined infrastructure.\u201d \ufeff<\/em><\/p>\n<cite>https:\/\/searchitoperations.techtarget.com\/definition\/Infrastructure-as-Code-IAC <\/cite><\/blockquote>\n\n\n\n<p>The distinction between the two definitions is therefore not easy. Furthermore there is a constant lack of clarity about this on the Internet. The keyword <em>\u201cSoftware-defined infrastructure\u201d<\/em> can also be found out there. Let\u2019s ignore this keyword to simplify the distinction.<\/p>\n\n\n\n<p>I personally understood the two concepts that way and will use them likewise after my research:<br><\/p>\n\n\n\n<p>Infrastructure as code is the creation (build) of infrastructure components through code definitions such as describing virtual machines. It depends on how much resources a VM can get at startup, which networks the VM should have available and which OS is used, etc. So IaC always refers to a hardware-close approach. Configurations management refers more to the software perspective. IaC-Tools are also named \u201cOrchestrators\u201d. <\/p>\n\n\n\n<p>Software-Configuration Management tools help to install and configure software with desired states. So if you want to install Nginx in a specific version and some virtual hosts you can do this for example with <strong><em>Ansible<\/em><\/strong>.<br><\/p>\n\n\n\n<p>Conclusion: <br>First you define for example a virtual machine through IaC and then you provision the desired state of the virtual machine with a Software-Configuration Management tool. <br><\/p>\n\n\n\n<p>But Configuration Management Tools can also define Infrastructure &#8211; the differentiation is very subtle. In my opinion, there are terminology issues and it depends on how you use the tools mentioned in table 2.<\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td><strong>Tool<\/strong><\/td><td><a href=\"https:\/\/www.chef.io\/\">Chef<\/a><br><\/td><td><a href=\"https:\/\/puppet.com\/\">Puppet<\/a><\/td><td><a href=\"https:\/\/www.ansible.com\/\">Ansible<\/a><\/td><td><a href=\"https:\/\/www.saltstack.com\/\">SaltStack<\/a><\/td><td><a href=\"https:\/\/aws.amazon.com\/de\/cloudformation\/\">CloudFormation<\/a><\/td><td><a href=\"https:\/\/www.terraform.io\/\">Terraform<\/a><br><\/td><\/tr><tr><td><strong>Type<\/strong><\/td><td>Config Mgmt <\/td><td>Config Mgmt <\/td><td>Config Mgmt <\/td><td>Config Mgmt <\/td><td>Orchestration (IaC)<\/td><td>Orchestration (IaC)<\/td><\/tr><tr><td><strong>Cloud<\/strong><\/td><td>All<\/td><td>All<\/td><td>All<\/td><td>All<\/td><td>AWS<\/td><td>All<\/td><\/tr><tr><td><strong>Infrastructure<\/strong><\/td><td>Mutable<\/td><td>Mutable<\/td><td>Mutable<\/td><td>Mutable<\/td><td>Immutable<\/td><td>Immutable<\/td><\/tr><tr><td><strong>Language<\/strong><\/td><td>Procedural<\/td><td>Declarative<\/td><td>Procedural<\/td><td>Declarative<\/td><td>Declarative<\/td><td>Declarative<\/td><\/tr><tr><td><strong>VM <g class=\"gr_ gr_7 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del multiReplace\" id=\"7\" data-gr-id=\"7\">prov<\/g>.<br>Storage<br>Network<\/strong><br><\/td><td>Partial<\/td><td>Partial<\/td><td>Partial<\/td><td>Partial<\/td><td>Yes<\/td><td>Yes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"has-text-align-center\">Table 2: Config Mgmt vs. Orchestration Tools Overview<br><em>Combination and adjustment of these tables: <\/em><a href=\"https:\/\/www.ibm.com\/blogs\/bluemix\/2018\/11\/chef-ansible-puppet-terraform\/\"><em>https:\/\/www.ibm.com\/blogs\/bluemix\/2018\/11\/chef-Ansible-puppet-terraform\/<\/em><\/a><em> <\/em><a href=\"https:\/\/wilsonmar.github.io\/terraform\/\"><em>https:\/\/wilsonmar.github.io\/terraform\/<\/em><\/a><em> <\/em><br><\/p>\n\n\n\n<p><strong>Type<\/strong>: As above described differentiation<\/p>\n\n\n\n<p><strong>Cloud<\/strong>: Which cloud platforms are supported<\/p>\n\n\n\n<p><strong>Infrastructure<\/strong>: Mutable means that the configuration could be changed. So every deployed server changes over time &#8211; this could lead into some unwanted configuration drifts of the servers. Immutable is like the container solution of docker &#8211; each deployment will be creating a new server whereas the old one is being destroyed! &nbsp;<\/p>\n\n\n\n<p><strong>Language<\/strong>: Procedural means in this context: a step-by-step flow and define how the desired end state could be achieved. Declarative means the tool (IaC) can remember a state and it works according to the desired final state. <a href=\"https:\/\/blog.gruntwork.io\/why-we-use-terraform-and-not-chef-puppet-ansible-saltstack-or-cloudformation-7989dad2865c\">Here<\/a> you can read a detailed example regarding this. <\/p>\n\n\n\n<p><strong>VM provisioning, Storage &amp; Networking<\/strong>: Manageable Features. <\/p>\n\n\n\n<p>I give you a short example of how you can define an AWS EC2 Instance with <strong><em>Terraform.<\/em><\/strong> After this step you can run an <strong><em>Ansible<\/em><\/strong> Playbook to provision this machine. Please note, I couldn&#8217;t give a whole tutorial about <strong><em>Terraform<\/em><\/strong> \/ <strong><em>Ansible<\/em><\/strong> and their functionality. Anybody who is interested can have a look at their documentation.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Terraform Example on AWS EC2 Instance <\/strong><\/h3>\n\n\n\n<p>All files are located in my example repository from the HDM Gitlab: <a href=\"https:\/\/gitlab.mi.hdm-stuttgart.de\/ih038\/uls\">https:\/\/gitlab.mi.hdm-stuttgart.de\/ih038\/uls<\/a> If you need access as an external user, please contact me: <a>ih038(AT-@))<g class=\"gr_ gr_5 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del multiReplace\" id=\"5\" data-gr-id=\"5\">hdm<\/g>-stuttgartD.O.<g class=\"gr_ gr_6 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del multiReplace\" id=\"6\" data-gr-id=\"6\">Tde<\/g><\/a> <br><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Install Terraform <\/li>\n\n\n\n<li>Create a Terraform configuration for your first build: <\/li>\n<\/ol>\n\n\n\n<pre class=\"hljs\" style=\"display: block; overflow-x: auto; padding: 0.5em; background-color: rgb(51, 51, 51); color: rgb(255, 255, 255);\">$ mkdir ~\/.aws and add your aws creds there (https:\/\/docs.aws.amazon.com\/cli\/latest\/userguide\/cli-configure-files.html) \n$ touch ~\/.aws\/config \nand add something like this:\n[default]\nregion=us-east-1\noutput=json\n\n$ touch example.tf \n(<span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">in<\/span> your project dir, and add this content:)\n\nprovider <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"aws\"<\/span> {\n  access_key = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"ACCESS_KEY_HERE-PLS-CHANGE-OR-DELETE-ME\"<\/span>\n  secret_key = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"SECRET_KEY_HERE\"<\/span>\n  region     = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"us-east-1\"<\/span>\n}\n\n<span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">if<\/span> you delete the access keys - terraform search <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">for<\/span> it <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">in<\/span> ~\/.aws\/credentials !\nresource <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"aws_instance\"<\/span> <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"example\"<\/span> {\n  ami           = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"ami-2757f631\"<\/span> <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">#adjust for other regions\/images this is a ubuntu trusty<\/span>\n  instance_<span class=\"hljs-built_in\" style=\"color: rgb(255, 255, 170);\">type<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"t2.micro\"<\/span>  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">#adjust for other instance types<\/span>\n}\n<\/pre>\n\n\n\n<p>3. Create an AWS IAM User for Terraform and save the credentials in the ~\/.aws\/credentials file! * Please keep this file top secret! <\/p>\n\n\n\n<p>4. Run <em>terraform init<\/em>:<\/p>\n\n\n\n<pre class=\"hljs\" style=\"display: block; overflow-x: auto; padding: 0.5em; background-color: rgb(51, 51, 51); color: rgb(255, 255, 255);\">$ terraform init\n\nInitializing provider plugins...\n- Checking <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">for<\/span> available provider plugins on https:\/\/releases.hashicorp.com...\n- Downloading plugin <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">for<\/span> provider <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"aws\"<\/span> (2.1.0)...\n\u2026\nTerraform has been successfully initialized!\n\nYou may now begin working with Terraform. Try running <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"terraform plan\"<\/span> to see\nany changes that are required <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">for<\/span> your infrastructure\n\u2026 \n<\/pre>\n\n\n\n<p>you can see the newly created .terraform folder: <\/p>\n\n\n\n<pre class=\"hljs\" style=\"display: block; overflow-x: auto; padding: 0.5em; background-color: rgb(51, 51, 51); color: rgb(255, 255, 255);\">$ <span class=\"hljs-built_in\" style=\"color: rgb(255, 255, 170);\">pwd<\/span>\n\/Users\/immi\/repo\/.terraform\/plugins\/darwin_amd64\n<span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># as you can see i got the needed aws darwin plugins (darwin is macos) <\/span>\n$ tree\n.\n\u251c\u2500\u2500 lock.json\n\u2514\u2500\u2500 terraform-provider-aws_v2.1.0_x4<\/pre>\n\n\n\n<p>5. Run <em>terraform apply<\/em> to see what terraform will create for you:<\/p>\n\n\n\n<pre class=\"hljs\" style=\"display: block; overflow-x: auto; padding: 0.5em; background-color: rgb(51, 51, 51); color: rgb(255, 255, 255);\">$ terraform apply\n\nAn execution plan has been generated and is shown below.\nResource actions are indicated with the following symbols:\n  + create\n\nTerraform will perform the following actions:\n\n  + aws_instance.example\n      id:                           &lt;computed&gt;\n      ami:                          <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"ami-2757f631\"<\/span>\n      arn:                          &lt;computed&gt;\n      \u2026 \n<span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">#\u201dcomputed\u201d means that this values are generated through aws after successful generation <\/span>\nPlan: 1 to add, 0 to change, 0 to destroy.\n\nDo you want to perform these actions?\n  Terraform will perform the actions described above.\n  Only <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'yes'<\/span> will be accepted to approve.\n\n  Enter a value: yes\n\u2026 \naws_instance.example: Still creating... (10s elapsed)\naws_instance.example: Still creating... (20s elapsed)\naws_instance.example: Creation complete after 28s (ID: i-0a91a240db8555f5f)\n\nApply complete! Resources: 1 added, 0 changed, 0 destroyed.\n<\/pre>\n\n\n\n<p>After logging into the AWS console you can see the newly created VM running:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img loading=\"lazy\" decoding=\"async\" width=\"1504\" height=\"183\" data-attachment-id=\"6468\" data-permalink=\"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/03\/15\/kubernetesk8s-everywhere-but-how\/screen-shot-2019-03-10-at-21-32-34\/\" data-orig-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/Screen-Shot-2019-03-10-at-21.32.34.png\" data-orig-size=\"1504,183\" 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=\"Screen Shot 2019-03-10 at 21.32.34\" data-image-description=\"\" data-image-caption=\"\" data-large-file=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/Screen-Shot-2019-03-10-at-21.32.34-1024x125.png\" src=\"https:\/\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/Screen-Shot-2019-03-10-at-21.32.34.png\" alt=\"\" class=\"wp-image-6468\"\/><\/figure>\n\n\n\n<p>Or you can run <em>terraform show<\/em> to confirm that everything worked well. <\/p>\n\n\n\n<p>The VM can be terminated by running<em> terraform destroy<\/em>. <br><\/p>\n\n\n\n<p>Because I want to show you a whole setup I created the solution available below.<\/p>\n\n\n\n<p>I used the official example from this source: <\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/terraform-providers\/terraform-provider-aws\/tree\/master\/examples\/eip\">https:\/\/github.com\/terraform-providers\/terraform-provider-aws\/tree\/master\/examples\/eip<\/a><\/p>\n\n\n\n<p><em>Note: you have to create a private\/public key pair and add the name in variables.<g class=\"gr_ gr_5 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del multiReplace\" id=\"5\" data-gr-id=\"5\">tf<\/g> file<\/em><\/p>\n\n\n\n<p>This setup creates an EC2 t2.micro instance. After this, a local provisioner script installs nginx. <em>But I wanted more!<\/em><strong><em> <\/em><\/strong><br><\/p>\n\n\n\n<p>My final target was to run Ansible as provisioner to show you an extended setup. Therefore I installed Docker, then pulled the NGINX image instead of a local installation. After adjusting the setup, the final files look like this:<\/p>\n\n\n\n<pre class=\"hljs\" style=\"display: block; overflow-x: auto; padding: 0.5em; background-color: rgb(51, 51, 51); color: rgb(255, 255, 255);\">tree\n.\n\u251c\u2500\u2500 README.md\n\u251c\u2500\u2500 main.tf\n\u251c\u2500\u2500 outputs.tf\n\u251c\u2500\u2500 provision.yml\n\u251c\u2500\u2500 terraform.tfstate\n\u251c\u2500\u2500 terraform.tfstate.backup\n\u2514\u2500\u2500 variables.tf<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Terraform Files:<\/h4>\n\n\n\n<p><em><strong>variables.tf<\/strong><\/em><\/p>\n\n\n\n<pre class=\"hljs\" style=\"display: block; overflow-x: auto; padding: 0.5em; background-color: rgb(51, 51, 51); color: rgb(255, 255, 255);\"><span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">variable<\/span> <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"aws_region\"<\/span> {\n  description <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">=<\/span> <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">\"The AWS region to create things in.\"<\/span>\n  default     <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">=<\/span> <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">\"us-east-1\"<\/span>\n}\n\n<span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">variable<\/span> <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">\"aws_amis\"<\/span><span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"> {<\/span>\n  default <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">= {<\/span>\n    <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"us-east-1\"<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"ami-07e101c2aebc37691\"<\/span>\n    <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"us-west-2\"<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"ami-7f675e4f\"<\/span>\n  }\n}\n\n<span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">variable<\/span> <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">\"key_name\"<\/span><span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"> {<\/span>\n  description <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">=<\/span> <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">\"Name of the SSH keypair to use in AWS.\"<\/span>\n  default <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">=<\/span> <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">\"please-ask-politely\"<\/span>\n}<\/pre>\n\n\n\n<p><strong><em>main.tf<\/em><\/strong><\/p>\n\n\n\n<pre class=\"hljs\" style=\"display: block; overflow-x: auto; padding: 0.5em; background-color: rgb(51, 51, 51); color: rgb(255, 255, 255);\"><span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># Specify the provider and access details<\/span>\nprovider <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"aws\"<\/span> {\n  <span class=\"hljs-attr\">region<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"<span class=\"hljs-subst\">${var.aws_region}<\/span>\"<\/span>\n}\n\nresource <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"aws_eip\"<\/span> <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"default\"<\/span> {\n  <span class=\"hljs-attr\">instance<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"<span class=\"hljs-subst\">${aws_instance.web.id}<\/span>\"<\/span>\n  <span class=\"hljs-attr\">vpc<\/span>      = <span class=\"hljs-literal\" style=\"color: rgb(252, 194, 140);\">true<\/span>\n}\n\n<span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># Our default security group to access<\/span>\n<span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># the instances over SSH and HTTP<\/span>\nresource <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"aws_security_group\"<\/span> <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"default\"<\/span> {\n  <span class=\"hljs-attr\">name<\/span>        = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"eip_example\"<\/span>\n  <span class=\"hljs-attr\">description<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"Used in the terraform\"<\/span>\n\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># SSH access from anywhere<\/span>\n  ingress {\n    <span class=\"hljs-attr\">from_port<\/span>   = <span class=\"hljs-number\" style=\"color: rgb(211, 99, 99);\">22<\/span>\n    <span class=\"hljs-attr\">to_port<\/span>     = <span class=\"hljs-number\" style=\"color: rgb(211, 99, 99);\">22<\/span>\n    <span class=\"hljs-attr\">protocol<\/span>    = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"tcp\"<\/span>\n    <span class=\"hljs-attr\">cidr_blocks<\/span> = [<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"0.0.0.0\/0\"<\/span>]\n  }\n\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># HTTP access from anywhere<\/span>\n  ingress {\n    <span class=\"hljs-attr\">from_port<\/span>   = <span class=\"hljs-number\" style=\"color: rgb(211, 99, 99);\">80<\/span>\n    <span class=\"hljs-attr\">to_port<\/span>     = <span class=\"hljs-number\" style=\"color: rgb(211, 99, 99);\">80<\/span>\n    <span class=\"hljs-attr\">protocol<\/span>    = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"tcp\"<\/span>\n    <span class=\"hljs-attr\">cidr_blocks<\/span> = [<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"0.0.0.0\/0\"<\/span>]\n  }\n\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># outbound internet access<\/span>\n  egress {\n    <span class=\"hljs-attr\">from_port<\/span>   = <span class=\"hljs-number\" style=\"color: rgb(211, 99, 99);\">0<\/span>\n    <span class=\"hljs-attr\">to_port<\/span>     = <span class=\"hljs-number\" style=\"color: rgb(211, 99, 99);\">0<\/span>\n    <span class=\"hljs-attr\">protocol<\/span>    = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"-1\"<\/span>\n    <span class=\"hljs-attr\">cidr_blocks<\/span> = [<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"0.0.0.0\/0\"<\/span>]\n  }\n}\n\nresource <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"aws_instance\"<\/span> <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"web\"<\/span> {\n  <span class=\"hljs-attr\">instance_type<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"t2.micro\"<\/span>\n\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># Lookup the correct AMI based on the region<\/span>\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># we specified<\/span>\n  <span class=\"hljs-attr\">ami<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"<span class=\"hljs-subst\">${lookup(var.aws_amis, var.aws_region)}<\/span>\"<\/span>\n\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># The name of our SSH keypair you've created and downloaded<\/span>\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># from the AWS console.<\/span>\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">#<\/span>\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># https:\/\/console.aws.amazon.com\/ec2\/v2\/home?region=us-west-2#KeyPairs:<\/span>\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">#<\/span>\n  <span class=\"hljs-attr\">key_name<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"<span class=\"hljs-subst\">${var.key_name}<\/span>\"<\/span>\n\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># Our Security group to allow HTTP and SSH access<\/span>\n  <span class=\"hljs-attr\">security_groups<\/span> = [<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"<span class=\"hljs-subst\">${aws_security_group.default.name}<\/span>\"<\/span>]\n\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># Here you can see how terraform is able to provision a instance<\/span>\n  provisioner <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"remote-exec\"<\/span> {\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># Install Python for Ansible<\/span>\n  <span class=\"hljs-attr\">inline<\/span> = [<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"while [ ! -f \/var\/lib\/cloud\/instance\/boot-finished ]; do echo 'Waiting for cloud-init...'; sleep 1; done; sudo rm \/var\/lib\/apt\/lists\/* ; sudo apt-get update ; sudo apt-get install -y python python-pip \"<\/span>]\n    connection {\n      <span class=\"hljs-attr\">type<\/span>        = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"ssh\"<\/span>\n      <span class=\"hljs-attr\">user<\/span>        = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"ubuntu\"<\/span>\n    }\n  }\n\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\"># Here we run provision from local disc to ec2-instance with the help of Ansible<\/span>\n  provisioner <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"local-exec\"<\/span> {\n    <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">#we dont want host-key-check because we don't knew the assigned eip<\/span>\n    <span class=\"hljs-attr\">command<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"ANSIBLE_HOST_KEY_CHECKING=False Ansible-playbook -u ubuntu -i '<span class=\"hljs-subst\">${self.public_ip}<\/span>,' -T 300 provision.yml\"<\/span>\n  }\n\n  <span class=\"hljs-comment\" style=\"color: rgb(136, 136, 136);\">#Instance tags, name the vm<\/span>\n  <span class=\"hljs-attr\">tags<\/span> = {\n    <span class=\"hljs-attr\">Name<\/span> = <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"eip-docker-example\"<\/span>\n  }\n}<\/pre>\n\n\n\n<p>the other files are generated by the<em> terraform init <\/em>step and during the execution. <br><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Ansible Files<\/h4>\n\n\n\n<p>I created a small playbook for simplicity. In a real-world project, you would separate the definitions.<\/p>\n\n\n\n<pre class=\"hljs\" style=\"display: block; overflow-x: auto; padding: 0.5em; background-color: rgb(51, 51, 51); color: rgb(255, 255, 255);\">- host<span class=\"hljs-variable\" style=\"color: rgb(173, 229, 252);\">s:<\/span> <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">all<\/span>\n  become: true #execute <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">all<\/span> steps with sudo\n  task<span class=\"hljs-variable\" style=\"color: rgb(173, 229, 252);\">s:<\/span>\n  - name: install <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">python<\/span> stuff <span class=\"hljs-built_in\" style=\"color: rgb(255, 255, 170);\">and<\/span> docker <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">py<\/span> package\n    pip:\n      name : [<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'urllib3'<\/span>,<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'pyOpenSSL'<\/span>,<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'ndg-httpsclient'<\/span>,<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'pyasn1'<\/span>, <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'docker'<\/span>]\n      \n  - name: Add Docker GPG key\n    apt_key: url=http<span class=\"hljs-variable\" style=\"color: rgb(173, 229, 252);\">s:<\/span>\/\/download.docker.<span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">com<\/span>\/linux\/ubuntu\/gpg\n\n  - name: Add Docker APT repository\n    apt_repository:\n      repo: <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">deb<\/span> [arch=amd64] http<span class=\"hljs-variable\" style=\"color: rgb(173, 229, 252);\">s:<\/span>\/\/download.docker.<span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">com<\/span>\/linux\/ubuntu {{Ansible_distribution_release}} stable\n\n  - name: Install <span class=\"hljs-keyword\" style=\"color: rgb(252, 194, 140);\">list<\/span> of packages\n    ap<span class=\"hljs-variable\" style=\"color: rgb(173, 229, 252);\">t:<\/span>\n      name: [<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'apt-transport-https'<\/span>,<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'ca-certificates'<\/span>,<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'curl'<\/span>,<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'software-properties-common'<\/span>,<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'docker-ce'<\/span>, <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'python3'<\/span>,<span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">'python3-pip'<\/span>]\n      state: present\n      update_cache: yes\n\n  - name: Build Docker Container\n    docker_container:\n      name: web\n      image: nginx:latest\n      state: started\n      port<span class=\"hljs-variable\" style=\"color: rgb(173, 229, 252);\">s:<\/span> <span class=\"hljs-string\" style=\"color: rgb(162, 252, 162);\">\"0.0.0.0:80:80\"<\/span><\/pre>\n\n\n\n<p>Of <g class=\"gr_ gr_6 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Punctuation only-ins replaceWithoutSep\" id=\"6\" data-gr-id=\"6\">course<\/g> it is possible to install NGINX through the local <strong><em>Terraform<\/em><\/strong> provisioner but I wanted to show you the possibility of using <strong><em>Ansible<\/em><\/strong>. I think it\u2019s a great solution because you can use the <strong><em>Ansible <\/em><\/strong>script for other hosts. With the Docker support, you are able to run every containerized application within seconds &#8211; just pull the corresponding image and adjust the <em><strong>Ansible<\/strong><\/em> Docker run cmd to the needs of this image (port\/volume mapping etc.) <\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Encountered problems<\/strong><\/h3>\n\n\n\n<p>At this point the article shows errors that occurred and how they were fixed. <br><\/p>\n\n\n\n<h5 class=\"wp-block-heading\">Terraform specific problems:<\/h5>\n\n\n\n<p>The<em> terraform apply <\/em>step failed, and so did the creation of the VM<\/p>\n\n\n\n<p><strong>Error:<\/strong><br><\/p>\n\n\n\n<p><em>&#8220;aws_instance (remote-exec): E: Package &#8216;python&#8217; has no installation candidate&#8221;<\/em><\/p>\n\n\n\n<p><strong> Solutions:<\/strong><br><\/p>\n\n\n\n<p>To fix this, add this one-liner before performing <em>apt-get update<\/em> <\/p>\n\n\n\n<p><em>&#8220;while [ ! -f \/var\/lib\/cloud\/instance\/boot-finished ]; do echo &#8216;Waiting for cloud-init&#8230;&#8217;; sleep 1; done; &#8220;<\/em><br><\/p>\n\n\n\n<p><strong> Explanation:<\/strong><br><\/p>\n\n\n\n<p>This problem was caused because the cloud-init process wasn\u2019t finished and for that reason the <em>apt-get upgrade<\/em> step was blocked.<\/p>\n\n\n\n<p><strong>Ansible specific problems: <\/strong><br><\/p>\n\n\n\n<p>1. Running an Ansible Playbook from macOS to the remote Host for Docker-CE installation does not work with <g class=\"gr_ gr_5 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Grammar multiReplace\" id=\"5\" data-gr-id=\"5\">a SSL-Error<\/g>. &nbsp;<\/p>\n\n\n\n<p><strong>Error: <\/strong><br><\/p>\n\n\n\n<p><em>FAILED! =&gt; {&#8220;changed&#8221;: false, &#8220;msg&#8221;: &#8220;Failed to validate the SSL certificate for download.docker.com:443. Make sure your managed systems have a valid CA certificate installed.<\/em><br><\/p>\n\n\n\n<p><strong> Solution:<\/strong><br><\/p>\n\n\n\n<p>Remove Ansible Installation, install Python3 and Ansible through Homebrew <br><\/p>\n\n\n\n<p><strong>Explanation:<\/strong><\/p>\n\n\n\n<p>It seems that the execution of Ansible was performed through python v2 &#8211; this creates this strange error.  <\/p>\n\n\n\n<p>2. Using the Ansible Docker Package for managing Containers within a playbook fails with the following error. The \u201c<em>docker\u201d<\/em> or \u201cdocker-py\u201d-python package installation through pip was requested although it was already installed.<br><\/p>\n\n\n\n<p><strong>Error:<\/strong> <br><\/p>\n\n\n\n<p><em>FAILED! =&gt; {&#8220;changed&#8221;: false, &#8220;msg&#8221;: &#8220;Failed to import docker or docker-py &#8211; cannot import name DependencyWarning. Try `pip install docker` or `pip install docker-py` (Python 2.6)&#8221;}<\/em><br><\/p>\n\n\n\n<p>comes in combination with: <br><\/p>\n\n\n\n<p><em>FAILED! =&gt; {&#8220;changed&#8221;: false, &#8220;msg&#8221;: &#8220;Ansible requires a minimum of Python2 version 2.6 or Python3 version 3.5. Current version: 3.4.3 &nbsp;[GCC 4.8.4]&#8221;}<\/em><br><\/p>\n\n\n\n<p> <strong>Solution:<\/strong><br><\/p>\n\n\n\n<p> Use a Distribution \/ Image with Python version bigger than 3.5 <br><\/p>\n\n\n\n<p> <strong>Explanation:<\/strong><\/p>\n\n\n\n<p>It seems that the execution of Ansible was performed through Python v2 &#8211; this creates a strange error. The installed 14.04 Ubuntu LTS AMI-Image comes per default with Python 3.4.3 installed through apt-get. But Ansible wants Python &gt; 3.5! After deploying an AMI-Image, which represents a Ubuntu 18.04 LTS, the Ansible provision was successful! The reason for that is 18.04 Ubuntu using Python 3.6.7.  <\/p>\n\n\n\n<p>So all these errors resulted from python version drifts! To avoid this always remember &#8211; if you use Python v2 you shouldn&#8217;t try to provision a remote host with Ansible where only Python 3 is installed and vice versa! <\/p>\n\n\n\n<p><em>Notes: If the provisioning of Ansible went wrong, Terraform does not clearly recognize this &#8211; in this case it would be nice to find a workaround or you have to be aware of this and check the CLI-output carefully. <\/em><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>And now? What about the K8S-Cluster installation? &nbsp;<\/strong><\/h2>\n\n\n\n<p>Due to the nature of the matter, it is logical that there is always a multi node cluster. The tools here can be seen as wrapper over <em>kubeadm<\/em> and give you the possibility of an easy installation and the flexibility for multi cloud platform support.  <\/p>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td><strong>Name<\/strong><\/td><td><strong>Supported <br>Cloud<\/strong><\/td><td><strong>Provisioning Tool<\/strong><\/td><td><strong>K8s version<\/strong><\/td><td><strong>Complexity &amp; Notes<\/strong><\/td><\/tr><tr><td><a href=\"https:\/\/typhoon.psdn.io\/\">Typhoon<\/a><\/td><td>AWS<br>Azure<br>Baremetal<br>Digital Ocean<br>Google Cloud<\/td><td>Terraform<\/td><td>v1.13.4<br><\/td><td>Terraform knowledge needed<\/td><\/tr><tr><td><a href=\"https:\/\/kubernetes.io\/docs\/setup\/custom-cloud\/kubespray\/\">Kubespray<\/a><\/td><td>AWS<br>Azure<br>Baremetal (packet)<br>Openstack<br>Oracle Cloud Infrastructure (Experimental)<br>vSphere<\/td><td>Ansible<br>Vagrant<br><br><\/td><td>v1.13.4<\/td><td>Ansible or Vagrant knowledge needed<\/td><\/tr><tr><td><a href=\"https:\/\/kubernetes.io\/docs\/setup\/custom-cloud\/kops\/\">Kops<\/a><\/td><td>AWS<br>Google Cloud (beta)<br>vSphere (alpha)<br>other platforms planned<\/td><td>No standard provisioning tool &#8211; own binary like kubectl<br>Export to Terraform possible<br><br><\/td><td>v1.11.x<\/td><td>Very matured tool<br>Easy Setup (few steps) <br>No baremetal support <br>No Ansible\/Terraform knowledge needed<br><br><\/td><\/tr><tr><td><a href=\"https:\/\/github.com\/gardener\/kubify\">Kubeify<\/a><\/td><td>AWS<br>Azure<br>Openstack<\/td><td>Terraform<\/td><td>v1.10.12<\/td><td>Terraform knowledge needed<br>Small Project \u2192 &nbsp;only 12 contributors in github<br><br><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>What do we use now? <g class=\"gr_ gr_30 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Punctuation only-ins replaceWithoutSep\" id=\"30\" data-gr-id=\"30\">F<\/g>irst of <g class=\"gr_ gr_29 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Punctuation only-ins replaceWithoutSep\" id=\"29\" data-gr-id=\"29\">all, it depends on<\/g> the support of the cloud providers as the first criteria of exclusion. The next one is the available Kubernetes version. In the past, <strong><em>Kops<\/em><\/strong> was accused of not always being up-to-date. Of <g class=\"gr_ gr_31 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Punctuation only-ins replaceWithoutSep\" id=\"31\" data-gr-id=\"31\">course<\/g> it does not make much sense to deploy an outdated cluster. However, it is one of the most matured tools and does not only have a cool name. <strong><em>Kops<\/em><\/strong> is shipped as its own binary, which again increases simplicity. If you don&#8217;t have knowledge of T<g class=\"gr_ gr_28 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Grammar multiReplace\" id=\"28\" data-gr-id=\"28\">erraform<\/g> or Ansible, but you have to deploy a cluster quickly, <strong><em>Kops<\/em><\/strong> is the first choice. If you are able to make use of one of these tools it depends on the project you choose. So if you prefer Ansible, use <strong><em>Kubespray<\/em><\/strong> for example. Furthermore, it is difficult or even impossible to compare <g class=\"gr_ gr_26 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Grammar only-del replaceWithoutSep\" id=\"26\" data-gr-id=\"26\">the individual<\/g> projects and their functions\/features\/<g class=\"gr_ gr_21 gr-alert gr_spell gr_inline_cards gr_disable_anim_appear ContextualSpelling ins-del\" id=\"21\" data-gr-id=\"21\">addons<\/g>. This is primarily due to the fact that the documentation and its scope differ significantly. And for any feature, etc. <g class=\"gr_ gr_127 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Grammar only-ins doubleReplace replaceWithoutSep\" id=\"127\" data-gr-id=\"127\">additional<\/g> understanding must be created, in order to create an objective comparison. This goes beyond the scope of this article. I personally would prefer <strong><em>Typhoon<\/em><\/strong> because it supports a lot of cloud providers. In the <g class=\"gr_ gr_128 gr-alert gr_gramm gr_inline_cards gr_disable_anim_appear Punctuation only-ins replaceWithoutSep\" id=\"128\" data-gr-id=\"128\">end<\/g> it is only a collection of Terraform modules and can easily be modified to your own requirements. Also, the deployed version of Kubernetes is very up-to-date in comparison to <strong><em>Kops<\/em><\/strong>. The disadvantage of <strong><em>Typhoon<\/em><\/strong> is that it is a relatively unknown tool, as it is not even listed in the official Kubernetes documentation. So <strong><em>Kubespray<\/em><\/strong> would be the second choice as it is also very up-to-date and supports many cloud providers too.<br><\/p>\n\n\n\n<p>But as so often: there are hundreds of ways to install a cluster, so this is only a short overview. In the references, you can find useful links if you want to dive in deeper. <br><\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Conclusion <\/strong><\/h2>\n\n\n\n<p>My personal advice is to use the tools you know best. If you have never used any of these tools, I would recommend you to give Ansible the first try in combination with Terraform. This is a rock solid combination frequently used by many people. The learning curve of Ansible is limited and there are many good ready-made Playbooks which can be used as examples. The documentation of Terraform and Ansible are very helpful. Although I had no previous experience with Terraform and very little AWS knowledge, the excursion could be completed within one day. <br><\/p>\n\n\n\n<p>As research questions for this blog entry, some topics remain open, e.g. the best IaC\/Configuration Management tool. Are there any noticeable differences between performance, security, features etc.? Regarding the Kubernetes installations in the cloud, you can ask yourself similar questions. There is no such thing as a &#8220;golden&#8221; installation. It always depends on what you want and what requirements are set by the project. In the beginning, it is probably easier to prefer a managed Kubernetes solution like EKS from AWS to a self-installed solution. As soon as the experience is available or you want to make flexible changes to the configurations of Kubernetes, soon installing and maintaining your own cluster will be worth it. Once again, the environment around Kubernetes and Cloud is very chaotic and it is growing and growing. If you want a really \u201csuper ultra large scale\u201d systems approach with multiple Clusters, the <a href=\"https:\/\/gardener.cloud\/\">https:\/\/gardener.cloud<\/a> &nbsp;is a very promising project. They call it a Cluster as a service solution. Also this <a href=\"https:\/\/de.slideshare.net\/QAware\/kubernetes-clusters-as-a-service-with-gardener\">https:\/\/de.slideshare.net\/QAware\/kubernetes-clusters-as-a-service-with-gardener<\/a> might be advisable.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">References: <\/h4>\n\n\n\n<ol class=\"wp-block-list\">\n<li>https:\/\/www.pexels.com\/de-de\/foto\/bart-boot-chillen-draussen-1121797\/<\/li>\n\n\n\n<li>https:\/\/wilsonmar.github.io\/terraform\/ <\/li>\n\n\n\n<li>https:\/\/slideshare.net\/DevOpsMeetupBern\/infrastructure-as-code-with-terraform-and-Ansible <\/li>\n\n\n\n<li>https:\/\/searchitoperations.techtarget.com\/definition\/Infrastructure-as-Code-IAC  <\/li>\n\n\n\n<li>https:\/\/searchitoperations.techtarget.com\/definition\/configuration-management-CM  <\/li>\n\n\n\n<li>https:\/\/reddit.com\/r\/devops\/comments\/9a0717\/infrastructureascode_vs_configurationascode\/ <\/li>\n\n\n\n<li>https:\/\/reddit.com\/r\/devops\/comments\/8d0bo8\/recommended_way_for_deploying_kubernetes_on_aws\/<\/li>\n\n\n\n<li>https:\/\/medium.com\/@mglover\/deploying-to-aws-with-terraform-and-Ansible-81cccd4c563e <\/li>\n\n\n\n<li>https:\/\/kubernetes.io\/docs\/setup\/pick-right-solution\/<\/li>\n\n\n\n<li>https:\/\/ibm.com\/blogs\/bluemix\/2018\/11\/chef-Ansible-puppet-terraform\/<\/li>\n\n\n\n<li>https:\/\/wilsonmar.github.io\/terraform\/ <\/li>\n\n\n\n<li>https:\/\/ibm.com\/blogs\/bluemix\/2018\/11\/chef-ansible-puppet-terraform\/<\/li>\n\n\n\n<li>https:\/\/github.com\/hashicorp\/terraform\/issues\/16656 <\/li>\n\n\n\n<li>https:\/\/github.com\/dzeban\/c10k\/tree\/master\/infrastructure\/roles <\/li>\n\n\n\n<li>https:\/\/github.com\/ansible\/ansible\/issues\/37640<\/li>\n\n\n\n<li>https:\/\/gist.github.com\/rbq\/886587980894e98b23d0eee2a1d84933<\/li>\n\n\n\n<li>https:\/\/codementor.io\/mamytianarakotomalala\/how-to-deploy-docker-container-with-Ansible-on-debian-8-mavm48kw0 <\/li>\n\n\n\n<li>https:\/\/askubuntu.com\/questions\/1028423\/cant-upgrade-to-ubuntu-18-04-failed-to-fetch-http-np-archive-ubuntu-com-ubun\/1028436 <\/li>\n\n\n\n<li>https:\/\/andrewaadland.me\/2018\/10\/14\/installing-newer-versions-of-docker-in-ubuntu-18-04\/<\/li>\n\n\n\n<li>http:\/\/inanzzz.com\/index.php\/post\/6138\/setting-up-a-nginx-docker-container-on-remote-server-with-ansible<\/li>\n<\/ol>\n","protected":false},"excerpt":{"rendered":"<p>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.<\/p>\n","protected":false},"author":884,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[1,120,659,650,223],"tags":[84,227,7,232,225,9,3,226,228,224,154,229,230],"ppma_author":[762],"class_list":["post-6338","post","type-post","status-publish","format-standard","hentry","category-allgemein","category-cloud-technologies","category-devops","category-scalable-systems","category-ultra-large-scale-systems","tag-aws","tag-azure","tag-cloud","tag-cloud-computing","tag-container","tag-devops","tag-docker","tag-gcp","tag-iaas","tag-k8s","tag-kubernetes","tag-paas","tag-saas"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":6652,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/07\/24\/how-to-create-a-k8s-cluster-with-custom-nodes-in-rancher\/","url_meta":{"origin":6338,"position":0},"title":"How to create a K8s cluster with custom nodes in Rancher","author":"Sarah Schwab","date":"24. July 2019","format":false,"excerpt":"Don't you find it annoying not to be able to manage all your Kubernetes clusters at a glance? Ranger 2.0 offers an ideal solution.\u00a0 The following article is less a scientific post than a how-to guide to creating a new Kubernetes cluster with custom nodes in Ranger 2.0.\u00a0 But before\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\/2019\/07\/cluster-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/07\/cluster-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/07\/cluster-1.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/07\/cluster-1.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/07\/cluster-1.png?resize=1050%2C600&ssl=1 3x"},"classes":[]},{"id":25560,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/08\/07\/high-availability-and-reliability-in-cloud-computing-ensuring-seamless-operation-despite-the-threat-of-black-swan-events\/","url_meta":{"origin":6338,"position":1},"title":"High Availability and Reliability in Cloud Computing: Ensuring Seamless Operation Despite the Threat of Black Swan Events","author":"mk306","date":"7. August 2023","format":false,"excerpt":"Introduction Nowadays cloud computing has become the backbone of many businesses, offering unparalleled flexibility, scalability and cost-effectiveness. According to O\u2019Reilly\u2019s Cloud Adoption report from 2021, more than 90% of organizations rely on the cloud to run their critical applications and services\u00a0[1]. High availability and reliability of cloud computing systems has\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\/2023\/08\/CrossRegion.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/CrossRegion.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/CrossRegion.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/CrossRegion.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":26830,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2025\/02\/24\/gitops-demystified-principles-practices-and-challenges\/","url_meta":{"origin":6338,"position":2},"title":"GitOps Demystified: Principles, Practices, and Challenges","author":"Kay Kn\u00f6pfle","date":"24. February 2025","format":false,"excerpt":"GitOps, a term coined by Alexis Richardson (CEO of Weaveworks) in 2017, represents a modern approach to continuous deployment and infrastructure management that leverages Git as its core technological foundation [1]. At its essence, GitOps extends the familiar Git workflow patterns from application development to infrastructure management, establishing Git repositories\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\/2025\/02\/whats_gitops.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/02\/whats_gitops.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/02\/whats_gitops.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2025\/02\/whats_gitops.png?resize=700%2C400&ssl=1 2x"},"classes":[]},{"id":21651,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2021\/09\/18\/deploy-random-chat-application-on-aws-ec2-with-kubernetes\/","url_meta":{"origin":6338,"position":3},"title":"Deploying Random Chat Application on AWS EC2 with Kubernetes","author":"dv029","date":"18. September 2021","format":false,"excerpt":"1. Introduction For the examination of the lecture \u201cSoftware Development for Cloud Computing\u201d, I want to build a simple Random Chat Application. The idea of this application is based on the famous chat application called Omegle. Omegle is where people can meet random people in the world and can have\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\/image-19.png?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":25999,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2023\/09\/15\/automate-pdf-a-cloud-driven-workflow-tool-with-cloud-functions-and-kubernetes\/","url_meta":{"origin":6338,"position":4},"title":"Automate PDF &#8211; A Cloud-Driven Workflow Tool with Cloud Functions and Kubernetes","author":"fb089","date":"15. September 2023","format":false,"excerpt":"Gitlab You can find the Project under this link https:\/\/gitlab.mi.hdm-stuttgart.de\/fb089\/automatecloud Wiki You can find all the Infos in our Gitlab Wiki (https:\/\/gitlab.mi.hdm-stuttgart.de\/fb089\/automatecloud\/-\/wikis\/AutomateCloud). You can even try it urself. Feel free Short Description Automate PDF is a workflow automation tool created in the course \u201cSoftware Development for Cloud Computing\u201d. The application\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\/09\/Bildschirmfoto-2023-09-15-um-19.23.39.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/Bildschirmfoto-2023-09-15-um-19.23.39.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/09\/Bildschirmfoto-2023-09-15-um-19.23.39.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":4005,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2018\/08\/20\/cloud-security-tools-and-recommendations-for-devops-in-2018\/","url_meta":{"origin":6338,"position":5},"title":"Cloud security tools and recommendations for DevOps in 2018","author":"Immanuel Haag","date":"20. August 2018","format":false,"excerpt":"Introduction Over the last five years, the use of cloud computing services has increased rapidly, in German companies. According to a statistic from Bitkom Research in \u00a02018, the acceptance of cloud-computing services is growing. Cloud-computing brings many advantages for a business. For example, expenses for the internal infrastructure and its\u2026","rel":"","context":"In &quot;DevOps&quot;","block_context":{"text":"DevOps","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/scalable-systems\/devops\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/19AAsLm7ATw8Fl8aVbJQdYw.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/19AAsLm7ATw8Fl8aVbJQdYw.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/19AAsLm7ATw8Fl8aVbJQdYw.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":762,"user_id":884,"is_guest":0,"slug":"ih038","display_name":"Immanuel Haag","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/3095f100f75fe977c838303e854bb8cd3ffc7fbf01963610781fcd51bb5a4680?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\/6338","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\/884"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=6338"}],"version-history":[{"count":40,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/6338\/revisions"}],"predecessor-version":[{"id":25449,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/6338\/revisions\/25449"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=6338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=6338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=6338"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=6338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}