<?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: iamtito</title>
    <description>The latest articles on Forem by iamtito (@iamtito).</description>
    <link>https://forem.com/iamtito</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%2F291985%2F154cbc57-a3b1-429c-bb1b-01fa9a154f23.jpeg</url>
      <title>Forem: iamtito</title>
      <link>https://forem.com/iamtito</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/iamtito"/>
    <language>en</language>
    <item>
      <title>Clickjacking attack Protection</title>
      <dc:creator>iamtito</dc:creator>
      <pubDate>Fri, 03 Jul 2020 11:36:44 +0000</pubDate>
      <link>https://forem.com/iamtito/clickjacking-attack-protection-lh9</link>
      <guid>https://forem.com/iamtito/clickjacking-attack-protection-lh9</guid>
      <description>&lt;p&gt;Clickjacking, also known as a “UI redress attack” is a malicious technique for tricking a user into clicking on something different from what the user perceives, the attacker tricks the users with invisible or disguised webpage elements. This example from OWASP clearly explains it "imagine an attacker who builds a web site that has a button on it that says “click here for a free iPod”. However, on top of that web page, the attacker has loaded an iframe with your mail account and lined up exactly the “delete all messages” button directly on top of the “free iPod” button. The victim tries to click on the “free iPod” button but instead actually clicked on the invisible “delete all messages” button. In essence, the attacker has “hijacked” the user’s click, hence the name “Clickjacking”."&lt;/p&gt;

&lt;h2&gt;
  
  
  Preventing Clickjacking
&lt;/h2&gt;

&lt;p&gt;Sending the proper Content Security Policy (CSP) frame-ancestors directive response headers that instruct the browser to not allow framing from other domains. (This replaces the older X-Frame-Options HTTP headers.)&lt;/p&gt;

&lt;p&gt;Content Security Policy replaced the &lt;code&gt;X-Frame-Options&lt;/code&gt;, this sends an instruction to the browser to not allow iframe from other domains. However, you can set this up for some exceptions in your application server config&lt;/p&gt;

&lt;h3&gt;
  
  
  Apache Config
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Deny
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Header always append X-Frame-Options DENY
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Will be configured as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Header always append Content-Security-Policy "frame-ancestors 'deny'
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  DENY all but not self
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Header always append X-Frame-Options SAMEORIGIN
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;functions as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Header always append Content-Security-Policy "frame-ancestors 'self' 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Allow self and multiple domains
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Header always append Content-Security-Policy "frame-ancestors 'self' https://www.example1.com/ https://example2.com/;"
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Nginx Config
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Deny All
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add_header Content-Security-Policy "frame-ancestors none;";
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  DENY all but not self
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add_header Content-Security-Policy "frame-ancestors 'self';";
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Allow from multiple domains
&lt;/h4&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;add_header Content-Security-Policy "frame-ancestors self example1.com example2.com;";
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h4&gt;
  
  
  Test
&lt;/h4&gt;

&lt;p&gt;👇click on HTML and change the domain to your domain&lt;br&gt;
&lt;iframe height="600" src="https://codepen.io/iamtito/embed/RwrxBea?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;h4&gt;
  
  
  Tools for checking your headers
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://securityheaders.com"&gt;https://securityheaders.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.serpworx.com/check-security-headers/"&gt;https://www.serpworx.com/check-security-headers/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://gf.dev/secure-headers-test"&gt;https://gf.dev/secure-headers-test&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Reference and helpful links:
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://owasp.org/www-community/attacks/Clickjacking"&gt;https://owasp.org/www-community/attacks/Clickjacking&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://www.keycdn.com/blog/http-security-headers"&gt;https://www.keycdn.com/blog/http-security-headers&lt;/a&gt;&lt;/em&gt;&lt;br&gt;
&lt;em&gt;&lt;a href="https://content-security-policy.com/examples/"&gt;https://content-security-policy.com/examples/&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>apache</category>
      <category>hack</category>
      <category>security</category>
    </item>
    <item>
      <title>Ansible Dynamic Inventory</title>
      <dc:creator>iamtito</dc:creator>
      <pubDate>Fri, 03 Jul 2020 03:48:42 +0000</pubDate>
      <link>https://forem.com/iamtito/ansible-dynamic-inventory-31n4</link>
      <guid>https://forem.com/iamtito/ansible-dynamic-inventory-31n4</guid>
      <description>&lt;p&gt;Static inventory will not serve the needs when tracking and deploying to multiple sources with hosts spinning up and shutting down in response to business demands. The solution to such a changing infrastructure would be ansible dynamic inventory. To accomplish this, you will need a cloud provider ini file (e.g aws.ini) and ec2.py (which ansible use to communicate to the AWS API to fetch the metadata for all the instances). This post focus on AWS(Amazon Web Service).&lt;/p&gt;

&lt;p&gt;&lt;code&gt;ec2.ini&lt;/code&gt; file provided by Ansible. All the cloud provider &lt;code&gt;.ini&lt;/code&gt; can be found here &lt;a href="https://github.com/ansible/ansible/tree/stable-2.9/contrib/inventory"&gt;https://github.com/ansible/ansible/tree/stable-2.9/contrib/inventory&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ec2.py:&lt;/strong&gt; EC2 external inventory script which dynamically fetches data from AWS API&lt;/p&gt;

&lt;p&gt;To set up the ec2 external inventory script, copy the script to &lt;code&gt;/etc/ansible/ec2.py&lt;/code&gt; and run &lt;code&gt;chmod +x /etc/ansible/ec2.py&lt;/code&gt;. You will also need to copy the &lt;code&gt;ec2.ini&lt;/code&gt; file to &lt;code&gt;/etc/Ansible/ec2.ini&lt;/code&gt;. Then run ansible-playbook normally, the --limit args can be parsed.&lt;/p&gt;

&lt;p&gt;To make a successful call to AWS API, configure boto. There are a variety of methods available, you can add setup your aws credential by setting up your &lt;code&gt;~/.aws/credentials&lt;/code&gt; or export the following environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export AWS_ACCESS_KEY_ID=’mYaWeSoMeAcCeSsKeY′
export AWS_SECRET_ACCESS_KEY=’IcAnToTaLlYpUtMySeCrEtHeRe′
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Set up a few more environment variables to the inventory management script such as&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ export ANSIBLE_HOSTS=/PATH/ec2.py
$ export EC2_INI_PATH=/PATH/ec2.ini
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This variable sets ansible-playbook to use the dynamic EC2 script instead of a static &lt;code&gt;/etc/ansible/hosts&lt;/code&gt; file. Open up &lt;code&gt;ec2.py&lt;/code&gt; in a text editor and make sure that the path to ec2.ini config file is defined correctly at the top of the script:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;EC2_INI_PATH&lt;/code&gt; instructs &lt;code&gt;ec2.py&lt;/code&gt; where the &lt;code&gt;ec2.ini&lt;/code&gt; config file is located.&lt;/p&gt;

&lt;p&gt;Make the script executable and test it by running&lt;br&gt;
&lt;code&gt;./ec2.py –list&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ./ec2.py --list
{
  "_meta": {
    "hostvars": {
      "1.9O.1OO.12O": {
        "ansible_host": "1.9O.1OO.12O",
        "ec2__in_monitoring_element": false,
        "ec2_account_id": "19OP23I42OF3",
        "ec2_ami_launch_index": "0",
        ....
        "ec2_tag_App": "olonje",
        "ec2_tag_Env": "Staging",
        "ec2_tag_Name": "Bami Gbe",
        "ec2_virtualization_type": "hvm",
        "ec2_vpc_id": "vpc-IaMhIdDeN"
      },
      "4.OOO.122.1OO9": {
        "ansible_host": "4.OOO.122.1OO9",
        "ec2__in_monitoring_element": false,
        ...
        "ec2_key_name": "emi-moni-profile",
        "ec2_root_device_name": "/dev/xvda",
        "ec2_tag_App": "ounje2",
        "ec2_tag_Env": "prod",
        "ec2_tag_Name": "Production Stack",
        "ec2_virtualization_type": "hvm",
        "ec2_vpc_id": "vpc-IaMhIdDeN"
      }
    }
  },
  "ami_1k02nd83js84k6apO": [
    "1.9O.1OO.12O",
    "4.OOO.122.1OO9"
  ],
  "tag_App_olonje": [
    "1.9O.1OO.12O"
  ],
  "tag_App_order2": [
    "4.OOO.122.1OO9"
  ],
  "tag_Env_Staging": [
    "1.9O.1OO.12O"
  ],
  "tag_Env_prod": [
    "4.OOO.122.1OO9"
  ],
  "tag_Name_app_Worker": [
    "1.9O.1OO.12O"
  ],
  "tag_Name_Production_Stack": [
    "4.OOO.122.1OO9"
  ],
  "vpc_id_vpc_IaMhIdDeN": [
    "1.9O.1OO.12O",
    "4.OOO.122.1OO9"
  ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To fine-tune the output and other features that aren’t applicable refer to the &lt;code&gt;ec2.ini&lt;/code&gt; file. For multiple AWS accounts, you can pass &lt;code&gt;--profile&lt;/code&gt; PROFILE name to the &lt;code&gt;ec2.py&lt;/code&gt; script.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cat ~/.aws/credentials
[default]
aws_access_key_id = &amp;lt;default access key&amp;gt;
aws_secret_access_key = &amp;lt;default secret key&amp;gt;

[profile tito]
aws_access_key_id = &amp;lt;tito access key&amp;gt;
aws_secret_access_key = &amp;lt;tito secret key&amp;gt;

[profile ounje]
aws_access_key_id = &amp;lt;ounje access key&amp;gt;
aws_secret_access_key = &amp;lt;ounje secret key&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To get the inventory for the ounje account run &lt;code&gt;AWS_PROFILE=ounje ansible-playbook -i /etc/ansible/ec2.py myplaybook.yml&lt;/code&gt;. Since the EC2 external inventory provides mappings to instances from several groups, we can filter the target instance based on resource tag. Speaking of &lt;strong&gt;Tags.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Tags
&lt;/h3&gt;

&lt;p&gt;Each instance has a variety of key/value pairs associated with it called &lt;strong&gt;Tags&lt;/strong&gt;. The most common tag key is ‘Name’, though anything is possible. Each key/value pair is its own group of instances, again with special characters converted to underscores, in the format tag_KEY_VALUE e.g. &lt;code&gt;tag_Name_Web&lt;/code&gt; can be used as is &lt;code&gt;tag_Name_redis-master-001&lt;/code&gt; becomes &lt;code&gt;tag_Name_redis_master_001&lt;/code&gt; &lt;code&gt;tag_aws_cloudformation_logical-id_WebServerGroup&lt;/code&gt; becomes &lt;code&gt;tag_aws_cloudformation_logical_id_WebServerGroup&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;When Ansible interacts with a specific server, the EC2 inventory script is called again with the --host HOST option. This looks up the HOST in the index cache to get the instance ID, and then makes an API call to AWS to get information about that specific instance. It then makes information about that instance available as variables to your playbooks. Each variable is prefixed by ec2_. e.g&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ec2_dns_name
ec2_id
ec2_image_id
ec2_instance_type
ec2_ip_address
ec2_tag_Name
ec2_vpc_id
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;a href="https://docs.ansible.com/ansible/latest/user_guide/intro_dynamic_inventory.html#inventory-script-example-aws-ec2"&gt;Read more&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To see the complete list of variables available for an instance, run the script by itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/etc/ansible/ec2.py --host ec2-12-1O1-14-12.compute-1.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note: API calls to EC2 can be slow. Therefore, API results are cached. The number of seconds a cache is considered valid can be updated in the &lt;code&gt;ec2.ini&lt;/code&gt; file in &lt;code&gt;/etc/ansible/ec2.ini&lt;/code&gt;. Default setting is&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;...
cache_max_age = 300
...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;You can set it to &lt;code&gt;cache_max_age=0&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  TESTING OUR DYNAMIC INVENTORY ABOVE
&lt;/h2&gt;

&lt;p&gt;Running ansible-playbook deployment. Using &lt;code&gt;sample.yml&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- name: Deploy Ounje Artifact
  hosts: all
  vars:
    - app: "e-status "
    - env: "staging"
  tasks:
    - name: Get Instance IDs
      ec2_remote_facts:
        aws_access_key: "moYaCoverSecretMi"
        aws_secret_key: "amalaShitaLoSureJuMafo"
        region: "us-east-1"
        filters:
          "tag:Env": "{{ env }}"
      register: gbebodi

    - name: Store ounje hosts
      debug: var=gbebodi

    - name: Store Ounje EC2 instance ID
      set_fact:
         instance_id: "{{ item.id }}"
      with_items: "{{ gbebodi.instances }}"

    - name: Store EC2 instance ID in var
      debug: var=instance_id
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ansible-playbook -i /etc/ansible/ec2.py --limit "tag_App_order2" -u ec2-user sample.yml -e env=prod
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In the above example:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ansible-playbook&lt;/code&gt; is the standard command to run an ansible playbook&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/etc/ansible/ec2.py&lt;/code&gt; points ansible inventory to use the ec2.py to callout to aws API to get the ec2 instance metadata&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;--limit "tag_App_ounje2”&lt;/code&gt; This limit the host you want to target by instructing ansible-playbook to pull the metadata of all instances with a tag of key &lt;code&gt;App&lt;/code&gt; and value &lt;code&gt;ounje2&lt;/code&gt;. This enables the ansible-playbook to know where to run the tasks, know which instance you want to access and limit the activities to the only ounje2&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sample.yml&lt;/code&gt; is the name of our playbook file&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;–e&lt;/code&gt; a way of parsing env variable to the playbook, or to override the default env variable&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-u&lt;/code&gt; indicates the user ansible needs to use to login to the instance.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;output&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ ansible-playbook -i /etc/ansible/ec2.py --limit "tag_App_ounje2" -u ec2-user sample.yml -e env=prod

[DEPRECATION WARNING]: ec2_remote_facts is kept for backwards compatibility but usage is discouraged. The module documentation details page may explain more about this rationale.. This feature will be removed in a future release. Deprecation warnings can be disabled by setting deprecation_warnings=False in
ansible.cfg.
PLAY [Deploy Ounje Artifact] ***********************************************************************************************************************************
TASK [Gathering Facts] ******************************************************************************************************************************************
Monday 23 September 2O19 O1:17:25 -O4OO (O:OO:OO.141) O:OO:OO.141 ******
ok: [1.OO.1O9.111]
TASK [Get Instance IDs] *****************************************************************************************************************************************
Monday 23 September 2O19 O1:17:28 -O4OO (O:OO:O2.234) O:OO:O2.376 ******
ok: [1.OO.1O9.111]
TASK [Store ounje hosts] ***************************************************************************************************************************************
Monday 23 September 2O19 O1:17:29 -O4OO (O:OO:O1.481) O:OO:O3.857 ******
ok: [1.OO.1O9.111] =&amp;gt; { "ounje": { "changed": false, "failed": false, "instances": [ { "ami_launch_index": "O", "architecture": "x86_94", "block_device_mapping": [ { "attach_time": "2O19-O6-23TO4:54:57.OOOZ", "delete_on_termination": true, "device_name": "/dev/xvda", "status": "attached", "volume_id": "vol-298hfn3f348ff4f348f" } ], "client_token": "", "ebs_optimized": false, "groups": [ { "id": "sg-Of11425adOe7f7d1a", "name": "launch-wizard-13" } ], "hypervisor": "xen", "id": "i-1O293847561OO293", "image_id": "ami-1k02nd83js84k6apO", "instance_profile": null, "interfaces": [ { "id": "eni-nf32f2fn48489r348", "mac_address": "41:9O:i7:dc:69:lO" } ], "kernel": null, "key_name": "emi-moni-profile", "launch_time": "2O19-O6-23TO4:54:56.OOOZ", "monitoring_state": "disabled", "persistent": false, "placement": { "tenancy": "default", "zone": "us-east-1c" }, "private_dns_name": "ip-1-OO-1O9-111.ec2.internal", "private_ip_address": "OO7-OO-69-42O", "public_dns_name": "ec2-1-OO-1O9-111.compute-1.amazonaws.com", "public_ip_address": "1.OO.1O9.111", "ramdisk": null, "region": "us-east-1", "requester_id": null, "root_device_type": "ebs", "source_destination_check": "true", "spot_instance_request_id": null, "state": "running", "tags": { "App": "ounje2", "Env": "prod", "Name": "Production Stack" }, "virtualization_type": "hvm", "vpc_id": "vpc-IaMhIdDeN" } ] }
}
TASK [Store EC2 instance ID] ************************************************************************************************************************************
Monday 23 September 2O19 O1:17:29 -O4OO (O:OO:OO.145) O:OO:O4.OO3 ******
ok: [1.OO.1O9.111] =&amp;gt; (item={u'ramdisk': None, u'kernel': None, u'instance_profile': None, u'root_device_type': u'ebs', u'private_dns_name': u'ip-1-OO-1O9-111.ec2.internal', u'block_device_mapping': [{u'status': u'attached', u'device_name': u'/dev/xvda', u'delete_on_termination': True, u'attach_time': u'2O19-O6-23TO4:54:57.OOOZ', u'volume_id': u'vol-298hfn3f348ff4f348f'}], u'key_name': u'emi-moni-profile', u'interfaces': [{u'id': u'eni-nf32f2fn48489r348', u'mac_address': u'41:9O:i7:dc:69:lO'}], u'persistent': False, u'image_id': u'ami-1k02nd83js84k6apO', u'groups': [{u'id': u'sg-Of11425adOe7f7d1a', u'name': u'launch-wizard-13'}], u'spot_instance_request_id': None, u'requester_id': None, u'source_destination_check': u'true', u'id': u'i-1O293847561OO293', u'tags': {u'App': u'ounje2', u'Name': u'Production Stack', u'Env': u'prod'}, u'public_ip_address': u'1.OO.1O9.111', u'monitoring_state': u'disabled', u'placement': {u'tenancy': u'default', u'zone': u'us-east-1c'}, u'ami_launch_index': u'O', u'hypervisor': u'xen', u'region': u'us-east-1', u'ebs_optimized': False, u'launch_time': u'2O19-O6-23TO4:54:56.OOOZ', u'public_dns_name': u'ec2-1-OO-1O9-111.compute-1.amazonaws.com', u'state': u'running', u'architecture': u'x86_94', u'private_ip_address': u'OO7-OO-69-42O', u'vpc_id': u'vpc-IaMhIdDeN', u'client_token': u'', u'virtualization_type': u'hvm'})
TASK [Store EC2 instance ID in var] *****************************************************************************************************************************
Monday 23 June 2O19 O1:17:29 -O4OO (O:OO:OO.173) O:OO:O4.176 ******
ok: [1.OO.1O9.111] =&amp;gt; { "instance_id": "i-1O293847561OO293"
}
PLAY RECAP ******************************************************************************************************************************************************
1.OO.1O9.111 : ok=5 changed=O unreachable=O failed=O
Monday 23 June 2O19 O1:17:29 -O4OO (O:OO:OO.11O) O:OO:O4.287 ******
===============================================================================
Gathering Facts ------------------------------------------------------------------------------------------------------------------------------------------ 2.23s
Get Instance IDs ----------------------------------------------------------------------------------------------------------------------------------------- 1.48s
Store EC2 instance ID ------------------------------------------------------------------------------------------------------------------------------------ O.17s
Store ounje hosts --------------------------------------------------------------------------------------------------------------------------------------- O.15s
Store EC2 instance ID in var ----------------------------------------------------------------------------------------------------------------------------- O.11s
Playbook run took O days, O hours, O minutes, 4 seconds
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;With no hostfile to maintain, you can deploy to freshly created instances spun up by terraform without having to worry about maintaining an hostfile.&lt;/p&gt;

</description>
      <category>ansible</category>
      <category>devops</category>
    </item>
    <item>
      <title>Ansible Error – “NSPlaceholderDate”</title>
      <dc:creator>iamtito</dc:creator>
      <pubDate>Mon, 18 May 2020 14:48:44 +0000</pubDate>
      <link>https://forem.com/iamtito/ansible-error-nsplaceholderdate-27c3</link>
      <guid>https://forem.com/iamtito/ansible-error-nsplaceholderdate-27c3</guid>
      <description>&lt;p&gt;If you are working in ansible and you try to run a playbook and you come across the error below 👇&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;TASK [Obtain secrets and deploy] ***********************************************************************************************************************************************************************************************
objc[6763]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called.
objc[6763]: +[__NSPlaceholderDate initialize] may have been in progress in another thread when fork() was called. We cannot safely call it or ignore it in the fork() child process. Crashing instead. Set a breakpoint on objc_initializeAfterForkError to debug.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;As mentioned in issue:&lt;a href="https://github.com/ansible/ansible/issues/31869"&gt;https://github.com/ansible/ansible/issues/31869&lt;/a&gt;&lt;br&gt;
This is an issue with macOS 10.13 where Apple changed the way fork() works on the OS which is incompatible with Python fork().&lt;/p&gt;

&lt;p&gt;Solution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To avoid doing it manually you can simply append it to your &lt;code&gt;bash_profile&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES" &amp;gt;&amp;gt; ~/.bash_profile
source ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



</description>
      <category>ansible</category>
      <category>bugfix</category>
    </item>
    <item>
      <title>Understanding Terraform on AWS: Spin Up EC2 Instances</title>
      <dc:creator>iamtito</dc:creator>
      <pubDate>Wed, 12 Feb 2020 11:53:43 +0000</pubDate>
      <link>https://forem.com/iamtito/understanding-terraform-part-ii-4il3</link>
      <guid>https://forem.com/iamtito/understanding-terraform-part-ii-4il3</guid>
      <description>&lt;p&gt;&lt;strong&gt;Deploying a server&lt;/strong&gt;&lt;br&gt;
Is it really easy to deploy a server using terraform?&lt;br&gt;
Part I - &lt;a href="https://dev.to/iamtito/understanding-terraform-152k"&gt;https://dev.to/iamtito/understanding-terraform-152k&lt;/a&gt;&lt;br&gt;
&lt;a href="https://i.giphy.com/media/YAnpMSHcurJVS/source.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://i.giphy.com/media/YAnpMSHcurJVS/source.gif" alt=""&gt;&lt;/a&gt;&lt;br&gt;
Terraform code is written in a language called HCL in files with the extension .tf. It is a declarative language. So the main goal will be to describe the infrastructure we want, and Terraform will create it. Firstly we have to configure the cloud provider(s) we want to use. Create a file called &lt;code&gt;resources.tf&lt;/code&gt; and add the following code in it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region = "us-east-1"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This instructs Terraform the cloud prover you would be using, in this case, it is aws and that you wish to deploy your infrastructure in the us-east-1 region. If you've already configured your credentials as environment variables, you only need to specify the region. However, if you didn't configure your creds as an environment variable, the below works. i.e it specifies the location of your aws credentials/config&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
    region = "us-east-1"
    shared_credentials_file = "/PATH/TO/AWS/CONFIG"
    profile                 = "myAWSprofile"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Once updated run the below to initialize the project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform init
Terraform has been successfully initialized!
You may now begin working with Terraform. Try running `terraform plan` to see
any changes that are required for your infrastructure. All Terraform commands
should now work.
If you ever set or change modules or backend configuration for Terraform,
rerun this command to reinitialize your working directory. If you forget, other
commands will detect it and remind you to do so if necessary.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Now, we want to deploy an ec2 instance of type &lt;code&gt;t2.micro&lt;/code&gt;. To do this, we need to specify the resource block and set the configuration of the resource block. i.e we need to set the ami (the Amazon Machine Image to run on the EC2 Instance) and the instance_type. Add the following code to &lt;code&gt;resources.tf&lt;/code&gt; file&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region = "us-east-1"
}
resource "aws_instance" "server" {
  ami = "ami-2d39803a"
  instance_type = "t2.micro"
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;To identify the resource in the terraform code, the resource specifies a type (in this case, &lt;code&gt;aws_instance&lt;/code&gt;), a name (in this case &lt;code&gt;server&lt;/code&gt;) and a set of configuration parameters specific to the resource. Resource block describes one or more infrastructure objects, such as virtual networks, compute instances, or higher-level components such as DNS records. Check out the resource documentation.&lt;br&gt;
To build the resource, its advisable to view the resource(s) that would be created before it gets created...use the below code to see what will happen to your infrastructure before applying/deploying it. This is a way to run a sanity test on your changes before deploying/applying it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.


------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  + create
Terraform will perform the following actions:
  + aws_instance.server
      id:                           &amp;lt;computed&amp;gt;
      ami:                          "ami-2d39803a"
      arn:                          &amp;lt;computed&amp;gt;
      associate_public_ip_address:  &amp;lt;computed&amp;gt;
      availability_zone:            &amp;lt;computed&amp;gt;
      cpu_core_count:               &amp;lt;computed&amp;gt;
      cpu_threads_per_core:         &amp;lt;computed&amp;gt;
      ebs_block_device.#:           &amp;lt;computed&amp;gt;
      ephemeral_block_device.#:     &amp;lt;computed&amp;gt;
      get_password_data:            "false"
      host_id:                      &amp;lt;computed&amp;gt;
      instance_state:               &amp;lt;computed&amp;gt;
      instance_type:                "t2.micro"
      ipv6_address_count:           &amp;lt;computed&amp;gt;
      ipv6_addresses.#:             &amp;lt;computed&amp;gt;
      key_name:                     &amp;lt;computed&amp;gt;
      network_interface.#:          &amp;lt;computed&amp;gt;
      network_interface_id:         &amp;lt;computed&amp;gt;
      password_data:                &amp;lt;computed&amp;gt;
      placement_group:              &amp;lt;computed&amp;gt;
      primary_network_interface_id: &amp;lt;computed&amp;gt;
      private_dns:                  &amp;lt;computed&amp;gt;
      private_ip:                   &amp;lt;computed&amp;gt;
      public_dns:                   &amp;lt;computed&amp;gt;
      public_ip:                    &amp;lt;computed&amp;gt;
      root_block_device.#:          &amp;lt;computed&amp;gt;
      security_groups.#:            &amp;lt;computed&amp;gt;
      source_dest_check:            "true"
      subnet_id:                    &amp;lt;computed&amp;gt;
      tenancy:                      &amp;lt;computed&amp;gt;
      volume_tags.%:                &amp;lt;computed&amp;gt;
      vpc_security_group_ids.#:     &amp;lt;computed&amp;gt;


Plan: 1 to add, 0 to change, 0 to destroy.
------------------------------------------------------------------------
Note: You didn't specify an "-out" parameter to save this plan, so Terraform
can't guarantee that exactly these actions will be performed if
"terraform apply" is subsequently run.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note: resources with a plus sign &lt;code&gt;+&lt;/code&gt; will be created, resources with a minus sign &lt;code&gt;-&lt;/code&gt; will be deleted, and resources with a tilde sign &lt;code&gt;~&lt;/code&gt; will be modified.&lt;br&gt;
To create an instance, run &lt;code&gt;terraform apply&lt;/code&gt;. Bypass the &lt;code&gt;yes&lt;/code&gt; prompt by using &lt;code&gt;terraform apply -auto-approve&lt;/code&gt; command to create the terraform resources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply -auto-approve
aws_instance.server: Creating...
  ami:                          "" =&amp;gt; "ami-2d39803a"
  arn:                          "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  associate_public_ip_address:  "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  availability_zone:            "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  cpu_core_count:               "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  cpu_threads_per_core:         "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  ebs_block_device.#:           "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  ephemeral_block_device.#:     "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  get_password_data:            "" =&amp;gt; "false"
  host_id:                      "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  instance_state:               "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  instance_type:                "" =&amp;gt; "t2.micro"
  ipv6_address_count:           "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  ipv6_addresses.#:             "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  key_name:                     "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  network_interface.#:          "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  network_interface_id:         "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  password_data:                "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  placement_group:              "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  primary_network_interface_id: "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  private_dns:                  "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  private_ip:                   "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  public_dns:                   "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  public_ip:                    "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  root_block_device.#:          "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  security_groups.#:            "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  source_dest_check:            "" =&amp;gt; "true"
  subnet_id:                    "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  tenancy:                      "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  volume_tags.%:                "" =&amp;gt; "&amp;lt;computed&amp;gt;"
  vpc_security_group_ids.#:     "" =&amp;gt; "&amp;lt;computed&amp;gt;"
aws_instance.server: Still creating... (10s elapsed)
aws_instance.server: Still creating... (20s elapsed)
aws_instance.server: Still creating... (30s elapsed)
aws_instance.server: Creation complete after 36s (ID: i-0bf984bef5ff354d6)
Apply complete! Resources: 1 added, 0 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Note: It took &lt;strong&gt;36s&lt;/strong&gt; for Terraform to provision an ec2 instance in aws, manually it could couple of minutes. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The state of the ec2 instance created and all the info attributed to the instance is stored in &lt;code&gt;terraform.tfstate&lt;/code&gt; file. Currently, its saved locally. In the coming next post, the state will be stored in a remote location to make it for easier version control, safer storage and outputs delegations to multiple teams. Terraform supports storing state in Terraform Cloud, HashiCorp Consul, Amazon S3, Alibaba Cloud OSS, and more.&lt;/p&gt;
&lt;/blockquote&gt;





&lt;center&gt;Viewing the state file🧐&lt;/center&gt;
&lt;br&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "version": 3,
    "terraform_version": "0.11.11",
    "serial": 1,
    "lineage": "c2d70ed5-xxxxx-xxxx-xxxx-xxxxxxxx",
    "modules": [
        {
            "path": [
                "root"
            ],
            "outputs": {},
            "resources": {
                "aws_instance.server": {
                    "type": "aws_instance",
                    "depends_on": [],
                    "primary": {
                        "id": "i-0bf984bef5ff354d6",
                        "attributes": {
                            "ami": "ami-2d39803a",
                            "arn": "arn:aws:ec2:us-east-1:139912354378:instance/i-0bf984bef5ff354d6",
                            "associate_public_ip_address": "true",
                            "availability_zone": "us-east-1c",
                            "cpu_core_count": "1",
                            "cpu_threads_per_core": "1",
                            "credit_specification.#": "1",
                            "credit_specification.0.cpu_credits": "standard",
                            "disable_api_termination": "false",
                            "ebs_block_device.#": "0",
                            "ebs_optimized": "false",
                            "ephemeral_block_device.#": "0",
                            "get_password_data": "false",
                            "iam_instance_profile": "",
                            "id": "i-0bf984bef5ff354d6",
                            "instance_state": "running",
                            "instance_type": "t2.micro",
                            "ipv6_addresses.#": "0",
                            "key_name": "",
                            "monitoring": "false",
                            "network_interface.#": "0",
                            "network_interface_id": "eni-0372xxxxxx",
                            "password_data": "",
                            "placement_group": "",
                            "primary_network_interface_id": "eni-0372xxxxxxx",
                            "private_dns": "ip-172-31-53-112.ec2.internal",
                            "private_ip": "172.31.53.112",
                            "public_dns": "ec2-52-91-71-43.compute-1.amazonaws.com",
                            "public_ip": "52.91.71.43",
                            "root_block_device.#": "1",
                            "root_block_device.0.delete_on_termination": "true",
                            "root_block_device.0.iops": "100",
                            "root_block_device.0.volume_id": "vol-0394832bb747e9bf1",
                            "root_block_device.0.volume_size": "8",
                            "root_block_device.0.volume_type": "gp2",
                            "security_groups.#": "1",
                            "security_groups.xxxx": "default",
                            "source_dest_check": "true",
                            "subnet_id": "subnet-xxxxxxx",
                            "tags.%": "0",
                            "tenancy": "default",
                            "volume_tags.%": "0",
                            "vpc_security_group_ids.#": "1",
                            "vpc_security_group_ids.xxxxx": "sg-xxxxxxxx"
                        },
                        "meta": {
                            "e2bfb730-xxxx-xxxx-xxx-xxxxxxx": {
                                "create": 600000000000,
                                "delete": 1200000000000,
                                "update": 600000000000
                            },
                            "schema_version": "1"
                        },
                        "tainted": false
                    },
                    "deposed": [],
                    "provider": "provider.aws"
                }
            },
            "depends_on": []
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




&lt;p&gt;Server deployment completed using Terraform! To verify, login to the EC2 console, and you'll see something like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--WgVezQIn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ucarecdn.com/a592bbb6-6787-4da2-b70d-f434b3062b81/" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--WgVezQIn--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://ucarecdn.com/a592bbb6-6787-4da2-b70d-f434b3062b81/" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice, the ec2-instance id output &lt;code&gt;i-0bf984bef5ff354d6&lt;/code&gt; is identical with the instance id on the aws console. Next, modify the ec2-instance by giving a tag name for the ec2 instance.&lt;br&gt;
Update the &lt;code&gt;resources.tf&lt;/code&gt; file by add thing tags&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;provider "aws" {
  region = "us-east-1"
}
resource "aws_instance" "server" {
  ami               = "ami-2d39803a"
  instance_type     = "t2.micro"
  tags {
      Name          = "server-one"
      Environment   = "Production"
      App           = "ecommerce"
  }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Run the plan to preview&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform plan
Refreshing Terraform state in-memory prior to plan...
The refreshed state will be used to calculate this plan, but will not be
persisted to local or remote state storage.

aws_instance.server: Refreshing state... (ID: i-0bf984bef5ff354d6)
------------------------------------------------------------------------
An execution plan has been generated and is shown below.
Resource actions are indicated with the following symbols:
  ~ update in-place
Terraform will perform the following actions:
  ~ aws_instance.server
      tags.%:           "0" =&amp;gt; "3"
      tags.App:         "" =&amp;gt; "ecommerce"
      tags.Environment: "" =&amp;gt; "Production"
      tags.Name:        "" =&amp;gt; "server-one"


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



&lt;p&gt;Note: You didn't specify an &lt;code&gt;-out&lt;/code&gt; parameter to save this plan, so Terraform&lt;br&gt;
can't guarantee that exactly these actions will be performed if&lt;br&gt;
&lt;code&gt;terraform apply&lt;/code&gt; is subsequently run.&lt;br&gt;
Since terraform keeps track of all the resources it created, therefore, it knows the ec2 instance already exists. The &lt;code&gt;id&lt;/code&gt; for the deployed ec2 instance is &lt;code&gt;i-0bf984bef5ff354d6&lt;/code&gt;, then it shows the difference between the current and new intended change, denoted with the sign &lt;code&gt;~&lt;/code&gt;. Apply the change and verify it on the console.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform apply -auto-approve
aws_instance.server: Refreshing state... (ID: i-0bf984bef5ff354d6)
aws_instance.server: Modifying... (ID: i-0bf984bef5ff354d6)
  tags.%:           "0" =&amp;gt; "3"
  tags.App:         "" =&amp;gt; "ecommerce"
  tags.Environment: "" =&amp;gt; "Production"
  tags.Name:        "" =&amp;gt; "server-one"
aws_instance.server: Modifications complete after 3s (ID: i-0bf984bef5ff354d6)
Apply complete! Resources: 0 added, 1 changed, 0 destroyed.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;It took &lt;strong&gt;3s&lt;/strong&gt; for terraform to apply this change to the ec2 instance.&lt;br&gt;
Source Code: &lt;a href="https://github.com/iamtito/DevOps/tree/Terraform/Terraform/example1"&gt;https://github.com/iamtito/DevOps/tree/Terraform/Terraform/example1&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That's all folks. Feel free to point out any mistake, make some corrections, and contribute to this post in the comment section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next.👉Attaching An ElasticIP and DNS Record(Route53) using terraform🙃&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>aws</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Understanding Terraform on AWS: Introduction, Installation And Setup</title>
      <dc:creator>iamtito</dc:creator>
      <pubDate>Mon, 10 Feb 2020 02:14:02 +0000</pubDate>
      <link>https://forem.com/iamtito/understanding-terraform-152k</link>
      <guid>https://forem.com/iamtito/understanding-terraform-152k</guid>
      <description>&lt;h3&gt;
  
  
  PART I - Introduction and Account Setup
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Introduction to Terraform&lt;/strong&gt;&lt;br&gt;
Terraform is a tool for building, changing, and versioning infrastructure safely and efficiently. Terraform can manage existing and popular service providers as well as custom in-house solutions. Managing existing resources on aws will require the importation of the resources to Terraform and be managed by Terraform, which will allow other resources to be built around it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Infrastructure as Code&lt;/strong&gt;&lt;br&gt;
Infrastructure is described using a high-level configuration syntax. This allows a blueprint of your datacenter to be versioned and treated as you would any other code. Additionally, infrastructure can be shared and re-used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Execution Plans&lt;/strong&gt;&lt;br&gt;
Terraform has a "planning" step where it generates an execution plan. The execution plan shows what Terraform will do when you call &lt;code&gt;terraform apply&lt;/code&gt;. This lets you avoid any surprises when Terraform manipulates infrastructure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform plan
+ aws_instance.example.11 ami: "ami-v1" instance_type: "t2.micro"
+ aws_instance.example.12 ami: "ami-v1" instance_type: "t2.micro"
+ aws_instance.example.13 ami: "ami-v1" instance_type: "t2.micro"
+ aws_instance.example.14 ami: "ami-v1" instance_type: "t2.micro"
+ aws_instance.example.15 ami: "ami-v1" instance_type: "t2.micro"
Plan: 5 to add, 0 to change, 0 to destroy.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;The above shows what will be added before the changes will be made on the infrastructure.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The use of variables&lt;/li&gt;
&lt;li&gt;resources importation&lt;/li&gt;
&lt;li&gt;infrastructure state file&lt;/li&gt;
&lt;li&gt;infrastructure diagram generator based on the state&lt;/li&gt;
&lt;li&gt;custom output variables&lt;/li&gt;
&lt;li&gt;Comparison of Infrastructure As Code tools&lt;/li&gt;
&lt;li&gt;interpolation&lt;/li&gt;
&lt;li&gt;Infrastructure versioning&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Setup AWS Account&lt;/strong&gt;&lt;br&gt;
Login to your aws account, go to your &lt;strong&gt;IAM console&lt;/strong&gt;, go to "&lt;strong&gt;Users&lt;/strong&gt;", click "&lt;strong&gt;Add user&lt;/strong&gt;" to generate an access key and a secret key. Under access type, check &lt;strong&gt;&lt;em&gt;Programmatic access&lt;/em&gt;&lt;/strong&gt;, Click the "&lt;strong&gt;Create user&lt;/strong&gt;" button on the last step and you will be able to see the security credentials for that user, which consist of Access Key ID and a Secret Access Key. You should save these keys immediately, as the Secret Access Key will never be shown again.&lt;br&gt;
In order for terraform to be able to make changes to our aws infrastructure, we need to set AWS credential for the user. On your terminal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export AWS_ACCESS_KEY_ID=(your access key id)
export AWS_SECRET_ACCESS_KEY=(your secret access key)
$ env |grep AWS
AWS_ACCESS_KEY_ID=XXXXXXXXXXXXXXXXXXXXXXX
AWS_SECRET_ACCESS_KEY=XXXXXXXXXXXXXXXXXXX
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;






&lt;p&gt;&lt;strong&gt;Install Terraform&lt;/strong&gt;&lt;br&gt;
To install Terraform, find the appropriate package for your system and download it. After downloading, unzip the package. Terraform runs as a single binary named terraform. Any other files in the package can be safely removed and Terraform will still function.&lt;br&gt;
The final step is to make sure that the terraform binary is available on the PATH. See this page for instruction on setting the PATH on Linux and Mac. This page contains instructions for setting the PATH on Windows.&lt;br&gt;
Easy installation:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Linux&lt;/em&gt;&lt;br&gt;
Download terraform for Linux&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ wget https://releases.hashicorp.com/terraform/0.xx.x/terraform_0.xx.x_linux_amd64.zip
$ unzip terraform_0.xx.x_linux_amd64.zip
set path 
$ sudo mv terraform /usr/local/bin
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Mac&lt;/em&gt;&lt;br&gt;
Using brew install is the quickest way brew install terraform. If you dont have homebre, install it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" &amp;lt; /dev/null 2&amp;gt; /dev/null
install ruby
brew install terraform
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Window&lt;/em&gt;&lt;br&gt;
 - Download terraform for windows&lt;/p&gt;

&lt;p&gt;Note: Terraform is packaged as a zip archive, so after downloading Terraform, unzip the package. Terraform runs as a single binary named terraform. Any other files in the package can be safely removed and Terraform will still function&lt;br&gt;
Copy files from the zip to c:\terraform for example. That's our terraform PATH.&lt;br&gt;
The final step is to make sure that the terraform binary is available on the PATH.&lt;br&gt;
Set the path in your system utility in control panel.&lt;/p&gt;

&lt;p&gt;Verifying the Installation&lt;br&gt;
After installing Terraform, verify the installation worked by opening a new terminal session and checking that terraform is available. By executing terraform you should see help output similar to this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ terraform
Usage: terraform [--version] [--help] &amp;lt;command&amp;gt; [args]
The available commands for execution are listed below.
The most common, useful commands are shown first, followed by
less common or more advanced commands. If you're just getting
started with Terraform, stick with the common commands. For the
other commands, please read the help and docs before usage.
Common commands:
    apply              Builds or changes infrastructure
    console            Interactive console for Terraform interpolations
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;If you get an error that terraform could not be found, your PATH environment variable was not set up properly. Please go back and ensure that your PATH variable contains the directory where Terraform was installed.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;That's all folks. Feel free to point out any mistake, make some corrections, and contribute to this post in the comment section.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next.👉&lt;a href="https://dev.to/iamtito/understanding-terraform-part-ii-4il3"&gt;Deploying a server using terraform&lt;/a&gt;🙃&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>devops</category>
      <category>aws</category>
    </item>
  </channel>
</rss>
