<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: CloudDude</title>
    <description>The latest articles on Forem by CloudDude (@cloud_dude).</description>
    <link>https://forem.com/cloud_dude</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F681663%2Fed71e6e6-6cf3-4006-8ace-019ecf52ffa2.png</url>
      <title>Forem: CloudDude</title>
      <link>https://forem.com/cloud_dude</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/cloud_dude"/>
    <language>en</language>
    <item>
      <title>Terraform for dummies Part1 : Launch an instance with a static website on OCI</title>
      <dc:creator>CloudDude</dc:creator>
      <pubDate>Sat, 10 Jun 2023 00:44:18 +0000</pubDate>
      <link>https://forem.com/cloud_dude/terraform-for-dummies-part1-launch-an-instance-with-a-static-website-on-oci-47al</link>
      <guid>https://forem.com/cloud_dude/terraform-for-dummies-part1-launch-an-instance-with-a-static-website-on-oci-47al</guid>
      <description>&lt;h3&gt;
  
  
  Terraform for dummies Part1 : Launch an instance with a static website on OCI
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;Terraform brings a new paradigm where Infrastructure becomes a Code, and with Cloud becoming what it is today, everyone is invited at the (devops) table. Therefore, after provisioning with oci-cli in my previous&lt;a href="https://brokedba.blogspot.com/2020/06/launch-oci-instance-with-oci-cli-in-10.html"&gt;BlogPost&lt;/a&gt;, I will explore the same task using terraform.To add more fun, we won’t just deploy an instance but also configure a website linked to its public IP.&lt;br&gt;&lt;br&gt;
 &lt;strong&gt;Note&lt;/strong&gt; This lab will also help you practice if you are preparing for&lt;a href="https://www.oracle.com/cloud/iaas/training/operations.html"&gt;OCI Operations Associate exam(1Z0–1067)&lt;/a&gt; .&lt;/p&gt;
&lt;h3&gt;
  
  
  Topology
&lt;/h3&gt;

&lt;p&gt;The following illustration shows the layers involved between your workstation an Oracle cloud infrastructure while running the terraform commands along with the instance attributes we will be provisioning .&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CDHFD8Dd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/853/0%2A7jjncmJgjYmBtj96.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CDHFD8Dd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/853/0%2A7jjncmJgjYmBtj96.png" alt="" width="800" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Besides describing my &lt;a href="https://github.com/brokedba/terraform-examples"&gt;GitHub repo&lt;/a&gt; before starting this tutorial, I’ll just briefly discuss some principles.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure As Code&lt;/strong&gt; Manages and provisions cloud resources using a declarative code (i.e Terraform) and definition files avoiding interactive configuration. Terraform is an immutable Orchestrator that creates and deletes all resources in the proper sequence.Each Cloud vendor has what we call a provider that terraform uses in order to convert declarative texts into API calls reaching the Cloud infrastructure layer.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Terraform Files&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can be a single file or split into multiple &lt;strong&gt;tf&lt;/strong&gt; or &lt;strong&gt;tf.json&lt;/strong&gt; files, any other file extension is ignored  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Files are merged in alphabetical order but resource definition order doesn’t matter (subfolders are not read)  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Common configurations have 3 type of &lt;strong&gt;tf&lt;/strong&gt; files and a statefile&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Terraform resource declaration syntax&lt;/strong&gt; looks like this:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Component "Provider_Resource_type" "MyResource_Name" { Attribute1 = value ..
                                                       Attribute2 = value ..}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Where the hell do I find a good deployment sample&lt;/strong&gt;?&lt;br&gt;&lt;br&gt;
The most important thing when learning a new program is accomplishing your first HelloWorld. Unfortunately, google can’t always make the cut as samples I used had errors. Luckily, OCI Resource Manager had some samples I managed to export and tweak which was a good starting point for this lab.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terraform lab content:&lt;/strong&gt; I have deliberately split this lab in 2 :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://brokedba.blogspot.com/2020/07/terraform-for-dummies-launch-instance.html#partial"&gt;&lt;strong&gt;VCN Deployment&lt;/strong&gt;&lt;/a&gt;: To grasp the basics of a single resource deployment&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://brokedba.blogspot.com/2020/07/terraform-for-dummies-launch-instance.html#full"&gt;&lt;strong&gt;FULL Instance Deployment&lt;/strong&gt;&lt;/a&gt;: which is a more complex deployment (instance provisioning with a hosted web sever).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  I.Terraform setup
&lt;/h3&gt;

&lt;p&gt;Although I’m on windows I tried the lab using &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10"&gt;WSL&lt;/a&gt; (Ubuntu) terminal (but same applies to Mac).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows:&lt;/strong&gt; Download and run the installer from their &lt;a href="https://www.terraform.io/downloads.html"&gt;website&lt;/a&gt; (&lt;a href="https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_windows_386.zip"&gt;32-bit&lt;/a&gt; ,&lt;a href="https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_windows_amd64.zip"&gt;64-bit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux:&lt;/strong&gt; Download, unzip and move the binary to the local bin directory
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://releases.hashicorp.com/terraform/1.0.3/terraform_1.0.3_linux_amd64.zip 
$ unzip terraform_1.0.3_linux_amd64.zip 
$ mv terraform /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Once installed run the version command to validate your installation
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform --version
  Terraform v1.0.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;OCI API Key based authentication&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tenancy_ocid, Compartment_ocid, user_ocid and the region&lt;/li&gt;
&lt;li&gt;The private API key path and its fingerprint to authenticate with your tenancy account&lt;/li&gt;
&lt;li&gt;The SSH key pair (Private/Public) required when launching the new compute instance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Assumptions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Terraform&lt;/em&gt; shares most of the authentication parameters with oci-cli (located in ~/.oci/config ). Please refer to my &lt;a href="https://brokedba.blogspot.com/2020/05/install-oci-cli-in-5-minutes.html"&gt;Other post&lt;/a&gt; for details on how to setup oci-cli if it isn’t done yet.&lt;/li&gt;
&lt;li&gt;However, terraform also allows using environment variables to define these parameters. This is why I will be using a shell script that sets them before the deployment (I still needed oci-cli for API keys).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  II. Clone the repository
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pick an area that is close to your oci-terraform directory on your file system and issue the following command
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/brokedba/terraform-examples.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As explained earlier you will find 2 directories inside the repository which will make things easier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-oci/create-vcn"&gt;&lt;strong&gt;terraform-provider-oci/create-vcn/&lt;/strong&gt;&lt;/a&gt; To grasp how we deploy a VCN.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-oci/launch-instance"&gt;&lt;strong&gt;terraform-provider-oci/launch-instance/&lt;/strong&gt;&lt;/a&gt; For the full instance deploy, once comfortable with terraform.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  III. Provider setup
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;INSTALL AND SETUP THE OCI PROVIDER&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Cd Into the subdirectory &lt;strong&gt;terraform-provider-oci/create-vcn&lt;/strong&gt; where our configuration resides (i.e vcn )
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd ~/terraform-examples/terraform-provider-oci/create-vcn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;OCI provider plugin is distributed by HashiCorp hence it will be automatically installed by &lt;strong&gt;terraform init&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform init
  Initializing the backend...

  Initializing provider plugins...
  - Checking for available provider plugins...
  - Downloading plugin for provider "oci" (hashicorp/oci) 3.83.1...
  * provider.oci: version = "~&amp;gt; 3.83"

$ terraform --version
  Terraform v0.12.24
  + provider.oci v3.83.1 ---&amp;gt; the privider is now installed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s see what’s in the directory. Here, only files matter along with (click to see content)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree
  .
  |-- env-vars ---&amp;gt; TF_environment_variables needed to authenticate to OCI 
  |-- outputs.tf ---&amp;gt; displays the resources detail at the end of the deploy
  |-- schema.yaml ---&amp;gt; Contains the stack (variables) description    
  |-- variables.tf ---&amp;gt; Resource variables needed for the deploy   
  `-- vcn.tf ---&amp;gt; Our vcn terraform declaration code (configuration) 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adjust the required authentication parameters in file according to your tenancy and key pairs .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ vi env-vars 

  export TF_VAR_tenancy_ocid="ocid1.tenancy.oc1..aaaaaaaa" # change me 
  export TF_VAR_user_ocid="ocid1.user.oc1..aaaaaaaa" # change me 
  export TF_VAR_compartment_ocid="ocid1.tenancy.oc1..aaaaaaaa" # change me 
  export TF_VAR_fingerprint=$(cat PATH_To_Fing/oci_api_key_fingerprint)# change me 
  export TF_VAR_private_key_path=PATH_To_APIKEY/oci_api_key.pem # change me 
  export TF_VAR_ssh_public_key=$(cat PATH_To_PublicSSH/id_rsa.pub) # change me 
  export TF_VAR_ssh_private_key=$(cat PATH_To_PrivateSSH/id_rsa) # change me 
  export TF_VAR_region="ca-toronto-1" # change me 
  $ . env-vars
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  IV. Partial Deployment
&lt;/h3&gt;

&lt;h4&gt;
  
  
  DEPLOY A SIMPLE VCN
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Now that &lt;strong&gt;env-vars&lt;/strong&gt; values are set and sourced, we can run &lt;strong&gt;terraform plan&lt;/strong&gt; command to create an execution plan (quick dry run to check the desired state/actions )
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
   Refreshing Terraform state in-memory prior to plan... 
  ------------------------------------------------------------------------
  An execution plan has been generated and is shown below.
    Terraform will perform the following actions:

    # oci_core_default_route_table.rt will be created
    + resource "oci_core_default_route_table" "rt" 
    {..}
    # oci_core_internet_gateway.gtw will be created
    + resource "oci_core_internet_gateway" "gtw" 
    {..}

    # oci_core_security_list.terra_sl will be created
    + resource "oci_core_security_list" "terra_sl" {
        + egress_security_rules {..}
        + ingress_security_rules {..
            + tcp_options {+ max = 22 + min = 22}}
        + ingress_security_rules {..
             + tcp_options { + max = 80 + min = 80}}
     }

    # oci_core_subnet.terrasub[0] will be created
    + resource "oci_core_subnet" "terrasub" {
        + availability_domain = "BahF:CA-TORONTO-1-AD-1"
        + cidr_block = "192.168.78.0/24"
        ...}

    # oci_core_vcn.vcnterra will be created
    + resource "oci_core_vcn" "vcnterra" {
        + cidr_block = "192.168.64.0/20"
        ...}

  Plan: 5 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The output being too verbose I deliberately kept only relevant attributes&lt;br&gt;&lt;br&gt;
for each VCN component&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, we can finally run &lt;strong&gt;terraform deploy&lt;/strong&gt; to apply the changes required to create our VCN ( listed in the plan )&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; $ terraform apply -auto-approve
oci_core_vcn.vcnterra: Creating...
...
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

Outputs:

default_dhcp_options_id = ocid1.dhcpoptions.oc1.ca-toronto-1.aaaaaaaaasxxxx
default_route_table_id = ocid1.routetable.oc1.ca-toronto-1.aaaaaaaaaxxx
default_security_list_id = ocid1.securitylist.oc1.ca-toronto-1.aaaaaaaaxx
internet_gateway_id = ocid1.internetgateway.oc1.ca-toronto-1.aaaaaaaaxxxx
subnet_ids = ["ocid1.subnet.oc1.ca-toronto-1.aaaaaaaaxxx,]
vcn_id = ocid1.vcn.oc1.ca-toronto-1.amaaaaaaaxxx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Yce0KO_E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AqBT4G2rRVwZ-vqbKJwVe0w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Yce0KO_E--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AqBT4G2rRVwZ-vqbKJwVe0w.png" alt="" width="800" height="122"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observations :&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The deploy started by loading the resources variables in &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-oci/create-vcn/variables.tf"&gt;variables.tf&lt;/a&gt; which allowed the execution of &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-oci/create-vcn/vcn.tf"&gt;vcn.tf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Finally terraform fetched the variables (ocids) of the resources listed in &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-oci/create-vcn/outputs.tf"&gt;outputs.tf&lt;/a&gt; (lookup)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;  : In order to continue the lab we will need to destroy the vcn as the full instance launch will recreate it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform destroy -auto-approve

Destroy complete! Resources: 5 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  V. Full deployment (Instance)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;OVERVIEW&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Awesome, After our small test let’s launch a full instance from scratch .&lt;/li&gt;
&lt;li&gt;First we need to switch to the second directory &lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-oci/launch-instance"&gt;&lt;strong&gt;terraform-provider-oci/launch-instance/&lt;/strong&gt;&lt;/a&gt;
Here's its content:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree ./terraform-provider-oci/launch-instance
.
|-- cloud-init ---&amp;gt; SubFolder
| `--&amp;gt; vm.cloud-config ---&amp;gt; script to install a web server &amp;amp; add a Webpage at startup
|-- compute.tf ---&amp;gt; Instance related terraform configuration
|-- env-vars ---&amp;gt; authentication envirment variables
|-- outputs.tf ---&amp;gt; displays the resources detail at the end of the deploy
|-- schema.yaml ---&amp;gt; Containes the stack (variables)
|-- variables.tf ---&amp;gt; Resource variables needed for the deploy   
|-- vcn.tf ---&amp;gt; same vcn terraform declaration
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As you can see we have 2 additional files and one Subfolder.&lt;br&gt;&lt;br&gt;
 &lt;strong&gt;compute.tf&lt;/strong&gt; is where the compute instance and all its attributes are declared. All the other tf files come from my vcn example with some additions for variables.tf and output.tf&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud-init&lt;/strong&gt;  : is a cloud instance initialization method that executes tasks upon instance startup by providing the &lt;strong&gt;user_data&lt;/strong&gt; entry in the &lt;strong&gt;metadata&lt;/strong&gt; block of the Terraform oci_core_instance resource definition (See below).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ vi compute.tf
resource "oci_core_instance" "terra_inst" {
...
metadata = {
  ssh_authorized_keys = file("../../.ssh/id_rsa.pub") ---&amp;gt; Upload sshkey
  user_data = base64encode(file("./cloud-init/vm.cloud-config")) ---&amp;gt; Run tasks 
      }      
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In my lab, I used &lt;strong&gt;cloud-init&lt;/strong&gt; to install nginx and write an html page that will be the server’s HomePage at startup.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. LAUNCH THE INSTANCE&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once in the &lt;strong&gt;launch-instance&lt;/strong&gt; directory make sure you copied the adjusted file and sourced it (see ). You can then run the plan command (output is truncated for more visibility)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
   Refreshing Terraform state in-memory prior to plan... 
  ------------------------------------------------------------------------
  An execution plan has been generated and is shown below.
    Terraform will perform the following actions:

  ... # VCN declaration 
  # oci_core_instance.terra_inst will be created
  + resource "oci_core_instance" " terra_inst" {
      + ...
      + defined_tags = (known after apply)
      + display_name = "TerraCompute"
      + metadata = {
         + "ssh_authorized_keys" =...
         + "user_data" = " ...
      + shape = "VM.Standard.E2.1.Micro"
      + ...
      + create_vnic_details {
      + hostname_label = "terrahost"
      + private_ip = "192.168.78.51"
      ..}
      + source_details {
          + boot_volume_size_in_gbs = "50"
          + source_type = "image"
           ..}
   # oci_core_volume.terra_vol will be created
   + resource "oci_core_volume" "terra_vol" {..}
   # oci_core_volume_attachment.terra_attach will be created
   + resource "oci_core_volume_attachment" "terra_attach" {..}
   ...
  Plan: 8 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now let the cloud party begin and provision our instance (output has been truncated for more visibility)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply -auto-approve
...
oci_core_instance.terra_inst: Creation complete after 1m46s
oci_core_volume.terra_vol: Creation complete after 14s  
oci_core_volume_attachment.terra_attach: Creation complete after 33s  
...
Apply complete! Resources: 8 added, 0 changed, 0 destroyed.

Outputs:
...
private_ip = ["192.168.78.51",]
public_ip = ["132.145.108.51",]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--YQOSoQDC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/999/1%2AZN-aPiEn8w_fkckA6py9ew.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--YQOSoQDC--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/999/1%2AZN-aPiEn8w_fkckA6py9ew.png" alt="" width="800" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. CONNECTION TO YOUR INSTANCE WEB PAGE&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1TnxUvg3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A8S3aatz2GTxdw0OfNsMb5Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1TnxUvg3--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2A8S3aatz2GTxdw0OfNsMb5Q.png" alt="" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;— — — — — — — — — — — — Your Web Page is 🔥 :)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the instance is provisioned, just copy the public IP address(&lt;a href="http://132.145.108.51/"&gt;132.145.108.51&lt;/a&gt;) in your browser and Voila!&lt;/li&gt;
&lt;li&gt;You have made yourself a fresh and shiny website ready to roll.&lt;/li&gt;
&lt;li&gt;Here I just embedded a video link into the index page but you can adapt the cloud-config to your own liking&lt;/li&gt;
&lt;li&gt;You can also tear down this configuration by simply running &lt;strong&gt;terraform destroy&lt;/strong&gt; from the same directory&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CONCLUSION
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We have demonstrated in this tutorial how to quickly deploy an instance using terraform in OCI and leverage Cloud-init to bootstrap your instance into a webserver .&lt;/li&gt;
&lt;li&gt;Remember that all used attributes in this exercise can be modified in the &lt;strong&gt;variables.tf&lt;/strong&gt; file.&lt;/li&gt;
&lt;li&gt;In my next blog post we will explore how to provision instances using oci ansible modules.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>tutorial</category>
      <category>terraform</category>
      <category>oraclecloud</category>
      <category>oci</category>
    </item>
    <item>
      <title>Terraform for dummies part 3: Launch a vm with a static website on Azure</title>
      <dc:creator>CloudDude</dc:creator>
      <pubDate>Fri, 09 Jun 2023 23:57:38 +0000</pubDate>
      <link>https://forem.com/cloud_dude/terraform-for-dummies-part-3-launch-a-vm-with-a-static-website-on-azure-1h52</link>
      <guid>https://forem.com/cloud_dude/terraform-for-dummies-part-3-launch-a-vm-with-a-static-website-on-azure-1h52</guid>
      <description>&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;In this tutorial we will try provisioning a vm on azure using their terraform provider and reproduce the same deployment I have completed on &lt;a href="http://www.brokedba.com/2020/10/terraform-for-dummies-part-2-launch.html"&gt;AWS&lt;/a&gt; and &lt;a href="https://brokedba.blogspot.com/2020/07/terraform-for-dummies-launch-instance.html"&gt;Oracle Cloud&lt;/a&gt;. As usual we won’t just deploy an instance but also configure an nginx website linked to its public IP. I’ll end this post with some notes on Azure/AWS differences.&lt;br&gt;&lt;br&gt;
I used &lt;strong&gt;azurerm_linux_virtual_machine&lt;/strong&gt; resource instead of the classic vm resource because azure decided it was better to split both windows/Linux for vm deployments(provider 2.0) which is unlike anything seen elsewhere.   &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I have done the same task with my &lt;strong&gt;AZ-CLI&lt;/strong&gt; based &lt;a href="https://github.com/brokedba/az-cli-examples"&gt;bash scripts&lt;/a&gt; (avaialble in Github) which was very helpful to understand the logic behind components needed during the vm creation (More details: &lt;a href="http://www.brokedba.com/2020/12/deploy-webserver-vm-using-azure-cli-and.html"&gt;deploy-webserver-vm-using-azure-cli&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content :&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://brokedba.blogspot.com/2021/10/terraform-for-dummies-part-3-launch-vm.html#setup"&gt;&lt;strong&gt;I. Terraform setup&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://brokedba.blogspot.com/2021/10/terraform-for-dummies-part-3-launch-vm.html#partial"&gt;&lt;strong&gt;IV. Partial deployment&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
 &lt;a href="https://brokedba.blogspot.com/2021/10/terraform-for-dummies-part-3-launch-vm.html#full"&gt;&lt;strong&gt;V. Full deployment&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://brokedba.blogspot.com/2021/10/terraform-for-dummies-part-3-launch-vm.html#tips"&gt;&lt;strong&gt;Tips &amp;amp; Conclusion&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Overview and Concepts
&lt;/h3&gt;
&lt;h3&gt;
  
  
  Topology
&lt;/h3&gt;

&lt;p&gt;The following illustration shows the layers involved between your workstation an Oracle cloud infrastructure while running the terraform actions along with the instance attributes we will be provisioning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Th0xmK8h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/850/0%2AGo3NuUdk0Ws643PA" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Th0xmK8h--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/850/0%2AGo3NuUdk0Ws643PA" alt="" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Besides describing my &lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-azure"&gt;GitHub repo&lt;/a&gt; before starting this tutorial, I’ll just briefly discuss some principles.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure As Code&lt;/strong&gt; Manages and provisions cloud resources using a declarative code (i.e Terraform) and definition files avoiding interactive configuration. Terraform is an immutable Orchestrator that creates and deletes all resources in the proper sequence. Each Cloud vendor has what we call a provider that terraform uses in order to convert declarative texts into API calls reaching the Cloud infrastructure layer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Terraform Files&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Can be a single file or split into multiple &lt;strong&gt;tf&lt;/strong&gt; or &lt;strong&gt;tf.json&lt;/strong&gt; files, any other file extension is ignored.&lt;/li&gt;
&lt;li&gt;Files are merged in alphabetical order but resource definition order doesn’t matter (subfolders are not read).&lt;/li&gt;
&lt;li&gt;Common configurations have 3 type of &lt;strong&gt;tf&lt;/strong&gt; files and a statefile.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Terraform resource declaration syntax&lt;/strong&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Component "Provider_Resource_type" "MyResource_Name" { Attribute1 = value .. 
                                                       Attribute2 = value ..}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Where do I find a good Azure deployment sample?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The easiest way is to create/locate an instance from the console and then use the &lt;strong&gt;import function&lt;/strong&gt; from terraform to generate each of the related components in HCL format (vnet, instance,subnet,etc..) based on their id.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example for a Vnet &amp;gt;&amp;gt;&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
1- Create a shell resource declaration for the vnet in a file called &lt;strong&gt;vnet.tf&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
2- Get the id of the vnet resource from your &lt;strong&gt;Azure portal&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
3- Run the &lt;strong&gt;Terraform import&lt;/strong&gt; then run &lt;strong&gt;Terraform show&lt;/strong&gt; to extract the vnet full declaration from azure to the same file ( &lt;strong&gt;vnet&lt;/strong&gt;.tf)&lt;br&gt;&lt;br&gt;
4- Now you can remove the id attribute with all non required attributes to create a &lt;a href="https://registry.terraform.io/providers/hashicorp/azurerm/latest/docs/resources/virtual_network#argument-reference"&gt;vnet resource&lt;/a&gt; (Do that for each resource)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1- # vi vnet.tf 
 provider "azurerm" { 
 features {}
 } 
 resource "azurerm_virtual_network" "terra_vnet" {
 }
2- # terraform import azurerm_virtual_network.terra_vnet /subscriptions/00*/resourceGroups/providers/Microsoft.Network/virtualNetworks/terra_vnet
3- # terraform show -no-color &amp;gt; vnet.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to import all the existing resources in your account in bulk mode (not one by one) there are tools like&lt;a href="https://github.com/andyt530/py-az2tf"&gt;&lt;strong&gt;py-az2tf&lt;/strong&gt;&lt;/a&gt; or &lt;a href="https://github.com/GoogleCloudPlatform/terraformer"&gt;&lt;strong&gt;terraformer&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;,&lt;/strong&gt; which can import both code and state from your azure account automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terraform lab content:&lt;/strong&gt; I have deliberately split this lab in 2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-azure/create-vnet"&gt;&lt;strong&gt;Vnet Deployment&lt;/strong&gt;&lt;/a&gt;: To grasp the basics of a single resource deployment.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-azure/launch-instancel"&gt;&lt;strong&gt;Instance Deployment&lt;/strong&gt;&lt;/a&gt;: Includes the instance provisioning configured as web sever(includes above vnet) .&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  I.Terraform setup
&lt;/h3&gt;

&lt;p&gt;Although I’m on windows I tried the lab using &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10"&gt;WSL&lt;/a&gt; (Ubuntu) terminal (but same applies to Mac).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows:&lt;/strong&gt; Download and run the installer from their &lt;a href="https://www.terraform.io/downloads.html"&gt;website&lt;/a&gt; (&lt;a href="https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_windows_386.zip"&gt;32-bit&lt;/a&gt; ,&lt;a href="https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_windows_amd64.zip"&gt;64-bit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux:&lt;/strong&gt; Download, unzip and move the binary to the local bin directory
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://releases.hashicorp.com/terraform/1.0.3/terraform_1.0.3_linux_amd64.zip 
$ unzip terraform_1.0.3_linux_amd64.zip 
$ mv terraform /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Once installed run the version command to validate your installation
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform --version
  Terraform v1.0.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Azure authentication&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To authenticate with your azure account, &lt;em&gt;Terraform&lt;/em&gt; will only need you to login using az cli . This can be done by running &lt;strong&gt;az cli&lt;/strong&gt; commands described here &amp;gt;&amp;gt; &lt;a href="https://brokedba.blogspot.com/2020/11/azure-cli-installation-and-few-cli.html"&gt;az-cli installation&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Assumptions&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I will assume that below authentication option is present in your workstation:&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;AZCLI&lt;/em&gt;&lt;/strong&gt; default profile configured with your azure credentials. Refer to my &lt;a href="https://brokedba.blogspot.com/2020/11/azure-cli-installation-and-few-cli.html"&gt;Blog post&lt;/a&gt; for more details
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ az account show 
EnvironmentName HomeTenantId IsDefault Name State 
----------------- ---------------- ----------- ------------- -------
AzureCloud 00000000-00000000... True BrokeDba Lab Enabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I’ll also assume the presence of an &lt;strong&gt;ssh key pair&lt;/strong&gt; to attach to your vm instance. If not here is a command to generate a PEM based key pair.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ssh-keygen -P "" -t rsa -b 2048 -m pem -f ~/id_rsa_az
 Generating public/private rsa key pair.
 Your identification has been saved in /home/brokedba/id_rsa_az.
 Your public key has been saved in /home/brokedba/id_rsa_az.pub.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  II. Clone the repository
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pick an area that is close to your azure-terraform directory on your file system and issue the following command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/brokedba/terraform-examples.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As explained earlier you will find 2 directories inside the repository which will make things easier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-azure/create-vnet"&gt;&lt;strong&gt;terraform-provider-azure/create-vnet/&lt;/strong&gt;&lt;/a&gt; To grasp how we deploy a single Vnet.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-azure/launch-instance"&gt;&lt;strong&gt;terraform-provider-azure/launch-instance/&lt;/strong&gt;&lt;/a&gt; For the final instance deploy.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  III. Provider setup
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;INSTALL AND SETUP THE AZURE PROVIDER&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;Cd Into &lt;em&gt;“&lt;/em&gt; &lt;strong&gt;terraform-provider-azure/create-vnet”&lt;/strong&gt; where our configuration resides (i.e vnet)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd /mnt/c/Users/brokedba/azure/terraform-examples/terraform-provider-azure/create-vnet 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Azure provider plugin will be automatically installed by running &lt;strong&gt;"terraform init"&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform init
  Initializing the backend...

  Initializing provider plugins...
  - Finding latest version of hashicorp/azurerm...
  - Installing hashicorp/azurerm v2.80.0...
  * Installed hashicorp/azurerm v2.80.0 (signed by HashiCorp)
    provider "azurerm" {
Terraform has been successfully initialized!

$ terraform --version
  Terraform v1.0.3 on linux_amd64
  + provider registry.terraform.io/hashicorp/azurerm v2.80.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Let’s see what’s in the directory. Here, only files matter (click to see content)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree
  .
  |-- outputs.tf ---&amp;gt; displays resources detail after the deploy
  |-- variables.tf ---&amp;gt; Resource variables needed for the deploy   
  |-- vnet.tf ---&amp;gt; Our vnet terraform declaration 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  IV. Partial Deployment
&lt;/h3&gt;

&lt;h4&gt;
  
  
  DEPLOY A SIMPLE VNET
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Once the authentication is setup and provider installed , we can run &lt;strong&gt;terraform plan&lt;/strong&gt; command to create an execution plan (quick dry run to check the desired state/actions). Specify the &lt;strong&gt;prefix&lt;/strong&gt; for your resource names
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
var.prefix The prefix used for all resources in this example
Enter a value: Demo
Terraform used selected providers to generate the following execution plan. 
Resource actions are indicated with the following symbols: + create
  ------------------------------------------------------------------------
  Terraform will perform the following actions:

    # azurerm_network_security_group.terra_nsg will be created
    + resource "azurerm_network_security_group" "terra_nsg" 
    {..
     + security_rule = [
     + destination_port_ranges = [+ "22", + "3389",+ "443",+ "80",]
     + direction = "Inbound"
     + name = "Inbound HTTP access"

    # azurerm_resource_group.rg will be created
    + resource "azurerm_resource_group" "rg" 
    {..} 
    # azurerm_subnet.terra_sub will be created
    + resource "azurerm_subnet" "terra_sub" 
    {..
     + address_prefixes = ["192.168.0.0/16”]
     …}
    # azurerm_subnet_network_security_group_association.nsg_sub will be created
    + + resource "azurerm_subnet_network_security_group_association" "nsg_sub"{

    # azurerm_virtual_network.terra_vnet will be created
    + resource "azurerm_virtual_network" "terra_vnet" {
    ...
    + address_space = [ "192.168.0.0/16”
   ...}

  Plan: 5 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The output being too verbose I deliberately kept only relevant attributes for the Vnet resource plan&lt;/li&gt;
&lt;li&gt;Next, we can run &lt;strong&gt;”terraform deploy”&lt;/strong&gt; to provision the resources to create our Vnet (listed in the plan)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply -auto-approve
azurerm_resource_group.rg: Creating...
azurerm_virtual_network.terra_vnet: Creating...
azurerm_network_security_group.terra_nsg: Creating...
azurerm_subnet.terra_sub: Creating...
...
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

Outputs:

Subnet_CIDR = 192.168.10.0/24
Subnet_Name = internal
vnet_CIDR = 192.168.0.0/16
vnet_Name = Terravnet
vnet_dedicated_security_group_Name = "Demo-nsg"
vnet_CIDR = 192.168.0.0/16
vnet_dedicated_security_ingress_rules = toset([
{…
"access" = "Allow" 
"description" = "RDP-HTTP-HTTPS ingress trafic"
"destination_port_ranges" = toset([
"22",
"3389",
"443",
"80",])
…
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J00SuJMe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/835/0%2AsskuljeDooHf3hzk" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J00SuJMe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/835/0%2AsskuljeDooHf3hzk" alt="" width="800" height="79"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The deploy started by loading the resources variables in &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-zure/create-vnet/variables.tf"&gt;variables.tf&lt;/a&gt; which allowed the execution of &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-zure/create-vnet/vnet.tf"&gt;vnet.tf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Finally terraform fetched the attributes of the created resources listed in &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-zure/create-vnet/outputs.tf"&gt;outputs.tf&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : We’ll now destroy the &lt;strong&gt;Vnet&lt;/strong&gt; as the next instance deploy contains the same &lt;strong&gt;Vnet&lt;/strong&gt;  specs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform destroy -auto-approve

Destroy complete! Resources: 6 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  V. Full deployment (Instance)
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;After our small intro to Vnet creation, let’s launch a vm and configure nginx in it in one command.&lt;/li&gt;
&lt;li&gt;First we need to switch to the second directory &lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-azure/launch-instance"&gt;&lt;strong&gt;terraform-provider-azure/launch-instance/&lt;/strong&gt;&lt;/a&gt;
Here's the content:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree ./terraform-provider-azure/launch-instance
.
|-- cloud-init --&amp;gt; SubFolder
| `--&amp;gt; centos_userdata.txt --&amp;gt; script to config a webserver+ modify the index
| `--&amp;gt; sles_userdata.txt --&amp;gt; for SUSE
| `--&amp;gt; ubto_userdata.txt --&amp;gt; for Ubunto 
| `--&amp;gt; el_userdata.txt --&amp;gt; for Enteprise linux distros 
| `--&amp;gt; Win_userdata.ps1 --&amp;gt; for windows 

|-- compute.tf ---&amp;gt; Instance related terraform configuration
|-- outputs.tf ---&amp;gt; displays the resources detail at the end of the deploy
|-- variables.tf ---&amp;gt; Resource variables needed for the deploy   
|-- vnet.tf ---&amp;gt; same vnet we deployed earlier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As you can see we have 2 additional files and one Subfolder. is where the compute instance and all its attributes are declared. All the other “. &lt;strong&gt;tf”&lt;/strong&gt; files come from my vnet example with some additions for &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-azure/launch-instance/variables.tf"&gt;variables.tf&lt;/a&gt; and &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-azure/launch-instance/outputs.tf"&gt;output.tf&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud-init&lt;/strong&gt; : is a cloud instance initialization method that executes tasks upon instance Startup by providing the &lt;strong&gt;user_data&lt;/strong&gt; entry of the &lt;strong&gt;azure vm&lt;/strong&gt; resource definition (See below). I have created enough for 6 OS’ (Centos,Ubuntu,Windows,RHEL,OL,SUSE)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...variable "user_data" { default = "./cloud-init/centos_userdata.txt"} 

 $ vi compute.tf
resource "azurerm_linux_virtual_machine" "terravm" {
...
custom_data = base64encode ("${file(var.user_data)}")
...  
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In my lab, I used &lt;strong&gt;cloud-init&lt;/strong&gt; to install nginx and write an html page that will replace the HomePage at Startup.&lt;/li&gt;
&lt;li&gt;Make sure you your &lt;strong&gt;public ssh key&lt;/strong&gt; is in your home directory or just modify the path below (see &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-azure/launch-instance/variables.tf"&gt;variables.tf&lt;/a&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ vi compute.tf
resource "azurerm_linux_virtual_machine" "terravm" {
.. 

admin_ssh_key {

   username = var.os_publisher[var.OS].admin

   public_key = file("~/id_rsa_az.pub") } ## Change m

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;LAUNCH THE INSTANCE&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once in “ &lt;strong&gt;launch-instance”&lt;/strong&gt; directory, you can run the plan command to validate the 9 resources required to launch our vm instance. The output has been truncated to reduce verbosity
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
 Terraform used selected providers to generate following execution plan. 
 Resource actions are indicated with the following symbols:  
  ------------------------------------------------------------------------
    Terraform will perform the following actions:

  ... # Vnet declaration (see previous vnet deploy) 
  ...  
 # azurerm_linux_virtual_machine.terravm will be created
  + resource "azurerm_linux_virtual_machine" "terravm" {
    + ...
    + admin_username = "centos"  
    + location = "eastus"   
    + size = "Standard_B1s" 
    + name = "TerraDemo-vm"
    + private_ip = "192.168.10.51"
    + admin_ssh_key { = {
      + public_key = &amp;lt;&amp;lt;-EOT ssh-rsa AAAABxxx…*
         EOT 
         username =”centos” }
     + custom_data = (sensitive value)
     + os_disk {…}
     + source_image_reference {
         + offer = "CentOS"
         + publisher = "OpenLogic"
         + version = "latest"
         }   
     }
  # azurerm_network_interface.Terranic will be created
  # azurerm_network_interface_security_group_association.terra_assoc_pubip_nsg will be created
  # azurerm_network_security_group.terra_nsg will be created
  # azurerm_public_ip.terrapubip will be created
    ...}
   ...
  }
  Plan: 9 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now let’s launch our CENTOS7 vm using &lt;strong&gt;terraform apply&lt;/strong&gt; (I left a map of different OS ids in the &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-azure/launch-instance/variables.tf"&gt;variables.tf&lt;/a&gt; you can choose from)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply -auto-approve
...
azurerm_resource_group.rg: Creating...
azurerm_virtual_network.terra_vnet: Creating...
azurerm_network_security_group.terra_nsg: Creating...
azurerm_subnet.terra_sub: Creating...
azurerm_subnet_network_security_group_association.nsg_sub: Creating...
azurerm_network_interface.Terranic: Creating...
azurerm_linux_virtual_machine.terravm: Creating......
Apply complete! Resources: 9 added, 0 changed, 0 destroyed.

Outputs:
... 
Subnet_Name = "internal"
vnet_CIDR = 192.168.0.0/16
Subnet_CIDR = 192.168.10.0/24
vnet_dedicated_security_ingress_rules = toset([
 {…
  "access" = "Allow" 
  "description" = "RDP-HTTP-HTTPS ingress trafic"
  "destination_port_ranges" = toset([
  "22",
  "3389",
  "443",
  "80",])
]
SSH_Connection = ssh connection to instance TerraCompute ==&amp;gt; sudo ssh -i ~/id_rsa_az centos@’’ &amp;lt;---- IP not displayed due to bug with az provider
private_ip = "192.168.10.4"
public_ip = ""
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--lsWxMLup--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1021/0%2AoEeL19t4GXeU8JS9" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--lsWxMLup--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1021/0%2AoEeL19t4GXeU8JS9" alt="" width="800" height="182"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--09YoVeEc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A5ryHzYEofRKswE7Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--09YoVeEc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A5ryHzYEofRKswE7Q.png" alt="" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the instance is provisioned, juts copy the public IP address(i.e &lt;strong&gt;52.191.26.102&lt;/strong&gt; ) in chrome and Voila!&lt;/li&gt;
&lt;li&gt;Although a bug of azurerm_linux_virtual_machine doesn’t show the public IP , just go to the console and copy past the IP into your browser&lt;/li&gt;
&lt;li&gt;You can also tear down this configuration by simply running &lt;strong&gt;terraform destroy&lt;/strong&gt; from the same directory&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tips
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You can fetch any of the specified attributes in &lt;strong&gt;outputs.tf&lt;/strong&gt; using terraform output command i.e:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform output SSH_Connection
ssh connection to instance TerraCompute ==&amp;gt; sudo ssh -i ~/id_rsa_az centos@ ’’ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Terraform Console:&lt;/strong&gt;
Although terraform is a declarative language, there are still myriads of functions you can use to process strings/number/lists/mappings etc. There is an excellent all in one script with examples of most terraform functions &amp;gt;&amp;gt; &lt;a href="https://cloudaffaire.com/terraform-functions/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I added cloud-init files for different distros you can play with by adapting &lt;strong&gt;var.user_data&lt;/strong&gt; &amp;amp;  &lt;strong&gt;var.OS&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Differences between Azure/AWS &amp;amp; things I wish azure kept simple
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Network&lt;/strong&gt; In Azure every subnet is a public subnet because as soon as you associate a public IP to a Vm’s VNIC, you’ll magically have internet access. Internet gateway is not needed here because &lt;a href="https://docs.microsoft.com/en-us/azure/virtual-network/virtual-networks-udr-overview"&gt;system routes&lt;/a&gt; are taking care of that.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CIDR&lt;/strong&gt; range in azure is slightly larger than aws ( from &lt;strong&gt;/8 to /29&lt;/strong&gt; ).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ID&lt;/strong&gt; Azure doesn’t provide regular alpha numeric IDs for its resources but a sort of path based identification (see below)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ SUBNET ID  
/subscriptions/xx/resourceGroups/my_group/providers/Microsoft.Network/virtualNetworks/MY-VNET/subnets/My_SUBNET
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Naming&lt;/strong&gt; Case insensitive but unique, a resource group can’t have 2 resources of the same type with the same name&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bummer:&lt;/strong&gt; I wish azure kept one terraform resource to create vms instead of having one for Linux and one for Windows since v2.0. This implies that we will have extra blocks/modules if we want to do both in one stack instead of leveraging loops. The classic one is not handy for Linux either.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CONCLUSION
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We have demonstrated in this tutorial how to quickly deploy a web server instance using terraform in Azure and leverage Cloud-init to configure the vm during the bootstrap .&lt;/li&gt;
&lt;li&gt;Remember that all used attributes in this exercise can be modified in the file.&lt;/li&gt;
&lt;li&gt;Route table and internet gateway setting in our code were replaced by the Public IP and VNICs&lt;/li&gt;
&lt;li&gt;I found azure vm spinning time &lt;strong&gt;so slow&lt;/strong&gt; comparing to AWS or OCI, not sure if it’s it’s regional thing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improvement:&lt;/strong&gt;
I will look to improve the compute.tf code to allow both windows &amp;amp; Linux type of resource to provision. Validate that &lt;strong&gt;userdata&lt;/strong&gt; works for windows too, unlike on &lt;strong&gt;az cli&lt;/strong&gt;.
Another improvement can be reached in terms of display of the security rules using &lt;a href="https://www.terraform.io/docs/language/functions/formatlist.html"&gt;formatlist&lt;/a&gt; .
stay tuned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Thank you for reading!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="http://www.brokedba.com/2021/10/terraform-for-dummies-part-3-launch-vm.html"&gt;&lt;em&gt;http://www.brokedba.com&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devops</category>
      <category>tutorial</category>
      <category>terraform</category>
      <category>iac</category>
    </item>
    <item>
      <title>Terraform for dummies part 2: Launch an instance with a static website on AWS</title>
      <dc:creator>CloudDude</dc:creator>
      <pubDate>Fri, 09 Jun 2023 23:35:02 +0000</pubDate>
      <link>https://forem.com/cloud_dude/terraform-for-dummies-part-2-launch-an-instance-with-a-static-website-on-aws-ik1</link>
      <guid>https://forem.com/cloud_dude/terraform-for-dummies-part-2-launch-an-instance-with-a-static-website-on-aws-ik1</guid>
      <description>&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;This has become a habit so far to explore different ways of automated provisioning for each cloud provider. This time, I will try Terraform on &lt;strong&gt;AWS&lt;/strong&gt; and reproduce the same deployment I have completed on &lt;a href="https://brokedba.blogspot.com/2020/07/terraform-for-dummies-launch-instance.html"&gt;Oracle Cloud&lt;/a&gt;, and as usual we won’t just deploy an instance but also configure a website linked to its public IP. I’ll end this post with some notes on OCI/AWS differences.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I have done a similar task with my &lt;a href="https://github.com/brokedba/aws-cli-examples"&gt;bash scripts&lt;/a&gt; and which was very helpful to understand the logic behind each IAC interaction during the resource creation (More details &amp;gt; &lt;a href="https://brokedba.blogspot.com/2020/09/launch-ec2-instance-with-static-website.html"&gt;here&lt;/a&gt;).&lt;/p&gt;

&lt;h3&gt;
  
  
  Topology
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--_HM-v5Gj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/816/0%2A7gr7JLPrvle_QZBx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_HM-v5Gj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/816/0%2A7gr7JLPrvle_QZBx.png" alt="" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The following illustration shows the layers involved between your workstation an Oracle cloud infrastructure while running the terraform commands along with the instance attributes we will be provisioning.&lt;/p&gt;

&lt;p&gt;Besides describing my &lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-aws"&gt;GitHub repo&lt;/a&gt; before starting this tutorial, I’ll just briefly discuss some principles.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Infrastructure As Code&lt;/strong&gt; Manages and provisions cloud resources using a declarative code (i.e Terraform) and definition files avoiding interactive configuration. Terraform is an immutable Orchestrator that creates and deletes all resources in the proper sequence. Each Cloud vendor has what we call a provider that terraform uses in order to convert declarative texts into API calls reaching the Cloud infrastructure layer.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Terraform Files&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Can be a single file or split into multiple &lt;strong&gt;tf&lt;/strong&gt; or &lt;strong&gt;tf.json&lt;/strong&gt; files, any other file extension is ignored.  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Files are merged in alphabetical order but resource definition order doesn’t matter (subfolders are not read).  &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Common configurations have 3 type of &lt;strong&gt;tf&lt;/strong&gt; files and a statefile.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Terraform resource declaration syntax&lt;/strong&gt; looks like this:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Component "Provider_Resource_type" "MyResource_Name" { Attribute1 = value .. 
                                                       Attribute2 = value ..}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Where do I find a good AWS deployment sample?&lt;/strong&gt;
The easiest way is to create/locate an instance from the console and then use the &lt;strong&gt;import function&lt;/strong&gt; from terraform to generate each of the related components in HCL format (vpc,instance,subnet,etc..) based on their id.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Example for a VPC &amp;gt;&amp;gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1- Create a shell resource declaration for the vpc in a file called &lt;strong&gt;vpc.tf&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
2- Get the id of the vpc resource from your AWS Console&lt;br&gt;&lt;br&gt;
3- Run the &lt;strong&gt;Terraform import&lt;/strong&gt; then run &lt;strong&gt;Terraform show&lt;/strong&gt; to extract the vpc’s full declaration from aws in the same file (vpc.tf)&lt;br&gt;&lt;br&gt;
4- Now you can remove the id attribute with all non required attributes to create a &lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/vpc#cidr_block"&gt;vpc resource&lt;/a&gt; (Do that for each resource)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1- # vi vpc.tf 
provider "aws" { region = "us-east-1" }
 resource "aws_vpc" "terra_vpc" {
 }
2- # terraform import aws_vpc.terra_vpc vpc-0091141e28608813c
3- # terraform show -no-color &amp;gt; vpc.tf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; If you want to import all the existing resources in your account in bulk mode (not one by one) there is a tool called &lt;a href="http://terraforming.dtan4.net/"&gt;&lt;strong&gt;Terraforming&lt;/strong&gt;&lt;/a&gt; &lt;strong&gt;,&lt;/strong&gt; which can import both code and state from your AWS account automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terraform lab content:&lt;/strong&gt; I have deliberately split this lab in 2:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-aws/create-vpc"&gt;&lt;strong&gt;VPC Deployment&lt;/strong&gt;&lt;/a&gt;: To grasp the basics of a single resource deployment.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://brokedba.blogspot.com/2020/07/terraform-for-dummies-launch-instance.html#full"&gt;&lt;strong&gt;Instance Deployment&lt;/strong&gt;&lt;/a&gt;: includes the instance provisioning (with above vpc) with a hosted web sever.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  I.Terraform setup
&lt;/h3&gt;

&lt;p&gt;Since I’m on windows I tried the lab using both &lt;a href="https://git-scm.com/downloads"&gt;Gitbash&lt;/a&gt; and &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10"&gt;WSL&lt;/a&gt; (Ubuntu) terminal clients (same applies for Mac).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows:&lt;/strong&gt; Download and run the installer from their &lt;a href="https://www.terraform.io/downloads.html"&gt;website&lt;/a&gt; (&lt;a href="https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_windows_386.zip"&gt;32-bit&lt;/a&gt; ,&lt;a href="https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_windows_amd64.zip"&gt;64-bit&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Linux:&lt;/strong&gt; Download, unzip and move the binary to the local bin directory&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_linux_amd64.zip 
$ unzip terraform_0.12.18_linux_amd64.zip 
$ mv terraform /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Once installed run the version command to validate your installation
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform --version   
Terraform v0.12.24
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;AWS authentication&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;To authenticate with your aws account, &lt;em&gt;Terraform&lt;/em&gt; will need to provide both &lt;strong&gt;access_key_id&lt;/strong&gt; &amp;amp; &lt;strong&gt;secret_access_key&lt;/strong&gt;  . This can be done either by sharing the authentication parameters with &lt;a href="https://brokedba.blogspot.com/2020/09/aws-cli-installation-version-1-then.html"&gt;aws-cli&lt;/a&gt; or by Including the access_key and key_id within the Terraform config (i.e. variables.tf)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Assumptions&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I will assume that either of the two below authentication options are present/configured in your workstation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;AWSCLI&lt;/em&gt;&lt;/strong&gt; default profile configured with your aws credentials (Access keys). Refer to my &lt;a href="https://brokedba.blogspot.com/2020/09/aws-cli-installation-version-1-then.html"&gt;Blog post&lt;/a&gt; for more details
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ aws configure list
Name Value Type Location
---- --------- ---- -------- 
profile &amp;lt;not set&amp;gt; None None
access_key ********* J2WA shared-credentials-file
region us-east-1 
config-file ~/.aws/config
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Or AWS&lt;/strong&gt; credentials imbedded in provider specific config section on one of your terraform files (See &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-aws/create-vpc/vpc.tf"&gt;vpc.tf&lt;/a&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
# access_key = "${var.aws_access_key}" - uncomment &amp;amp; replace accordingly 
# secret_key = "${var.aws_secret_key}" - uncomment &amp;amp; replace accordingly
region = var.aws_region --- uncomment and replace accordingly}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;I’ll also assume the presence of an &lt;strong&gt;ssh key pair&lt;/strong&gt; to attach to your ec2 instance. If not here is a command to generate a PEM based key pair.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ssh-keygen -P "" -t rsa -b 2048 -m pem -f ~/id_rsa_aws
     Generating public/private rsa key pair.
 Your identification has been saved in /home/brokedba/id_rsa_aws.
 Your public key has been saved in /home/brokedba/id_rsa_aws.pub.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  II. Clone the repository
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pick an area that is close to your aws-terraform directory on your file system and issue the following command
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/brokedba/terraform-examples.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As explained earlier you will find 2 directories inside the repository which will make things easier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-aws/create-vpc"&gt;&lt;strong&gt;terraform-provider-aws/create-vpc/&lt;/strong&gt;&lt;/a&gt; To grasp how we deploy a VPC.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-aws/launch-instance"&gt;&lt;strong&gt;terraform-provider-aws/launch-instance/&lt;/strong&gt;&lt;/a&gt; For the final instance deploy.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  III. Provider setup
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;INSTALL AND SETUP THE AWS PROVIDER&lt;/li&gt;
&lt;li&gt;Cd Into the subdirectory &lt;strong&gt;terraform-provider-aws/create-vpc&lt;/strong&gt; where our configuration resides (i.e vpc)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt; $ cd ~/brokedba/aws/terraform-examples/terraform-provider-aws/create-vpc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;AWS provider plugin is distributed by HashiCorp hence it will be automatically installed by &lt;strong&gt;terraform init&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform init Initializing the backend... 
Initializing provider plugins...
 - Checking for available provider plugins... 
- Downloading plugin for provider "aws" (hashicorp/aws) 3.11.0... 
* provider.aws: version = "~&amp;gt; 3.11"

$ terraform --version 
Terraform v0.12.24 
+ provider.aws v3.11.0 ---&amp;gt; the provider is now installed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s see what’s in the directory. Here, only files matter&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree . 
|-- outputs.tf ---&amp;gt; displays resources detail after the deploy 
|-- variables.tf ---&amp;gt; Resource variables needed for the deploy 
|-- vpc.tf ---&amp;gt; Our vpc terraform declartion
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  IV. Partial Deployment
&lt;/h3&gt;

&lt;h4&gt;
  
  
  DEPLOY A SIMPLE VPC
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Once the authentication configured (access_key_id/secrete set) , we can run &lt;strong&gt;terraform plan&lt;/strong&gt; command to create an execution plan (quick dry run to check the desired state/actions).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
   Refreshing Terraform state in-memory prior to plan... 
  ------------------------------------------------------------------------
  An execution plan has been generated and is shown below.
    Terraform will perform the following actions:

    # aws_internet_gateway.terra_igw will be created
    + resource "aws_internet_gateway" "terra_igw" 
    {..}
    # aws_route_table.terra_rt will be created
    + resource "aws_route_table" "terra_rt" {
    {..} 
    # aws_route_table_association.terra_rt_sub will be created
    + "aws_route_table_association" "terra_rt_sub" 
    {..}
    # aws_security_group.terra_sg will be created
    + resource "aws_security_group" "terra_sg" {
    + arn = (known after apply)
    + description = "SSH ,HTTP, and HTTPS"
    + egress =[{...}]
    + id = (known after apply)
    + ingress = [
        + {... rules for HTTP/SSH/HTTPS ingress access}
    # aws_subnet.terra_sub will be created
    + resource "aws_subnet" "terra_sub" {
    ...
    + cidr_block = "192.168.10.0/24”
   ...}
    # aws_vpc.terra_vpc will be created
    + resource "aws_vpc" "terra_vpc" {
    ...
    + cidr_block = "192.168.0.0/16”
    ...
    + tags = {
        + "Name" = "Terravpc" } }

  Plan: 6 to add, 0 to change, 0 to destroy.

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;The output being too verbose I deliberately kept only relevant attributes for the VPC resource plan
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply -auto-approve
aws_vpc.terra_vpc: Creating...
...
Apply complete! Resources: 6 added, 0 changed, 0 destroyed.

Outputs:

Subnet_CIDR = 192.168.10.0/24
Subnet_Name = terrasub
internet_gateway_Name = terra-igw
map_public_ip_on_launch = true
route_table_Name = terra-rt
vpc_Name = Terravpc
vpc_id = vpc-09d491059eb740562
vpc_CIDR = 192.168.0.0/16
vpc_dedicated_security_group_Name = terra-sg
vpc_dedicated_security_ingress_rules = 
["Inbound HTTP access : 80 , CIDR: 0.0.0.0/0",
  "Inbound HTTPS access : 443 , CIDR: 0.0.0.0/0",
  "Inbound RDP access : 3389 , CIDR: 0.0.0.0/0",
  "Inbound SSH access: 22 , CIDR: 0.0.0.0/0",]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--kT68zzrU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AJmvWAkncGj4oL1WA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--kT68zzrU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AJmvWAkncGj4oL1WA.png" alt="" width="800" height="107"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The deploy started by loading the resources variables in &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-aws/create-vpc/variables.tf"&gt;variables.tf&lt;/a&gt; which allowed the execution of &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-aws/create-vpc/vpc.tf"&gt;vpc.tf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Finally terraform fetched the attributes of the created resources listed in &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-aws/create-vpc/outputs.tf"&gt;outputs.tf&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : We’ll now destroy the vpc as the next instance deploy contains the same vpc specs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform destroy -auto-approve 
...
Destroy complete! Resources: 6 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  V. Full deployment (Instance)
&lt;/h3&gt;

&lt;p&gt;OVERVIEW&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Sweet, After our small test let’s launch a full instance from scratch.&lt;/li&gt;
&lt;li&gt;First we need to switch to the second directory &lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-aws/launch-instance"&gt;&lt;strong&gt;terraform-provider-aws/launch-instance/&lt;/strong&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's its content:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree ./terraform-provider-aws/launch-instance
.
|-- cloud-init ---&amp;gt; SubFolder
| `--&amp;gt; vm.cloud-config ---&amp;gt; script to config a webserver &amp;amp; add a HomePage
|-- compute.tf ---&amp;gt; Instance related terraform configuration
|-- outputs.tf ---&amp;gt; displays the resources detail at the end of the deploy
|-- variables.tf ---&amp;gt; Resource variables needed for the deploy   
|-- vpc.tf ---&amp;gt; same vpc terraform declaration deployed earlier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As you can see we have 2 additional files and one Subfolder. is where the compute instance and all its attributes are declared. All the other . &lt;strong&gt;tf&lt;/strong&gt; files come from my vpc example with some additions for &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-aws/launch-instance/variables.tf"&gt;variables.tf&lt;/a&gt; and &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-aws/launch-instance/outputs.tf"&gt;output.tf&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud-init&lt;/strong&gt; : is a cloud instance initialization method that executes tasks upon instance startup by providing the &lt;strong&gt;user_data&lt;/strong&gt; entry of the &lt;strong&gt;aws_instance&lt;/strong&gt; resource definition (See below).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...variable "user_data" { default = "./cloud-init/vm.cloud-config"} 

 $ vi compute.tf
resource "aws_instance" "terra_inst" {
...
user_data = filebase64(var.user_data)
...     
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In my lab, I used &lt;strong&gt;cloud-init&lt;/strong&gt; to install nginx and write an html page that will be the server’s HomePage at Startup.&lt;/li&gt;
&lt;li&gt;Make sure you your public ssh key is in your home directory or just modify the path below (see &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-aws/launch-instance/variables.tf"&gt;variables.tf&lt;/a&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;resource "aws_key_pair" "terra_key" {
key_name = var.key_name
public_key = file("~/id_rsa_aws.pub") } ## Change me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;LAUNCH THE INSTANCE&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once in “ &lt;strong&gt;launch-instance”&lt;/strong&gt; directory, you can run the plan command to validate the 10 resources required to launch the ec2 instance (end-state). The output has been truncated to reduce verbosity
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
   Refreshing Terraform state in-memory prior to plan... 
  ------------------------------------------------------------------------
  An execution plan has been generated and is shown below.
    Terraform will perform the following actions:

  ... # VPC declaration (see previous vpc deploy 
  ...
  # aws_key_pair.terra_key will be created
   + resource "aws_key_pair" "terra_key" {
      + key_name = "demo_aws_KeyPair"
      + key_pair_id = (known after apply)
      + public_key = "ssh-rsa AAAAB3Nz…"
      ...}
  # aws_ebs_volume.terra_vol[0] will be created
  + resource "aws_ebs_volume" "terra_vol" {...}

 # aws_instance.terra_inst will be created
  + resource "aws_instance" "terra_inst" {
    + ...
    + ami = "ami-01861c2f0a2adfdb7"  
    + availability_zone = "us-east-1a"   
    + instance_type = "t2.micro" 
    + key_name = "demo_aws_KeyPair"
    + private_ip = "192.168.10.51"
    + tags = {
     ----+ "Name" = "TerraCompute"
        }
     + user_data = "c8c701575f9c76db131ccf77cf352da"
     + ebs_block_device {
     + network_interface {
     + root_block_device {
     + ...
     + ...}

  # aws_volume_attachment.terra_vol_attach[0] will be created
  + resource "aws_volume_attachment" "terra_vol_attach" {
      + device_name = "/dev/xvdb"
      ...}
   ...
  }
  Plan: 10 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let’s launch our CENTOS7 instance using &lt;strong&gt;terraform apply&lt;/strong&gt; (I left a map of different OS ami’s in the &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-aws/launch-instance/variables.tf"&gt;variables.tf&lt;/a&gt; you can choose)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply -auto-approve ...aws_vpc.terra_vpc: Creating...

$ terraform apply -auto-approve
...
aws_vpc.terra_vpc: Creating...
aws_key_pair.terra_key: Creation complete after 0s [id=demo_aws_KeyPair]
aws_security_group.terra_sg: Creation complete after 3s [id=sg-0b04564e8b]
aws_instance.terra_inst: Still creating... [40s elapsed]
aws_instance.terra_inst: Creation complete after 44s [id=i-046f1b1406bff]
aws_ebs_volume.terra_vol[0]: Creation complete after 11s [id=vol-037c1a9f9]aws_volume_attachment.terra_vol_attach[0]: Creation complete after 21s [.. 
...
Apply complete! Resources: 10 added, 0 changed, 0 destroyed.

Outputs:
...
vpc_Name = Terravpc
vpc_CIDR = 192.168.0.0/16
Subnet_CIDR = 192.168.10.0/24
SecurityGroup_ingress_rules = [
  "Inbound HTTP access : 80 , CIDR: 0.0.0.0/0",
  "Inbound HTTPS access : 443 , CIDR: 0.0.0.0/0",
  "Inbound RDP access : 3389 , CIDR: 0.0.0.0/0",
  "Inbound SSH access: 22 , CIDR: 0.0.0.0/0",
]
SSH_Connection = ssh connection to instance TerraCompute ==&amp;gt; sudo ssh -i ~/id_rsa_aws centos@35.173.222.166
private_ip = "192.168.10.51"
public_ip = "54.91.27.50"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JNnO8bs_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AzsVZXIv2Kbit1edU1O4hTw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JNnO8bs_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/1%2AzsVZXIv2Kbit1edU1O4hTw.png" alt="" width="800" height="106"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8okdhQrm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AWuntJPhchpH-Y7SF.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8okdhQrm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2AWuntJPhchpH-Y7SF.png" alt="" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the instance is provisioned, just copy the public IP address(54.91.27.50 ) in your browser and Voila!&lt;/li&gt;
&lt;li&gt;Here I just embedded a video link into the index page but you can adapt the cloud-init file to your own liking (with a new content in the &lt;strong&gt;write_file&lt;/strong&gt; section.&lt;/li&gt;
&lt;li&gt;You can also tear down this configuration by simply running &lt;strong&gt;terraform destroy&lt;/strong&gt; from the same directory&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tips
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;You can fetch any of the specified attributes in outputs.tf using terraf&lt;/strong&gt; orm out &lt;strong&gt;put command i.e:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform output SSH_Connection
ssh connection to instance TerraCompute ==&amp;gt; sudo ssh -i ~/id_rsa_aws 
centos@54.91.27.50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Terraform Console:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
Although terraform is a declarative language, there are still myriads of functions you can use to process strings/number /lists/mappings etc. In my case I had to do some tests to get the right syntax for outputting the ingress SG rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform console
&amp;gt; formatlist("% s: %s" ,aws_security_group.terra_sg.ingress[*].description,aws_security_group.terra_sg.ingress[*].to_port)
[ "Inbound HTTP access : 80", "Inbound HTTPS access : 443",
"Inbound SSH access: 22",]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;There is an excellent all in one script with examples of most terraform functions &amp;gt;&amp;gt; &lt;a href="https://cloudaffaire.com/terraform-functions/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Differences between OCI/AWS &amp;amp; things I wish AWS provider had
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Unlike OCI, most of aws resources don’t have a display-name attribute, hence a tag is necessary each time you want to create a resource in AWS&lt;/li&gt;
&lt;li&gt;If you are used to &lt;strong&gt;DNS-labels&lt;/strong&gt; for Subnet/VCNs in OCI, this is not something you’ll find in AWS&lt;/li&gt;
&lt;li&gt;There is no direct way of setting the instance &lt;strong&gt;hostname&lt;/strong&gt; like in OCI’s hostname_label attribute, you will have to do it via user-data&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bummer:&lt;/strong&gt; I wish AWS had a &lt;strong&gt;data source for aws_key_pair&lt;/strong&gt; as we can’t check if a key pair exists while launching an instance. This is a drawback for cases where a dev team needs to share a key. The only option is to give it a different keyname for each deployment even if the key is the same, which will generate a lot of unnecessary duplicates .&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CONCLUSION
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We have demonstrated in this tutorial how to quickly deploy an instance using terraform in AWS and leverage Cloud-init to bootstrap an instance into a webserver.&lt;/li&gt;
&lt;li&gt;Remember that all used attributes in this exercise can be modified in the variables.tf file.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improvement:&lt;/strong&gt; In my next blog post, I will look to improve the vpc.tf code to leverage &lt;strong&gt;for_each&lt;/strong&gt; function on map collections to make security group rules creation dynamic and conditional.
stay tuned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Thank you for reading!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://bit.ly/3Ia3lqr"&gt;&lt;em&gt;http://www.brokedba.com&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>iac</category>
      <category>aws</category>
      <category>cloud</category>
    </item>
    <item>
      <title>Oracle 19c Data Guard builds on Rhel8 /Oracle linux8/Centos8 (Vagrant)</title>
      <dc:creator>CloudDude</dc:creator>
      <pubDate>Fri, 09 Jun 2023 22:58:41 +0000</pubDate>
      <link>https://forem.com/cloud_dude/oracle-19c-data-guard-builds-on-rhel8-oracle-linux8centos8-vagrant-3g46</link>
      <guid>https://forem.com/cloud_dude/oracle-19c-data-guard-builds-on-rhel8-oracle-linux8centos8-vagrant-3g46</guid>
      <description>&lt;p&gt;With Tools like Vagrant and virtualbox nowadays , developers can seamlessly re/create different environments for their apps by just checking vagrantfile definition, run a vagrant up, and start designing.&lt;/p&gt;

&lt;p&gt;This is more a description of new vagrant builds I’ve been working on lately. They are based on the work that &lt;a href="https://oracle-base.com/misc/site-info"&gt;Tim hall&lt;/a&gt; started a while now on his Github. So hat tip to Tim, he’s done the hard work, I merely adapted the build to the new Enterprise linux 8 distros (rhel/centos/oracle linux) and made sure nothing bugged during each provisioning.&lt;/p&gt;

&lt;h3&gt;
  
  
  Oracle 19c database and Data Guard builds on RHEL8/OL8/CENTOS8
&lt;/h3&gt;

&lt;p&gt;After forking his repo on github, I then started to adapt above Oracle 19c buildsto run on Red Hat 8 and Oracle linux 8. Centos 8 being left alone, I decided to include it to the rest of the pack :).&lt;/p&gt;

&lt;p&gt;As I didn’t write a blog post for this . I thought it’d be convenient for the reader to have an excerpt of the builds’ descriptions (Readme files) before kicking it off and trying them.&lt;/p&gt;

&lt;h3&gt;
  
  
  Required Software
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Clone Repository
&lt;/h3&gt;

&lt;p&gt;Pick an area on your file system to act as the base for this git repository and issue the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone [https://github.com/brokedba/vagrant.git](https://github.com/KoussHD/vagrant.git)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also use Git GUI to clone it as shown below&lt;/p&gt;

&lt;h3&gt;
  
  
  I. Oracle 19c database on RHEL8:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; let’s pick rhel_19_gen directory which is a build that uses a generic rhel8 vagrant box. You could, however, choose any of the builds listed above as it works the same.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;­­­­­¤¤ rhel_19_gen :README.md ¤¤&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Oracle 19c on Red Hat Linux 8&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A simple Vagrant build for Oracle Database 19c on Red hat linux 8.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The vagrant box here is generic and will be provisioned with the prerequisite rpm packages for Oracle 19c through a RHEL8 Beta repository (see install_os_packages.sh for details).&lt;/p&gt;

&lt;p&gt;Place the software in the “software” directory before calling the vagrant up command.&lt;/p&gt;

&lt;p&gt;Directory contents when software is included.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree . 
+--- README.md 
+--- scripts 
| +--- dbora.service 
| +--- install_os_packages.sh 
| +--- oracle_create_database.sh 
| +--- oracle_service_setup.sh 
| +--- oracle_software_installation.sh 
| +--- oracle_user_environment_setup.sh 
| +--- ords_software_installation.sh 
| +--- prepare_u01_u02_disks.sh 
| +--- root_setup.sh 
| +--- server.xml 
| +--- setup.sh 
+--- software 
| +--- apache-tomcat-9.0.22.tar.gz *optional 
| +--- apex_19.1_en.zip *optional 
| +--- LINUX.X64_193000_db_home.zip 
| +--- openjdk-12.0.2_linux-x64_bin.tar.gz *optional 
| +--- ords-19.2.0.199.1647.zip *optional 
| +--- put_software_here.txt 
| +--- sqlcl-19.2.1.206.1649.zip *optional 
+--- Vagrantfile $
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Locate the rhel_19_gen directory and the run the below vagrant command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd D:\VM\vagrant\database\rhel_19_gen vagrant up ..
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  II. Oracle 19c Data Guard on CENTOS8:
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Here also I just chose one of the builds but they all work the same .&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;­­­­­¤¤ cent8_19:README.md ¤¤&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Vagrant 19c Data Guard Build on Centos 8
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; The vagrant base box of centos 8 is generic and will be provisioned with the prerequisite rpm packages for Oracle 19c from a centos repository during vagrant start.&lt;/p&gt;

&lt;p&gt;The Vagrant scripts here will allow you to build a 19c Data Guard system on Centos 8. by just starting the VMs in the correct order.&lt;/p&gt;

&lt;p&gt;This configuration is slightly modified comparing to Tim hall’s original build but the modification merely resides in the below environment variables values (that are easy to adapt to your liking) and two start/stop scripts.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export DOMAIN_NAME=evilcorp.com export NODE1_HOSTNAME=montreal export NODE2_HOSTNAME=toronto export NODE1_PUBLIC_IP=192.168.78.54 export NODE2_PUBLIC_IP=192.168.78.55 export ORACLE_SID=montreal export NODE1_DB_UNIQUE_NAME=montreal export NODE2_DB_UNIQUE_NAME=toronto export ROOT_PASSWORD=racattack export ORACLE_PASSWORD=oracle export SYS_PASSWORD="racattack" export PDB_PASSWORD="PdbPassword1!"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You will also need to download the 19c database software.&lt;/p&gt;

&lt;p&gt;Copy the Oracle software under the “dataguard/cent8_19/software” directory. From the “dataguard” subdirectory, the structure should look like this.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tree . 
+--- config 
| +--- install.env 
| +--- vagrant.yml 
+--- node1 
| +--- scripts 
| | +--- oracle_create_database.sh 
| | +--- oracle_user_environment_setup.sh 
| | +--- root_setup.sh 
| | +--- setup.sh 
| +--- Vagrantfile +--- node2 
| +--- scripts 
| | +--- oracle_create_database.sh 
| | +--- oracle_user_environment_setup.sh 
| | +--- root_setup.sh 
| | +--- setup.sh 
| +--- Vagrantfile 
+--- README.md 
+--- shared_scripts 
| +--- configure_chrony.sh 
| +--- configure_hostname.sh 
| +--- configure_hosts_base.sh 
| +--- configure_shared_disks.sh 
| +--- install_os_packages.sh 
| +--- oracle_db_software_installation.sh 
| +--- prepare_u01_disk.sh +--- software 
| +--- LINUX.X64_193000_db_home.zip 
| +--- put_software_here.tx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build the Data Guard System
&lt;/h3&gt;

&lt;p&gt;The following commands will leave you with a functioning Data Guard installation.&lt;/p&gt;

&lt;p&gt;Start the first node and wait for it to complete. This will create the primary database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd node1 vagrant up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the second node and wait for it to complete. This will create the standby database and configure the broker.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ../node2 vagrant up
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Turn Off System
&lt;/h3&gt;

&lt;p&gt;Perform the following to turn off the system cleanly. (Stop_all script will set state to apply-off or transport-off according to the role of the node’s DB before db shutdown)&lt;/p&gt;

&lt;p&gt;On Node 1&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;oracle@# /home/oracle/scripts/stop_all.sh cd ../node2 vagrant halt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Node 2&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;oracle@# /home/oracle/scripts/stop_all.sh cd ../node1 vagrant halt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Restart the System after first install and shutdown
&lt;/h3&gt;

&lt;p&gt;Perform the following to turn on the system cleanly (start_all.sh script will run a startup if local DB role is Primary or startup mount if the local DB role is Standby).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd node1 vagrant up oracle@# /home/oracle/scripts/start_all.sh cd node2 vagrant up oracle@# /home/oracle/scripts/start_all.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Remove the whole System
&lt;/h3&gt;

&lt;p&gt;The following commands will destroy all VMs and the associated files, so you can run the process again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ../node2 vagrant destroy -f cd ../node1 vagrant destroy -f
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://www.linkedin.com/pulse/oracle-19c-data-guard-builds-rhel8-linux8centos8-vagrant-kosseila-hd/"&gt;&lt;em&gt;https://www.linkedin.com&lt;/em&gt;&lt;/a&gt;&lt;em&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>oracledataguard</category>
      <category>oracledatabase</category>
      <category>vagrant</category>
      <category>virtualbox</category>
    </item>
    <item>
      <title>Terraform for Dummies Part 4: Launch a VM with a Static Website on a Google Cloud Platform —…</title>
      <dc:creator>CloudDude</dc:creator>
      <pubDate>Fri, 29 Oct 2021 17:49:50 +0000</pubDate>
      <link>https://forem.com/cloud_dude/terraform-for-dummies-part-4-launch-a-vm-with-a-static-website-on-a-google-cloud-platform--3dgb</link>
      <guid>https://forem.com/cloud_dude/terraform-for-dummies-part-4-launch-a-vm-with-a-static-website-on-a-google-cloud-platform--3dgb</guid>
      <description>&lt;h3&gt;
  
  
  Terraform for Dummies Part 4: Launch a VM with a Static Website on a Google Cloud Platform — Eclipsys
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Terraform for Dummies Part 4: Launch a VM with a Static Website on a Google Cloud Platform
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Intro
&lt;/h3&gt;

&lt;p&gt;After &lt;a href="http://www.brokedba.com/2020/10/terraform-for-dummies-part-2-launch.html"&gt;AWS&lt;/a&gt;, &lt;a href="https://brokedba.blogspot.com/2020/07/terraform-for-dummies-launch-instance.html"&gt;Oracle Cloud&lt;/a&gt;, and &lt;a href="http://www.blogspot.brokedba.com/2021/10/terraform-for-dummies-part-3-launch-vm.html"&gt;Azure&lt;/a&gt;, GCP (Google Cloud Platform) is the 4th cloud platform in our Terraform tutorial series. We will describe what it takes to authenticate and provision a compute engine using their Terraform provider. The instance will also have an Nginx website linked to its public IP. If you want to know about the differences GCP brings in terms of networking, you can check out my &lt;a href="http://www.brokedba.com/2021/08/what-makes-gcp-networking-service.html"&gt;blog&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; GCP Terraform provider authentication was hell to get a hold on and counter-intuitive compared to other Cloud platforms. I wasted a lot of time just trying to figure if I could avoid hardcoding project id.&lt;/p&gt;

&lt;p&gt;Here’s a direct link to my GitHub repo linked to this lab: &lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-gcp"&gt;terraform-examples/terraform-provider-gcp&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Content:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://brokedba.blogspot.com/2021/10/terraform-for-dummies-part-4-launch-vm.html#setup"&gt;&lt;strong&gt;I. Terraform Setup&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://brokedba.blogspot.com/2021/10/terraform-for-dummies-part-4-launch-vm.html#partial"&gt;&lt;strong&gt;IV. Partial Deployment&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://brokedba.blogspot.com/2021/10/terraform-for-dummies-part-4-launch-vm.html#full"&gt;&lt;strong&gt;V. Full Deployment&lt;/strong&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
&lt;a href="https://brokedba.blogspot.com/2021/10/terraform-for-dummies-part-4-launch-vm.html#tips"&gt;&lt;strong&gt;Tips and Conclusion&lt;/strong&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Overview and Concepts
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Topology
&lt;/h4&gt;

&lt;p&gt;The following illustration shows the layers involved between your workstation and GCP cloud while running the Terraform actions along with the instance attributes we will be provisioning.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--PKUCf16W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/850/0%2ARn2O5ji4-aHRMw9Y.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--PKUCf16W--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/850/0%2ARn2O5ji4-aHRMw9Y.png" alt="" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Besides describing my &lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-gcp"&gt;GitHub repo&lt;/a&gt; before starting this tutorial, I’ll just briefly discuss some principles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terraform Files&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Can be a single file or split into multiple &lt;strong&gt;tf&lt;/strong&gt; or &lt;strong&gt;tf.json&lt;/strong&gt; files, any other file extension is ignored.&lt;/p&gt;

&lt;p&gt;Files are merged in alphabetical order but resource definition order doesn’t matter (subfolders are not read).&lt;/p&gt;

&lt;p&gt;Common configurations have 3 type of &lt;strong&gt;tf&lt;/strong&gt; files and a statefile.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;main.tf:&lt;/strong&gt; Terraform declaration code (configuration) . The file name can be anything you choose&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;variables.tf:&lt;/strong&gt; Resource variables needed for the deploy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;outputs.tf:&lt;/strong&gt; displays the resources detail at the end of the deploy&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;terraform.tfstate:&lt;/strong&gt; keeps track of the state of the stack(resources) after each Terraform apply run&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Terraform resource declaration syntax&lt;/strong&gt; looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Component "Provider_Resource_type" "MyResource_Name" { Attribute1 = value .. 
                                                       Attribute2 = value ..}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Where do I find a good GCP deployment sample?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The easiest way is to create/locate an instance from the console and then use the &lt;strong&gt;import function&lt;/strong&gt; from Terraform to generate each of the related components in HCL format (VPC, instance,subnet,etc..) based on their id.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example for a VPC &amp;gt;&amp;gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a shell resource declaration for the VPC in a file called ** vpc.tf**&lt;/li&gt;
&lt;li&gt;Get the id of the VPC resource from your &lt;strong&gt;GCP portal&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Run the &lt;strong&gt;Terraform import&lt;/strong&gt; then run &lt;strong&gt;Terraform show&lt;/strong&gt; to extract the VPC full declaration from GCP to the same file ( &lt;strong&gt;vpc&lt;/strong&gt;.tf)&lt;/li&gt;
&lt;li&gt;Now you can remove the id attribute with all non required attributes to create a &lt;a href="https://registry.terraform.io/providers/hashicorp/google/latest/docs/resources/compute_network"&gt;vpc resource&lt;/a&gt; (Do that for each resource)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1- # vi vpc.tf 
  provider "google" { 
              features {}
    }
  resource "google_compute_network" "terra_vpc" {
   }
2- # terraform import google_compute_network.terra_vpc {{project}}/{{name}}
3- # terraform show -no-color &amp;gt; vpc.tf 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
If you want to import all the existing resources in your account in bulk mode &lt;a href="https://github.com/GoogleCloudPlatform/terraformer"&gt;&lt;strong&gt;terraformer&lt;/strong&gt;&lt;/a&gt; can help import both code and state from your &lt;strong&gt;GCP&lt;/strong&gt; account automatically.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Terraform Lab Content:&lt;/strong&gt; I purposely split this lab in 2 for more clarity&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-gcp/create-vpc"&gt;&lt;strong&gt;VPC Deployment&lt;/strong&gt;&lt;/a&gt;: To grasp the basics of single resource deployment.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-gcp/launch-instancel"&gt;&lt;strong&gt;Instance Deployment&lt;/strong&gt;&lt;/a&gt;: Includes the instance provisioning configured as a web server(includes above VPC).&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  I. Terraform Setup
&lt;/h3&gt;

&lt;p&gt;Although I’m on windows I tried the lab using &lt;a href="https://docs.microsoft.com/en-us/windows/wsl/install-win10"&gt;WSL&lt;/a&gt; (Ubuntu) terminal (but same applies to Mac).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Windows:&lt;/strong&gt; Download and run the installer from their &lt;a href="https://www.terraform.io/downloads.html"&gt;website&lt;/a&gt; (&lt;a href="https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_windows_386.zip"&gt;32-bit&lt;/a&gt; ,&lt;a href="https://releases.hashicorp.com/terraform/0.12.28/terraform_0.12.28_windows_amd64.zip"&gt;64-bit&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux:&lt;/strong&gt; Download, unzip and move the binary to the local bin directory
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://releases.hashicorp.com/terraform/1.0.3/terraform_1.0.3_linux_amd64.zip 
$ unzip terraform_1.0.3_linux_amd64.zip 
$ mv terraform /usr/local/bin/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Once installed run the version command to validate your installation
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform --version
  Terraform v1.0.3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;GCP authentication (least user friendly)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To authenticate to GCP with Terraform you will need &lt;strong&gt;GCloud&lt;/strong&gt; , service account credentials key file, and the projectId&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prerequisites&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Using dedicated service accounts to authenticate with GCP is recommended practice (not user accounts or API keys)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;GCLOUD authentication&lt;/em&gt;&lt;/strong&gt; configured with your &lt;strong&gt;GCP&lt;/strong&gt; credentials. Refer to my &lt;a href="https://brokedba.blogspot.com/2021/09/google-sdk-cli-for-gcp-installation-and.html"&gt;Blog post&lt;/a&gt; for more details
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ gcloud auth login --activate
…
$ gcloud config list --format='table(account,project)'
 ACCOUNT PROJECT
-------------- ------------- 
bdba@gmail.com brokedba2000   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Service account:&lt;/strong&gt; Either you create a service account with “ &lt;strong&gt;owner role&lt;/strong&gt; “ in the console or run the below cli commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1 -- Create service account
$ gcloud iam service-accounts create terraform-sa --display-name="Terra_Service"
$ gcloud iam service-accounts list --filter="email~terraform" --format='value(email)'

2 -- Bind it to a project and add owner role 
$ gcloud projects add-iam-policy-binding PROJECT_ID --member="serviceAccount:email" --role="roles/owner"

3 -– Generate the Key file for the service account
$ gcloud iam service-accounts keys create ~/gcp-key.json --iam-account=email
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I’ll also assume the presence of an &lt;strong&gt;ssh key pair&lt;/strong&gt; to attach to your VM instance. If not here is a command to generate a PEM based key pair.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ssh-keygen -P "" -t rsa -b 2048 -m pem -f ~/id_rsa_az
     Generating public/private rsa key pair.
 Your identification has been saved in /home/brokedba/id_rsa_az.
 Your public key has been saved in /home/brokedba/id_rsa_az.pub.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  II. Clone the Repository
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Pick an area that is close to your gcp-terraform directory on your file system and issue the following command.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git clone https://github.com/brokedba/terraform-examples.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As explained earlier you will find 2 directories inside the repository which will make things easier:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-gcp/create-vpc"&gt;&lt;strong&gt;terraform-provider-gcp/create-vpc/&lt;/strong&gt;&lt;/a&gt; To grasp how we deploy a VPC.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-gcp/launch-instance"&gt;&lt;strong&gt;terraform-provider-gcp/launch-instance/&lt;/strong&gt;&lt;/a&gt; For the final instance deploy.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  III. Provider Setup
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. INSTALL AND SETUP THE GCP PROVIDER
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Cd Into &lt;em&gt;“&lt;/em&gt; &lt;strong&gt;terraform-provider-gcp/create-vpc”&lt;/strong&gt; where our configuration resides (i.e vpc)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cd /brokedba/gcp/terraform-examples/terraform-provider-gcp/create-vpc 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GCP&lt;/strong&gt; provider plugin will be automatically installed by running &lt;strong&gt;”terraform init”&lt;/strong&gt;.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform init
  Initializing the backend...

  Initializing provider plugins...
  - Finding latest version of hashicorp/google...
  - Installing hashicorp/google v3.88.0...
  * Installed hashicorp/google v3.88.0 (signed by HashiCorp)
Terraform has been successfully initialized!

$ terraform --version
  Terraform v1.0.3 on linux_amd64
  + provider registry.terraform.io/hashicorp/google v3.88.0   
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Let’s see what’s in the &lt;strong&gt;”create-vpc”&lt;/strong&gt; directory. Here, only &lt;strong&gt;*.tf&lt;/strong&gt; files matter
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree
  .
  |-- outputs.tf ---&amp;gt; displays resources detail after the deploy
  |-- variables.tf ---&amp;gt; Resource variables needed for the deploy   
  |-- vpc.tf ---&amp;gt; Our vpc terraform declaration 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  IV. Partial Deployment
&lt;/h3&gt;

&lt;h4&gt;
  
  
  DEPLOY A SIMPLE VPC
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Once the authentication is setup and provider installed , we can run &lt;strong&gt;terraform plan&lt;/strong&gt; command to create an execution plan (quick dry run to check the desired end-state).
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
var.prefix The prefix used for all resources in this example
Enter a value: Demo
Terraform used selected providers to generate the following execution plan. 
Resource actions are indicated with the following symbols: + create
  ------------------------------------------------------------------------
  Terraform will perform the following actions:

    # google_compute_network.terra_vpc will be created
    + resource "google_compute_firewall" "web-server" 
    {..
     + name = "allow-http-rule"
     + allow {
     + ports = [+ "80", + "22",+ "443",+ "3389",]
     + protocol = "tcp"
    ...

    # google_compute_firewall.web-server will be created
    + resource "google_compute_firewall" "web-server" {
    {..} 
    # google_compute_subnetwork.terra_sub will be created
    + resource "google_compute_subnetwork" "terra_sub"  
    {..
     ip_cidr_range = ["192.168.10.0/24”]
     ...}

  Plan: 3 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The output being too verbose I deliberately kept only relevant attributes for the VPC resource plan&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Next, we can run &lt;strong&gt;”terraform deploy”&lt;/strong&gt; to provision the resources to create our VPC (listed in the plan)&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply -auto-approve
google_compute_network.terra_vpc: Creating...
google_compute_firewall.web-server: Creating...
google_compute_subnetwork.terra_sub: Creating...
...
Apply complete! Resources: 3 added, 0 changed, 0 destroyed.

Outputs:

project = "brokedba2000"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--GhSxlNlB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/829/0%2Af0b1KhvlaWGem-ca" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--GhSxlNlB--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/829/0%2Af0b1KhvlaWGem-ca" alt="" width="800" height="131"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Observations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The deployment started by loading the resources variables in &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-gcp/create-vpc/variables.tf"&gt;variables.tf&lt;/a&gt; which allowed the execution of &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-gcp/create-vpc/vpc.tf"&gt;vpc.tf&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Finally Terraform fetched the attributes of the created resources listed in &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-gcp/create-vpc/outputs.tf"&gt;outputs.tf&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt; : We’ll now destroy the &lt;strong&gt;VPC&lt;/strong&gt; as the next instance deploy contains the same &lt;strong&gt;VPC&lt;/strong&gt;  specs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform destroy -auto-approve

Destroy complete! Resources: 3 destroyed.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  V. Full deployment (Instance)
&lt;/h3&gt;

&lt;h4&gt;
  
  
  1. OVERVIEW
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;After our small intro to VPC creation, let’s launch a VM and configure Nginx in it in one command.&lt;/li&gt;
&lt;li&gt;First, we need to switch to the second directory &lt;a href="https://github.com/brokedba/terraform-examples/tree/master/terraform-provider-gcp/launch-instance"&gt;&lt;strong&gt;terraform-provider-gcp/launch-instance/&lt;/strong&gt;&lt;/a&gt;
Here's the content:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ tree ./terraform-provider-gcp/launch-instance
.
|-- cloud-init --&amp;gt; SubFolder
| `--&amp;gt; centos_userdata.txt --&amp;gt; script to config a webserver the Web homepage
| `--&amp;gt; sles_userdata.txt --&amp;gt; for SUSE
| `--&amp;gt; ubto_userdata.txt --&amp;gt; for Ubunto 
| `--&amp;gt; el_userdata.txt --&amp;gt; for Enteprise linux distros 

|-- compute.tf ---&amp;gt; Compute engine Instance terraform configuration
|-- outputs.tf ---&amp;gt; displays the resources detail at the end of the deploy
|-- variables.tf ---&amp;gt; Resource variables needed for the deploy   
|-- vpc.tf ---&amp;gt; same vpc we deployed earlier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As you can see we have 2 additional files and one Subfolder. is where the compute instance and all its attributes are declared. All the other “. &lt;strong&gt;tf”&lt;/strong&gt; files come from my &lt;strong&gt;VPC&lt;/strong&gt; example with some additions for &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-gcp/launch-instance/variables.tf"&gt;variables.tf&lt;/a&gt; and &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-gcp/launch-instance/outputs.tf"&gt;output.tf&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Cloud-init&lt;/strong&gt; : is a cloud instance initialization method that executes scripts upon instance Startup. see below &lt;strong&gt;metadata&lt;/strong&gt; entry of the &lt;strong&gt;vm instance&lt;/strong&gt; definition (startup-script). There are 5 OS’ scripts (Centos,Ubuntu,Windows,RHEL,SUSE) windows was not tested.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...variable "user_data" { default = "./cloud-init/centos_userdata.txt"} 

 $ vi compute.tf 
resource "google_compute_instance" "terravm" { 
metadata = {
startup-script = ("${file(var.user_data)}")
...     
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;In my lab, I used &lt;strong&gt;cloud-init&lt;/strong&gt; to install Nginx and write an HTML page that will replace the HomePage at Startup.&lt;/li&gt;
&lt;li&gt;Make sure your &lt;strong&gt;public ssh key&lt;/strong&gt; is in your home directory or just modify the path below (see &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-gcp/launch-instance/variables.tf"&gt;variables.tf&lt;/a&gt;)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ vi compute.tf
resource "google_compute_instance" "terravm" {
metadata = {

admin_ssh_key {

   ssh-keys = var.admin":${file("~/id_rsa_gcp.pub")}" ## Change me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  2. LAUNCH THE INSTANCE
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Once in “ &lt;strong&gt;launch-instance”&lt;/strong&gt; directory, you can run the plan command to validate the 9 resources required to launch our vm instance. The output has been truncated to reduce verbosity
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
  ------------------------------------------------------------------------
    Terraform will perform the following actions:

  ... # VPC declaration (see previous VPC deploy) 
  ...  
 # google_compute_instance.terra_instance will be created
 + resource "google_compute_instance" "terra_instance" {
    + ...
    + hostname = "terrahost"
    + machine_type = "e2-micro"
    + name = "Terravm"
    + tags = [+ "web-server",]
    + boot_disk {
    + initialize_params { + image = "centos-cloud/centos-7"
    + network_interface {
      ... 
    + network_ip = "192.168.10.51"
     } 
    + metadata = {
  + "ssh-keys" = &amp;lt;&amp;lt;-EOT ssh-rsa AAAABxxx…*
         EOT 
   + "startup-script" = &amp;lt;&amp;lt;-EOT”        
      EOT}

  # google_compute_address.internal_reserved_subnet_ip will be created
  + resource "google_compute_address" "internal_reserved_subnet_ip" {
      ...}
   ...
  }
  Plan: 5 to add, 0 to change, 0 to destroy. terraform apply -auto-approve ... google_compute_network.terra_vpc: Creating... google_compute_firewall.web-server: Creating... google_compute_subnetwork.terra_sub: Creating... google_compute_address.internal_reserved_subnet_ip: Creating... google_compute_instance.terra_instance: Creating... Apply complete! Resources: 5 added, 0 changed, 0 destroyed. Outputs: vpc_name = "terra-vpc" Subnet_Name = "terra-sub" Subnet_CIDR = "192.168.10.0/24" fire_wall_rules = toset([{... "ports" = tolist([ "description" = "RDP-HTTP-HTTPS ingress trafic" "destination_port_ranges" = toset([ "80", "3389", "443", "3389",]) ] hostname = "terrahost.brokedba.com" project = "brokedba2000" private_ip = "192.168.10.51" public_ip = "35.227.81.2" SSH_Connection = "ssh connection to instance TerraCompute ==&amp;gt; sudo ssh -i ~/id_rsa_gcp centos@35.227.81.2"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Now let’s launch our CENTOS7 vm using &lt;strong&gt;terraform apply&lt;/strong&gt; (I left a map of different OS ids in the &lt;a href="https://github.com/brokedba/terraform-examples/blob/master/terraform-provider-aws/launch-instance/variables.tf"&gt;variables.tf&lt;/a&gt; you can choose from)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply -auto-approve
...
google_compute_network.terra_vpc: Creating...
google_compute_firewall.web-server: Creating...
google_compute_subnetwork.terra_sub: Creating...
google_compute_address.internal_reserved_subnet_ip: Creating...
google_compute_instance.terra_instance: Creating...
Apply complete! Resources: 5 added, 0 changed, 0 destroyed.

Outputs:
vpc_name = "terra-vpc"
Subnet_Name = "terra-sub"
Subnet_CIDR = "192.168.10.0/24"
fire_wall_rules = toset([
 {…
  "ports" = tolist([
  "description" = "RDP-HTTP-HTTPS ingress trafic"
  "destination_port_ranges" = toset([
  "80",
  "3389",
  "443",
  "3389",])
]
hostname = "terrahost.brokedba.com"
project = "brokedba2000"
private_ip = "192.168.10.51"
public_ip = "35.227.81.2"
 SSH_Connection = "ssh connection to instance TerraCompute ==&amp;gt; sudo ssh -i ~/id_rsa_gcp centos@35.227.81.2"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--MCYANI9p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1020/0%2AApEBrDVxZT04GnzU" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--MCYANI9p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1020/0%2AApEBrDVxZT04GnzU" alt="" width="800" height="55"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--OfZJCqHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1023/0%2AviwL4LUakxZZ2yvh" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--OfZJCqHX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1023/0%2AviwL4LUakxZZ2yvh" alt="" width="800" height="481"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Once the instance is provisioned, juts copy the public IP address(i.e &lt;strong&gt;52.191.26.102&lt;/strong&gt; ) in chrome and Voila!&lt;/li&gt;
&lt;li&gt;You can also tear down this configuration by simply running &lt;strong&gt;terraform destroy&lt;/strong&gt; from the same directory&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Tips
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You can fetch any of the specified attributes in &lt;strong&gt;outputs.tf&lt;/strong&gt; using terraform output command i.e:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform output SSH_Connection
ssh connection to instance TerraCompute ==&amp;gt; sudo ssh -i ~/id_rsa_gcp centos@ ’public_IP’ 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Terraform Console:&lt;/strong&gt;
Although Terraform is a declarative language, there are still myriads of functions you can use to process strings/number/lists/mappings etc. There is an excellent all in one script with examples of most terraform functions &amp;gt;&amp;gt;&lt;a href="https://cloudaffaire.com/terraform-functions/"&gt;here&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;I added cloud-init files for different distros you can play with by adapting &lt;strong&gt;var.user_data&lt;/strong&gt; &amp;amp;  &lt;strong&gt;var.OS&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CONCLUSION
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;We have demonstrated in this tutorial how to quickly deploy a web server instance using terraform in GCP and leverage Cloud-init (Startupscript) to configure the VM during the bootstrap .&lt;/li&gt;
&lt;li&gt;We had to hardcode the &lt;strong&gt;projectId&lt;/strong&gt; although it’s embedded in the config &lt;strong&gt;credentials&lt;/strong&gt; (key file) which make it tedious and rigid&lt;/li&gt;
&lt;li&gt;Remember that all user attributes in this exercise can be modified in the &lt;strong&gt;variables.tf&lt;/strong&gt; file.&lt;/li&gt;
&lt;li&gt;Route table and internet gateway didn’t need to be created&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Improvement:&lt;/strong&gt; Validate that the startup script works for windows too.
Another improvement can be reached in terms of the display of the security rules using&lt;a href="https://www.terraform.io/docs/language/functions/formatlist.html"&gt;formatlist&lt;/a&gt; .
stay tuned&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;em&gt;Originally published at&lt;/em&gt; &lt;a href="https://eclipsys.ca/terraform-for-dummies-part-4-launch-a-vm-with-a-static-website-on-a-google-cloud-platform/"&gt;&lt;em&gt;https://eclipsys.ca&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>gcp</category>
      <category>googlecloudplatform</category>
      <category>terraform</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Fixes for Virtualbox errors due to latest Windows 10 updates</title>
      <dc:creator>CloudDude</dc:creator>
      <pubDate>Sun, 02 Aug 2020 23:14:58 +0000</pubDate>
      <link>https://forem.com/cloud_dude/fixes-for-virtualbox-errors-due-to-latest-windows-10-updates-2ain</link>
      <guid>https://forem.com/cloud_dude/fixes-for-virtualbox-errors-due-to-latest-windows-10-updates-2ain</guid>
      <description>&lt;h3&gt;
  
  
  Fixes for Vagrant/Virtualbox errors due to latest Windows 10 updates
&lt;/h3&gt;

&lt;h4&gt;
  
  
  "Failed to create the host-only adapter" and "VT-x not available"
&lt;/h4&gt;

&lt;p&gt;It is always hard to keep up with Operating systems upgrades and patches for software companies, not only vagrant or Virtualbox. But if there was an OS that could make it even worse for us — end-users — that would definitely be Windows 10. Microsoft never ceases to amaze us, so much their updates side effects can be dumbfounding.&lt;/p&gt;

&lt;p&gt;Ok, let’s cut the Vendetta and show the workarounds for these unfortunate UX Sucker punches instead.&lt;/p&gt;

&lt;h3&gt;
  
  
  1- Failed to create the host-Only adapter
&lt;/h3&gt;

&lt;p&gt;A Host-Only adapter can usually be created from virtualbox GUI (see below) or from VboxManage.exe call as admin (manually or from an external app).&lt;br&gt;&lt;br&gt;
Note: I could still do it from vagrant before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wBEUdzNe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/762/1%2AQ1z7CeF1k8MnF0G4cv41MQ.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wBEUdzNe--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/762/1%2AQ1z7CeF1k8MnF0G4cv41MQ.png" alt="" width="762" height="359"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Create a Host Only adaptor from the vbox GUI&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
In my case I just recall applying windows 10 (v1909) updates few days ago. But when I started running my vagrant build yesterday, I then bumped into this unsavory (yet so insightful 😛) error from the get go.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Stderr: 0%...
Progress state: E_FAIL
VBoxManage.exe: **error:**  **Failed to create the host-only adapter**
VBoxManage.exe: error: Operation canceled by the user
VBoxManage.exe: error: Details: **code E\_FAIL (0x80004005)**, component VirtualBoxWrap, interface IVirtualBox
VBoxManageHostonly.cpp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--B493GKvV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A6sbwG8Xn8GYGOvbc" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--B493GKvV--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/1024/0%2A6sbwG8Xn8GYGOvbc" alt="" width="800" height="261"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;ENVIRONMENT&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;strong&gt;OS:&lt;/strong&gt; Windows 10 Home&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Update:&lt;/strong&gt; July 14, 2020 — KB4565483 (1903 OS Builds 18362.959 and 1909 18363.959)&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Vagrant version&lt;/strong&gt; : Vagrant 2.2.7&lt;br&gt;&lt;br&gt;
&lt;strong&gt;Vagrant provider&lt;/strong&gt; : VirtualBox&lt;br&gt;&lt;br&gt;
&lt;strong&gt;VirtualBox version&lt;/strong&gt; : 6.1&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Workaround
&lt;/h4&gt;

&lt;p&gt;You will have to temporarily change the user account Control setting. That way the vagrant background task won’t hang then crash as windows won’t show the confirmation pop up.&lt;/p&gt;

&lt;p&gt;**Actions  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Type&lt;/strong&gt; UAC &lt;strong&gt;in the search field on your taskbar and click&lt;/strong&gt; &lt;em&gt;Change User Account Control settings.&lt;br&gt;
-&lt;/em&gt; &lt;strong&gt;Turn UAC off by dragging the slider down to&lt;/strong&gt; Never notify &lt;strong&gt;and click ** OK&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--iGTK_vV---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/932/0%2A2PZg6wQZdhtJ9cPS.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--iGTK_vV---/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://cdn-images-1.medium.com/max/932/0%2A2PZg6wQZdhtJ9cPS.png" alt="" width="800" height="590"&gt;&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Disable notification when apps make changes to the system&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note: **&lt;/strong&gt; Please remember to Re-Enable the notification once your vagrant build is provisioned.**&lt;/p&gt;
&lt;h3&gt;
  
  
  2- VT-x is not available
&lt;/h3&gt;

&lt;p&gt;After solving the earlier issue, I tried to run the &lt;code&gt;vagrant up&lt;/code&gt; again but here comes another error message in my output.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
error seems to indicate that the virtualization capabilities were not detected&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;... The command and stderr is shown below.
Command: [" **startvm**", "6cef1e57-d4d3-4633-a122-1be55e990eec", "--type", " **headless**"]

Stderr: VBoxManage.exe: **error: VMMR0\_DO\_NEM\_INIT\_VM failed** : **VERR\_NEM\_MISSING\_KERNEL\_API\_2**.
VBoxManage.exe: error: **VT-x is not available (VERR\_VMX\_NO\_VMX)**
VBoxManage.exe: error: Details: **code E\_FAIL (0x80004005)**, component ConsoleWrap, interface IConsole
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  &lt;strong&gt;Workaround&lt;/strong&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;ThereforeVT-x&lt;/strong&gt; is a set of intel CPU instructions that include hardware virtualization features which accelerate virtual machines. This must be enabled at BIOS level. Coincidentally, I also had to update my laptop BIOS the same week, but it’s not what caused the error.&lt;br&gt;&lt;br&gt;
Windows is known to automatically disable &lt;strong&gt;VT-x&lt;/strong&gt; if Hyper-V is active. In my case I am sure the new updates have enabled it back. You will, therefore, have to unset that again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Actions&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
 Disable Hyper-V using the below Command and reboot your system&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PS C:\Users\brokedba&amp;gt; **bcdedit** /set hypervisorlaunchtype **off**
 The operation completed successfully.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We just confirmed through these small yet annoying issues that windows updates aren’t that harmless. Therefore, It’s wise to test your favorite applications functionalities after each major patch. Hopping this will help those who’ll face the same errors with vagrant on windows 10.&lt;/p&gt;

</description>
      <category>failedhostonlyadapte</category>
      <category>vagrant</category>
      <category>oracle</category>
      <category>virtualbox</category>
    </item>
  </channel>
</rss>
