<?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>DEV Community: Msaghu</title>
    <description>The latest articles on DEV Community by Msaghu (@msaghu).</description>
    <link>https://dev.to/msaghu</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%2F751846%2Faf7ee6d6-8fb1-49d2-88fa-3202be9dfcc1.jpg</url>
      <title>DEV Community: Msaghu</title>
      <link>https://dev.to/msaghu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/msaghu"/>
    <language>en</language>
    <item>
      <title>Python for Data Analysis Cheatsheet</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Sat, 10 May 2025 10:51:58 +0000</pubDate>
      <link>https://dev.to/msaghu/python-for-data-science-cheatsheet-53gg</link>
      <guid>https://dev.to/msaghu/python-for-data-science-cheatsheet-53gg</guid>
      <description>&lt;p&gt;Pandas is a panda package for data manipulation and visualization. Pandas is built ontop of Numpy and Matlplotlib(data visualization). In pandas, data analysis is done on rectangular data which is represented as dataframes, in SQL they are referred to as tables.&lt;br&gt;
We will be using the data from a csv of 'russian alcohol consumption'.&lt;/p&gt;
&lt;h1&gt;
  
  
  Exploring a Dataframe using the table
&lt;/h1&gt;

&lt;p&gt;Returns first few rows of the dataframe&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.head&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the names of columns, and their data types and if they contain missing values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.info&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the number of rows and columns of the datframe displayed as a tuple. This is an attribute, not a method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.shape&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the summary statistics of the dataframe;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.describe&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the values in a  2D NumPy array&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.values&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the column names&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.columns&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get row numbers/row names&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.index&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  1. Dataframes
&lt;/h1&gt;

&lt;p&gt;Change order of the rows by sorting them using a particular column. This automatically sorts be ascending order, from smallest to the largest.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sorted_drinks &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.sort_values&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;sorted_drinks&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To sort by descending order&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sorted_drinks &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.sort_values&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="nv"&gt;ascending&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;False&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;sorted_drinks&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sort my multiple variables by passing a list to the method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sorted_drinks &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.sort_values&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, &lt;span class="nv"&gt;ascending&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;True, False]&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;sorted_drinks&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Subset &lt;em&gt;columns&lt;/em&gt; to only see the data in a particular column
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To subset multiple columns to only see the data in the particular columns&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[[&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;]])&lt;/span&gt;
or 
column_info &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[column_info]&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Subset &lt;em&gt;rows&lt;/em&gt; to only see the data in a particular column. It displays the answer in boolean True or False.;
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;]&amp;gt;&lt;/span&gt;1999&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the whole dataframe displayed with only the year above 2000;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[alcohol_df[&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;]&amp;gt;&lt;/span&gt;&lt;span class="s2"&gt;"1999"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or&lt;br&gt;
only where the region is "Chuvash Republic":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[alcohol_df[&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;]==&lt;/span&gt;&lt;span class="s2"&gt;"Chuvash Republic"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Combining these conditions to get multiple insights at once;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;c_republic &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df[&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;"Chuvash Republic"&lt;/span&gt;
wine_percent &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df[&lt;span class="s2"&gt;"wine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; 2.0
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[c_republic &amp;amp; wine_percent]&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Subset using .isin()
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;is_chuvash_or_yaroslavl &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df[&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.isin&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"Chuvash Republic"&lt;/span&gt;,&lt;span class="s2"&gt;"Yaroslavl Oblast"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[is_chuvash_or_yaroslavl]&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Adding new column
&lt;/h4&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;alcohol_df[&lt;span class="s2"&gt;"wine_m"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df[&lt;span class="s2"&gt;"wine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; / 100
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.head&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  2. Aggregating Data
&lt;/h1&gt;

&lt;p&gt;Calculate column mean&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[&lt;span class="s2"&gt;"wine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.mean&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We use the same method to calculate &lt;em&gt;.median(), .mode(), .min(), .max(), .var(), .std(), .sum()&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To get the earliest year&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.min&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the latest year&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.max&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use the .agg() method to compute custom summary statistics. To get the 30th percentile of the wines column&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;def pct30&lt;span class="o"&gt;(&lt;/span&gt;column&lt;span class="o"&gt;)&lt;/span&gt;:
    &lt;span class="k"&gt;return &lt;/span&gt;column.quantile&lt;span class="o"&gt;(&lt;/span&gt;0.3&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[&lt;span class="s2"&gt;"wine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.agg&lt;span class="o"&gt;(&lt;/span&gt;pct30&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To get the 30th percentile of multiple columns&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;def pct30&lt;span class="o"&gt;(&lt;/span&gt;column&lt;span class="o"&gt;)&lt;/span&gt;:
    &lt;span class="k"&gt;return &lt;/span&gt;column.quantile&lt;span class="o"&gt;(&lt;/span&gt;0.3&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[[&lt;span class="s2"&gt;"wine"&lt;/span&gt;, &lt;span class="s2"&gt;"beer"&lt;/span&gt;, &lt;span class="s2"&gt;"vodka"&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;.agg&lt;span class="o"&gt;(&lt;/span&gt;pct30&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;def pct40&lt;span class="o"&gt;(&lt;/span&gt;column&lt;span class="o"&gt;)&lt;/span&gt;:
    &lt;span class="k"&gt;return &lt;/span&gt;column.quantile&lt;span class="o"&gt;(&lt;/span&gt;0.4&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df[&lt;span class="s2"&gt;"wine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.agg&lt;span class="o"&gt;([&lt;/span&gt;pct30, pct40]&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cumulative statistics
&lt;/h3&gt;

&lt;p&gt;Calculating the cumulative sum of a column and return an entire column of the DataFrame&lt;br&gt;
&lt;em&gt;.cummax(), .cummin(), .cumprod()&lt;/em&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Remove repeat values
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.drop_duplicates&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;subset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;

unique &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.drop_duplicates&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;subset&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;,&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;unique&lt;span class="o"&gt;)&lt;/span&gt;

print&lt;span class="o"&gt;(&lt;/span&gt;unique[&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.value_counts&lt;span class="o"&gt;())&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;unique[&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.value_counts&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;True&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To turn the counts into proportions of the total&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;unique[&lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.value_counts&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;normalize&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;True&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Summary statistics
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.groupby&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;, &lt;span class="s2"&gt;"region"&lt;/span&gt;&lt;span class="o"&gt;])[&lt;/span&gt;&lt;span class="s2"&gt;"wine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.mean&lt;span class="o"&gt;())&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.groupby&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;)[&lt;/span&gt;&lt;span class="s2"&gt;"wine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.mean&lt;span class="o"&gt;())&lt;/span&gt;

print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.groupby&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;)[&lt;/span&gt;&lt;span class="s2"&gt;"wine"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;.agg&lt;span class="o"&gt;([&lt;/span&gt;min, max, &lt;span class="nb"&gt;sum&lt;/span&gt;&lt;span class="o"&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pivot Tables
&lt;/h3&gt;

&lt;p&gt;Groups elements together where, &lt;em&gt;values&lt;/em&gt; &lt;br&gt;
arguments is the column we want to summarize and the &lt;em&gt;index&lt;/em&gt; is the column we want to group by. The pivot will take the mean value of each group&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_df.pivot_table&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"wine"&lt;/span&gt;, &lt;span class="nv"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also done as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;import numpy as np
year_percent &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.pivot_table&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"wine"&lt;/span&gt;, &lt;span class="nv"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;, &lt;span class="nv"&gt;aggfunc&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;median&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;year_percent&lt;span class="o"&gt;)&lt;/span&gt;

import numpy as np
year_percent &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.pivot_table&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"wine"&lt;/span&gt;, &lt;span class="nv"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;, &lt;span class="nv"&gt;aggfunc&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;np.median, np.mean]&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;year_percent&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To group by 2 variables&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;year_percent &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.pivot_table&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"wine"&lt;/span&gt;, &lt;span class="nv"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;, &lt;span class="nv"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"week"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;year_percent&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To fill empty values&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;year_percent &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.pivot_table&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;values&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"wine"&lt;/span&gt;, &lt;span class="nv"&gt;index&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;, &lt;span class="nv"&gt;columns&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"week"&lt;/span&gt;, &lt;span class="nv"&gt;fill_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;0, &lt;span class="nv"&gt;margins&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;True&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;year_percent&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  3. Slicing and Indexing Data
&lt;/h1&gt;

&lt;p&gt;Setting a column as the index&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;alcohol_ind &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.set_index&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_ind&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Removing an index&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_ind.reset_index&lt;span class="o"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can drop the index, therefore fully removing it from our dataframe&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_ind.reset_index&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;drop&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;True&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Subset on index values using loc&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_ind.loc[[2000,2003]]&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Multi-level indexes&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;alcohol_ind3 &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.set_index&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;.sort_index&lt;span class="o"&gt;()&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_ind3.loc[[&lt;span class="s2"&gt;"Amur Oblast"&lt;/span&gt;&lt;span class="o"&gt;]])&lt;/span&gt;

alcohol_ind4 &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.set_index&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_ind4.loc[[&lt;span class="s2"&gt;"Amur Oblast"&lt;/span&gt;, &lt;span class="s2"&gt;"Sakha (Yakutia) Republic"&lt;/span&gt;&lt;span class="o"&gt;]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Subsetting with a list of tuples&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;alcohol_ind4 &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.set_index&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_ind4.loc[[&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Amur Oblast"&lt;/span&gt;, 2000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Sakha (Yakutia) Republic"&lt;/span&gt;, 2000&lt;span class="o"&gt;)]])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Controlling the sort index&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_ind4 &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.sort_index&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;level&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;, &lt;span class="nv"&gt;ascending&lt;/span&gt;&lt;span class="o"&gt;=[&lt;/span&gt;True, False]&lt;span class="o"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Slicing and subsetting with .loc and .iloc&lt;br&gt;
This works on only outer index levels, if we want to index inner levels, we need to pass tuples&lt;br&gt;
Slicing the outer index level, but first we sort the index&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;alcohol_srt &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.set_index&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;.sort_index&lt;span class="o"&gt;()&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_srt.loc[2000:2005]&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Slicing columns&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;alcohol_srt &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.set_index&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;.sort_index&lt;span class="o"&gt;()&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_srt.loc[2000:2005]&lt;span class="o"&gt;)&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;alcohol_srt.loc[:, &lt;span class="s2"&gt;"region"&lt;/span&gt;:&lt;span class="s2"&gt;"wine"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Slicing on rows and columns at the same time&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#Wine consumption for the year 2000 for "Amur Oblast", "Astrakhan Oblast"&lt;/span&gt;

alcohol_srt &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.set_index&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;.sort_index&lt;span class="o"&gt;()&lt;/span&gt;
years_ind &lt;span class="o"&gt;=&lt;/span&gt; alcohol_srt.loc[[&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Amur Oblast"&lt;/span&gt;, 2000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Sakha (Yakutia) Republic"&lt;/span&gt;, 2000&lt;span class="o"&gt;)]]&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;years_ind.loc[:, &lt;span class="s2"&gt;"wine"&lt;/span&gt;:&lt;span class="s2"&gt;"beer"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#Wine consumption for the year 2000 for "Amur Oblast", "Astrakhan Oblast"&lt;/span&gt;
alcohol_srt &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.set_index&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;.sort_index&lt;span class="o"&gt;()&lt;/span&gt;
years_ind &lt;span class="o"&gt;=&lt;/span&gt; alcohol_srt.loc[[&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Amur Oblast"&lt;/span&gt;, 2000&lt;span class="o"&gt;)&lt;/span&gt;:&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Sakha (Yakutia) Republic"&lt;/span&gt;, 2000&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="s2"&gt;"wine"&lt;/span&gt;:&lt;span class="s2"&gt;"beer"&lt;/span&gt;&lt;span class="o"&gt;]]&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;years_ind&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Wine and beer consumption for the year 2000-2010 from the regions "Amur Oblast"only&lt;/span&gt;
alcohol_srt &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.set_index&lt;span class="o"&gt;([&lt;/span&gt;&lt;span class="s2"&gt;"region"&lt;/span&gt;, &lt;span class="s2"&gt;"year"&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt;.sort_index&lt;span class="o"&gt;()&lt;/span&gt;
years_ind &lt;span class="o"&gt;=&lt;/span&gt; alcohol_srt.loc[&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Amur Oblast"&lt;/span&gt;, 2000&lt;span class="o"&gt;)&lt;/span&gt;:&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Amur Oblast"&lt;/span&gt;, 2010&lt;span class="o"&gt;)&lt;/span&gt;, &lt;span class="s2"&gt;"wine"&lt;/span&gt;:&lt;span class="s2"&gt;"beer"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
print&lt;span class="o"&gt;(&lt;/span&gt;years_ind&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Slicing row and column number using iloc method&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;years_ind &lt;span class="o"&gt;=&lt;/span&gt; alcohol_df.iloc[2:5, 1:4]
print&lt;span class="o"&gt;(&lt;/span&gt;years_ind&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  4. Creating and Visualizing data
&lt;/h1&gt;

</description>
      <category>programming</category>
      <category>python</category>
      <category>pandas</category>
    </item>
    <item>
      <title>Launching a Static Website using AWS Amplify with CI/CD! v1</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Wed, 03 Jan 2024 19:01:17 +0000</pubDate>
      <link>https://dev.to/msaghu/launching-a-static-website-using-aws-amplify-with-cicd-v1-1loe</link>
      <guid>https://dev.to/msaghu/launching-a-static-website-using-aws-amplify-with-cicd-v1-1loe</guid>
      <description>&lt;p&gt;Happy New Year 2024! Big things in store for 2024 but first, lets launch our very first personal website using AWS. This will be my very first iteration of the website that I will update weekly, hopefully! If you have any comments/recommendations, please contact me below via the message box in my website!&lt;br&gt;
The website will go through numerous iterations by the time 2024 ends so come along and we will learn/go through all its versions!&lt;/p&gt;

&lt;p&gt;First about the website. I followed a website locally on my laptop using VSCode and the languages of choice were HTML, CSS and React. &lt;/p&gt;
&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Must know how to use Git and Github&lt;/li&gt;
&lt;li&gt;VSCode installed&lt;/li&gt;
&lt;li&gt;Must have the code for our website&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  What is AWS Amplify?
&lt;/h2&gt;

&lt;p&gt;AWS Amplify is a set of purpose-built tools and features that enables frontend web and mobile developers to quickly and easily build full-stack applications on AWS. Amplify provides two services: Amplify Hosting and Amplify Studio. For this instance we will be using Amplify Hosting . It provides a git-based workflow for hosting full-stack serverless web apps with continuous deployment. &lt;/p&gt;
&lt;h2&gt;
  
  
  Creating and connecting a repository
&lt;/h2&gt;

&lt;p&gt;Since our application was written in React, we can follow the following steps as is:&lt;/p&gt;
&lt;h3&gt;
  
  
  1. Upload our development code to Github
&lt;/h3&gt;

&lt;p&gt;If you already used an online code editor such as Gitpod, these steps will be somehow similar.&lt;/p&gt;
&lt;h4&gt;
  
  
  a. New repository
&lt;/h4&gt;

&lt;p&gt;Create a new GitHub repository for your app (link)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Zpknqh3n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uz6exzu35i6r1p4json.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Zpknqh3n--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5uz6exzu35i6r1p4json.png" alt="Creating Github repository" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  b. Push code to the repository
&lt;/h4&gt;

&lt;p&gt;From VSCode we will now initialize git and push the application to the new GitHub repo we created above. Execute the following commands in your command line interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
git remote add origin https://github.com/Msaghu/dhfhkdfkfj.git
git remote -v
git pull origin master
git add .
git commit -m “initial commit”
git push origin master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;i. Line 1* &amp;gt; &lt;br&gt;
if 'WebApp' is the folder you have your local web app. Change it to the directory &lt;code&gt;cd WebApp&lt;/code&gt;&lt;br&gt;
ii. Line 1 &amp;gt;&lt;br&gt;
initialize git in the folder&lt;br&gt;
iii. Line 2 &amp;gt;&lt;br&gt;
add github url as a remote&lt;br&gt;
 get the git@github command from the HTTPS tab on Github.&lt;br&gt;
iv. Line 3 &amp;gt;&lt;br&gt;
Now pull the read me file from the github repo&lt;br&gt;
v. Line 4 &amp;gt;&lt;br&gt;
Verify that the Remote URL added or not utilizing the following command:&lt;/p&gt;

&lt;h4&gt;
  
  
  c. Connect your repository,
&lt;/h4&gt;

&lt;p&gt;log in to the Amplify Console and choose Get Started at the top of the page then Get Started under Amplify Hosting.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--fLmEPvh0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1yvof1cah5fblcb5buq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fLmEPvh0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w1yvof1cah5fblcb5buq.png" alt="AWS Amplify" width="800" height="397"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  d. Select preferred VCS
&lt;/h4&gt;

&lt;p&gt;On the Get started with Amplify Hosting page, select GitHub and choose Continue.&lt;br&gt;
On the Add repository branch step, select yourbranchname from the Select a repository dropdown.&lt;br&gt;
We will then need to authorize AWS Amplify to your GitHub account.&lt;br&gt;
In the Branch dropdown select the branch master and choose Next. &lt;/p&gt;

&lt;h4&gt;
  
  
  e.
&lt;/h4&gt;

&lt;p&gt;On the Build settings page, leave all the defaults, select Allow AWS Amplify to automatically deploy all files hosted in your project root directory and choose Next.&lt;/p&gt;

&lt;p&gt;On the Review page select Save and deploy.&lt;/p&gt;

&lt;h4&gt;
  
  
  f. Deploy
&lt;/h4&gt;

&lt;p&gt;The process takes a couple of minutes for Amplify Console to create the necessary resources and to deploy your code.&lt;br&gt;
Once completed, select the site image, or the link underneath the thumbnail to launch your website. &lt;/p&gt;

&lt;p&gt;You have now successfully launched your website!&lt;/p&gt;

&lt;h2&gt;
  
  
  RESOURCES
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=4ag1LsgIUc0"&gt;Create a React Portfolio Website&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://aws.amazon.com/getting-started/hands-on/host-static-website/"&gt;Hosting a Static Website on AWS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[AWS Amplify Documentation](&lt;a href="https://docs.aws.amazon.com/amplify/latest/userguide/welcome.html"&gt;https://docs.aws.amazon.com/amplify/latest/userguide/welcome.html&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>aws</category>
      <category>amplify</category>
      <category>staticwebapps</category>
      <category>react</category>
    </item>
    <item>
      <title>Terraform Cloud Project Bootcamp with Andrew Brown - Storing the state file in Terraform Cloud</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Wed, 22 Nov 2023 19:08:35 +0000</pubDate>
      <link>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-storing-the-state-file-in-terraform-cloud-41cb</link>
      <guid>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-storing-the-state-file-in-terraform-cloud-41cb</guid>
      <description>&lt;p&gt;Hi guys , in this piece we will learn how to store the terraform state file that is created when we run &lt;code&gt;terraform apply&lt;/code&gt; to Terraform Cloud.&lt;/p&gt;

&lt;p&gt;This article is part of my Terraform journey with &lt;a href="https://www.youtube.com/watch?v=TXjzwiHtGqc&amp;amp;t=5852s" rel="noopener noreferrer"&gt;Terraform Bootcamp&lt;/a&gt; by Andrew Brown and Andrew Bayko, together with Chris Williams(I am also using his resources that he published &lt;a href="https://www.freecodecamp.org/news/terraform-certified-associate-003-study-notes/#preparation-materials" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the beloved Shala Warner. I am also using some other resources from &lt;a href="https://www.youtube.com/@mastermnd" rel="noopener noreferrer"&gt;Aaron Brooks&lt;/a&gt; so that I can better explain new terms. And a special shout out to &lt;a href="https://medium.com/@gwenleigh/terraform-cloud-project-bootcamp-with-andrew-brown-complete-learning-journal-3640cebc74b5" rel="noopener noreferrer"&gt;Gwen Leigh&lt;/a&gt; for such a helpful outline that I used as a guide to create this series so that the documentation is easy to read!&lt;/p&gt;

&lt;p&gt;As I learn more about Terraform, feel free to follow &lt;a href="https://www.youtube.com/@ExamProChannel" rel="noopener noreferrer"&gt;Andrew Brown on Youtube&lt;/a&gt; and see their free (and paid) content . Now let's jump in. &lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
Persisiting our local state file in Terraform Cloud 

&lt;ul&gt;
&lt;li&gt;What are Terraform State files?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

Create a Terraform Cloud account

&lt;ul&gt;
&lt;li&gt;1. We will create a new project called &lt;code&gt;terraform-beginner-bootcamp2023&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;2. Create a new workspace within the project.&lt;/li&gt;
&lt;li&gt;3. Run &lt;code&gt;terraform init&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;4. Generating our terraform state file&lt;/li&gt;
&lt;li&gt;5. Choose our preferred workflow&lt;/li&gt;
&lt;li&gt;6. In &lt;code&gt;main.tf&lt;/code&gt; file, we will edit it as below&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Automating the creation of the terraform login &lt;/li&gt;

&lt;li&gt;Resources&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Persisiting our local state file in Terraform Cloud
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What are Terraform State files?
&lt;/h3&gt;

&lt;p&gt;The statefile can contain a lot of secrets!!!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;resource IDs&lt;/li&gt;
&lt;li&gt;DB username/passwords&lt;/li&gt;
&lt;li&gt;private keys&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So you should treat it like you would your company passwords. By default local state is stored in plaintext as JSON. You can mark sensitive information in your config files as such with the &lt;code&gt;sensitive = true argument&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;redacted from the CLI output, but still is in the statefile as plaintext (that's why it's important to lock down the statefile).&lt;/p&gt;

&lt;p&gt;Use a backend that encrypts and protects your statefile from unauthorized access.&lt;/p&gt;

&lt;p&gt;TFC encrypts state at rest &amp;amp; in transit&lt;br&gt;
Turn on encryption if you are using S3 (&amp;amp; use state locking!)&lt;br&gt;
Terraform does not persist state to local disk when remote state is being used&lt;/p&gt;
&lt;h2&gt;
  
  
  Create a Terraform Cloud account
&lt;/h2&gt;

&lt;p&gt;We will need to create a Terraform Cloud account &lt;a href="https://app.terraform.io/session" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A Terraform project can have multiple workspaces, and a workspace is a configuration for an infrastructure project.&lt;/p&gt;
&lt;h3&gt;
  
  
  1. We will create a new project called &lt;code&gt;terraform-beginner-bootcamp2023&lt;/code&gt;.
&lt;/h3&gt;
&lt;h3&gt;
  
  
  2. Create a new workspace within the project.
&lt;/h3&gt;
&lt;h3&gt;
  
  
  3. Run &lt;code&gt;terraform init&lt;/code&gt;
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We have to run this multiple times because our Gitpod environment is restarted every time we shut down. We dont have to do this if we are doing this project on a local machine/environment.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  4. Generating our terraform state file
&lt;/h3&gt;

&lt;p&gt;To generate our terraform state file &lt;code&gt;terraform.tfstate&lt;/code&gt;,  we will run &lt;code&gt;terraform apply --auto-approve&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Since Terraform is agnostic, we can store our statefile in S3, locally or on Terraform Cloud.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  5. Choose our preferred workflow
&lt;/h3&gt;

&lt;p&gt;We will choose our preferred workflow in Terraform Cloud, which is the &lt;code&gt;CLI-driven workflow&lt;/code&gt;, name the workspace, &lt;code&gt;terrahouse-1&lt;/code&gt;. and add in the description. Create the workspace and. The organization will appear as below, with the name and email address already filled in&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kvs83bwbila7dp8p38p.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4kvs83bwbila7dp8p38p.png" alt="Creating an organization 1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjm2ifqzuk3hwzpq912uq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjm2ifqzuk3hwzpq912uq.png" alt="Creating an organization 2"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  6. In &lt;code&gt;main.tf&lt;/code&gt; file, we will edit it as below
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;terraform {
  cloud {
    organization = "msaghu"

    workspaces {
      name = "terra-house-renaissance"
    }
  }

  required_providers {
    random = {
      source = "hashicorp/random"
      version = "3.5.1"
    }
    aws = {
      source = "hashicorp/aws"
      version = "5.19.0"
    }
  }
}

provider "aws" {
  # Configuration options
}

provider "random" {
  # Configuration options
}

#https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string
resource "random_string" "bucket_name" {
  lower = true
  upper = false
  length           = 32
  special          = false
}

#Terraform AWS S3 
#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket
resource "aws_s3_bucket" "example" {
  #bUCKET NAMING RULES
  #https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html
  bucket = random_string.bucket_name.result
}

output "random_bucket_name" {
  value = random_string.bucket_name.result
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;We have the organization as the organization name we made when creating a Terraform Cloud
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;  backend "remote" {
    hostname = "app.terraform.io"
    organization = "company"

    workspaces {
      name = "my-app-prod"
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Establish a connection to Terraform cloud, run;
&lt;code&gt;terraform login&lt;/code&gt; and enter yes when prompted&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the Terraform Cloud page, go to the Tokens tab and copy the token provided.&lt;/p&gt;

&lt;p&gt;Create a file in Gitpod &lt;code&gt;touch /home/gitpod/.terraform.d/credentials.tfrc.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Open the file &lt;code&gt;open /home/gitpod/.terraform.d/credentials.tfrc.json&lt;/code&gt; and add in the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "credentials": {
    "app.terraform.io": {
      "token": "YOUR_TERRAFORMCLOUD_TOKEN//PASTE IN THE CODE ABOV"
    }
  }
}

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

&lt;/div&gt;



&lt;p&gt;Save and close the file&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run &lt;code&gt;terraform init&lt;/code&gt; which will tell you that it wants to copy the &lt;code&gt;terraform.tfstate&lt;/code&gt; file to Terraform. When prompted enter &lt;strong&gt;yes&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Go to Terraform cloud and see that the resources were created when we ran terraform init, plan and apply, i.e the S3 bucket and its random name, can now be seen on the Terraform cloud workspace.&lt;/p&gt;

&lt;h2&gt;
  
  
  Automating the creation of the terraform login
&lt;/h2&gt;

&lt;p&gt;If we are using a workspace like Gitpod, we will need to do this step. Find the code &lt;a href="https://github.com/Msaghu/terraform-beginner-bootcamp-2023/tree/15-automating-the-creation-of-tfrc-credentials" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;br&gt;
We need to create &lt;code&gt;credentials.tfrc.json&lt;/code&gt;;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;In Terraform Cloud, create a user token for about 30 days.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the token as an environment variable in Gitpod by adding in the terminal;&lt;br&gt;
&lt;code&gt;gp env TERRAFORM_CLOUD_TOKEN='usertokenfor30daysusertokenfor30daysusertokenfor30daysusertokenfor30days'&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;then&lt;br&gt;
&lt;code&gt;export TERRAFORM_CLOUD_TOKEN='usertokenfor30daysusertokenfor30daysusertokenfor30daysusertokenfor30days'&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We will create a bash file that will generate the tfrc credentials in bin folder ; &lt;code&gt;bin/generate_tfrc_credentials&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env bash

# Define the target directory
TARGET_DIR="/home/gitpod/.terraform.d"
TARGET_FILE="${TARGET_DIR}/credentials.tfrc.json"

# Check if the TERRAFORM_CLOUD_TOKEN environment variable is set
if [ -z "$TERRAFORM_CLOUD_TOKEN" ]; then
  echo "Error: TERRAFORM_CLOUD_TOKEN environment variable is not set."
  exit 1
fi

# Create the directory if it doesn't exist
if [ ! -d "$TARGET_DIR" ]; then
  mkdir -p "$TARGET_DIR"
fi

# JSON structure for credentials.tfrc.json
json_data='{
  "credentials": {
    "app.terraform.io": {
      "token": "'"$TERRAFORM_CLOUD_TOKEN"'"
    }
  }
}'

# Write the JSON data to credentials.tfrc.json
echo "$json_data" &amp;gt; "$TARGET_FILE"

echo "$TARGET_FILE has been generated."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Change the file permissions by 'chmod u+x .&lt;code&gt;bin/generate_tfrc_credentials&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Make sure to note the Terraform 30 day token somewhere but DO NOT commit the file.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/tutorials/cloud/cloud-migrate" rel="noopener noreferrer"&gt;Migrating state to Terraform Cloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/language/settings/backends/remote" rel="noopener noreferrer"&gt;Terraform backend remote&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/terraform-certified-associate-003-study-notes/#use-terraform-outside-the-core-workflow" rel="noopener noreferrer"&gt;Terraform Certified Associate (003) by Chris Williams&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>terraform</category>
      <category>terraformstate</category>
      <category>terraformcloud</category>
      <category>aws</category>
    </item>
    <item>
      <title>Terraform Cloud Project Bootcamp with Andrew Brown - Creating a command alias</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Wed, 22 Nov 2023 18:59:50 +0000</pubDate>
      <link>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-creating-a-command-alias-4oa2</link>
      <guid>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-creating-a-command-alias-4oa2</guid>
      <description>&lt;p&gt;Hi guys , in this piece we will learn how to create an alias for the terraform command i.e instead of using terraform init, we use &lt;code&gt;tf init&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This article is part of my Terraform journey with &lt;a href="https://www.youtube.com/watch?v=TXjzwiHtGqc&amp;amp;t=5852s"&gt;Terraform Bootcamp&lt;/a&gt; by Andrew Brown and Andrew Bayko, together with Chris Williams(I am also using his resources that he published &lt;a href="https://www.freecodecamp.org/news/terraform-certified-associate-003-study-notes/#preparation-materials"&gt;here&lt;/a&gt; and the beloved Shala Warner. I am also using some other resources from &lt;a href="https://www.youtube.com/@mastermnd"&gt;Aaron Brooks&lt;/a&gt; so that I can better explain new terms. And a special shout out to &lt;a href="https://medium.com/@gwenleigh/terraform-cloud-project-bootcamp-with-andrew-brown-complete-learning-journal-3640cebc74b5"&gt;Gwen Leigh&lt;/a&gt; for such a helpful outline that I used as a guide to create this series so that the documentation is easy to read!&lt;/p&gt;

&lt;p&gt;As I learn more about Terraform, feel free to follow &lt;a href="https://www.youtube.com/@ExamProChannel"&gt;Andrew Brown on Youtube&lt;/a&gt; and see their free (and paid) content . Now let's jump in. &lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;[Shortening commands ; creating tf instead of Terraform](#shortening-commands-ccreating-tf-instead-of-ter&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Shortening commands ; creating tf instead of Terraform
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Set an alias for terraform to be &lt;code&gt;tf&lt;/code&gt; in terraform, this can be replicated across other projects as you may like. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open &lt;code&gt;~/.bash_profile&lt;/code&gt; for the terminal where we can set bash configurations/bash commands.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add in a line&lt;br&gt;
&lt;code&gt;alias tf="terraform"&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We need to reload the file, therefore we will run &lt;code&gt;source ~/.bash_profile&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To make sure that it is set, type &lt;code&gt;tf&lt;/code&gt; in the terminal to test it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To persist it, we need to create a bash script for it;&lt;br&gt;
Create a new file &lt;code&gt;set_tf_alias&lt;/code&gt; and paste in;&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;#!/usr/bin/env bash

#Checks if the alias already exists in the .bash_profile
grep -q 'alias tf="terraform"' ~/.bash_profile

# $? is a special variable in bash that holds the exit status of the last
if [ $? -ne 0 ]; then
    #if the alias does not exist, append it
    echo 'alias tf="terraform"' &amp;gt;&amp;gt; ~/.bash_profile
    echo "Alias added successfully."
else
    # inform the user if the alias already exists
    echo "Alias already exists in .bash_profile"
fi 

#Optional: source the .bash_profile to make the alias variable immediately
source ~/.bash_profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Change its permissions in the terminal; &lt;br&gt;
&lt;code&gt;chmod u+x ./bin/set_tf_alias&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Execute it in the terminal(it should say that its already created`&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Add it to &lt;code&gt;gitpod.yml&lt;/code&gt; and add it for both terraform and aws.&lt;br&gt;
&lt;code&gt;&lt;/code&gt;`&lt;br&gt;
tasks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;name: terraform
before: |
source ./bin/set_tf_alias
source ./bin/install_terraform_cli
source ./bin/generate_tfrc_credentials&lt;/li&gt;
&lt;li&gt;name: aws-cli
env:
AWS_CLI_AUTO_PROMPT: on-partial
before: |
source ./bin/set_tf_alias
source ./bin/install_aws_cli&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;vscode:&lt;br&gt;
  extensions:&lt;br&gt;
    - amazonwebservices.aws-toolkit-vscode&lt;br&gt;
    - hashicorp.terraform&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restart the workspace to make sure that it loads as expected.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>terraform</category>
      <category>aws</category>
      <category>terraformcloud</category>
      <category>hashicorp</category>
    </item>
    <item>
      <title>Terraform Cloud Project Bootcamp with Andrew Brown - Git Basics</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Wed, 22 Nov 2023 18:54:47 +0000</pubDate>
      <link>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-git-basics-19aa</link>
      <guid>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-git-basics-19aa</guid>
      <description>&lt;p&gt;Hi , guys. I have had quite an informative class in Andrew Brown's bootcamp. Here are a few items I have been able to pick up from the class regarding Git. &lt;/p&gt;

&lt;p&gt;I will be showcasing examples where I demonstrate the steps one would take when executing a certain task and the definitions. In this use-case, we will be using GIT that has been installed on our Gitpod account.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;a href="https://www.gitpod.io/"&gt;Gitpod&lt;/a&gt; environment that gives you 500 free credits per month!&lt;/li&gt;
&lt;li&gt;If you will not be using Gitpod, make sure that Git is installed on your local computer.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is Git?
&lt;/h2&gt;

&lt;h2&gt;
  
  
  Installing Git on Gitpod environment
&lt;/h2&gt;

&lt;p&gt;Install a Gitpod extension on Chrome to access Gitpod on Github.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Semantic Versioning in Git?
&lt;/h2&gt;

&lt;h2&gt;
  
  
  The basic git workflow
&lt;/h2&gt;

&lt;p&gt;The basic Git workflow goes something like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You modify files in your working tree.&lt;/li&gt;
&lt;li&gt;You selectively stage just those changes you want to be part of your next commit, which adds only those changes to the staging area.&lt;/li&gt;
&lt;li&gt;You do a commit, which takes the files as they are in the staging area and stores that snapshot permanently to your Git directory.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;But what happens if we want to provide better/streamlined and seamless workflow for a project? Then we follow the lead below;&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic Git workflow chart for projects or for this project:
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FP4Tz-PU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxcf0edjrhz7zhqpdc2n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FP4Tz-PU--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lxcf0edjrhz7zhqpdc2n.jpg" alt="Image description" width="800" height="450"&gt;&lt;/a&gt;&lt;sup&gt;1&lt;/sup&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Stage 1: Create an Issue&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the github page, choose &lt;code&gt;Issues&lt;/code&gt; and choose &lt;code&gt;Create new issue&lt;/code&gt;. Then add a title to it and &lt;code&gt;Submit the new issue&lt;/code&gt;. You the right hand side, &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a new issue and create a label for it i.e is it a bug?, is it documentation?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Stage 2: Create a Branch&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Create a branch&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stage 3: Merge the Branch into Main&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stage 4: Verify&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Stage 1: Creating an issue
&lt;/h3&gt;

&lt;p&gt;We create a ticket/issue then name the branch after the feature issue i.e &lt;code&gt;1-a-new-issue&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--QmeBhfcr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydeqzg3c7krakk09ulaa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--QmeBhfcr--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ydeqzg3c7krakk09ulaa.png" alt="Creating a Github issue" width="800" height="343"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The issue will give us a number which we can use to create the branch with the command below.&lt;/p&gt;

&lt;h3&gt;
  
  
  Stage 2: Create a Branch
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oK9K2Udy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdav4jghn02ijszsl2xd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oK9K2Udy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/mdav4jghn02ijszsl2xd.png" alt="Creating a branch from the issue" width="800" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In the issues page, on the right hand, scroll down and select &lt;code&gt;create branch&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;The branch name should be the same as the issue name with the issue number, and accept &lt;code&gt;checkout locally&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Choose the create branch button. &lt;/p&gt;

&lt;p&gt;In our terminal, we can now create the branch. Then run the command below to streamline the code from the remote repository &lt;br&gt;
&lt;code&gt;&lt;br&gt;
git fetch origin&lt;br&gt;
git checkout 1-a-new-issue&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Stage 3: Merge the Branch into Main
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Pushing the code to the remote branch on Github
&lt;/h4&gt;

&lt;p&gt;In the version control knob in VSCode/ Gitpod , we can view the changes made. We will then stage the changes and then commit them with a commit message and the issue number i.e&lt;br&gt;
&lt;code&gt;#1 added an emoji to the code&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;If asked,  sync the changes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In the Git tree,&lt;br&gt;
&lt;strong&gt;main&lt;/strong&gt; are the files on your local machine,&lt;br&gt;
&lt;strong&gt;origin&lt;/strong&gt; the files on Github&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4&gt;
  
  
  Create a pull request
&lt;/h4&gt;

&lt;p&gt;Go to the Git tree and view the tag position which we now want to pull into the main branch.&lt;/p&gt;
&lt;h3&gt;
  
  
  Stage 4: Verify and Sync the changes
&lt;/h3&gt;

&lt;p&gt;In Github, go to pull requests then;&lt;/p&gt;
&lt;h4&gt;
  
  
  1. Create a pull request
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Bring the feature branch to main&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add a comment to the pull request.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Squash and merge the commit&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm the squash and merge.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Commit the changes
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;git commit&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Push the changes to remote
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;git push&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Go back to main
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;git checkout main&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Pull the changes
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;git pull&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Create a tag for the branch
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;git tag 0.1.0&lt;/code&gt;&lt;/p&gt;
&lt;h4&gt;
  
  
  Push the tags to remote Github branch
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;git push --tags&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Refresh on Github and make sure that the branches and the tags have been created.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In a larger team the squashed branch will be deleted to clear the version control code.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Switching to a branch from main
&lt;/h2&gt;

&lt;p&gt;If we have a branch that we have made changes in and we want to move into it from &lt;code&gt;main&lt;/code&gt;, we can follow the following steps.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git fetch
git add .
git stash save
git checkout branch name
git stash apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  We made changes to main instead of the branch, what do we do?
&lt;/h2&gt;

&lt;p&gt;Mistakes happen, even to the most meticulous of us, so don't fret. Here's what to do;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add .
git stash save
git stash list
git fetch
git checkout the-branch-we-should-have-made-changes-in
git pull
git stash apply
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;git stash list&lt;/code&gt; temporarily stores files&lt;br&gt;
&lt;code&gt;git fetch&lt;/code&gt; shows you all the new branch&lt;/p&gt;

&lt;h2&gt;
  
  
  To create tags
&lt;/h2&gt;

&lt;blockquote&gt;

&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout main
git pull
git tag 0.1.0
git push --tags
git fetch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HOW TO AUTOMATE DELETION OF BRANCHES AFTER MERGING&lt;br&gt;
HOW TO AUTOMATE TAGGING OF BRANCHES &lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=yh9kz9Sh1T8&amp;amp;list=PLBfufR7vyJJ7k25byhRXJldB5AiwgNnWv&amp;amp;index=3"&gt;Setting up a Gitpod account&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=A6_c-hJmehs&amp;amp;list=PLBfufR7vyJJ7k25byhRXJldB5AiwgNnWv&amp;amp;index=4"&gt;Add the Gitpod extension to chrome&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.youtube.com/results?search_query=cyberinsight"&gt;Cyber Insight Git workflow image&lt;/a&gt;&lt;sup&gt;1&lt;/sup&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>git</category>
      <category>cicd</category>
      <category>terraform</category>
      <category>vcs</category>
    </item>
    <item>
      <title>Terraform Cloud Project Bootcamp with Andrew Brown - Creating an S3 bucket and bucket name using Terraform Providers</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Wed, 22 Nov 2023 07:05:06 +0000</pubDate>
      <link>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-creating-an-s3-bucket-and-bucket-name-using-terraform-providers-52ce</link>
      <guid>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-creating-an-s3-bucket-and-bucket-name-using-terraform-providers-52ce</guid>
      <description>&lt;p&gt;Hi guys , in this piece we will now start creating resources with Terraform. In this post, we will outline how to create a resource that creates a random value that becomes the S3 bucket name.&lt;/p&gt;

&lt;p&gt;This article is part of my Terraform journey with &lt;a href="https://www.youtube.com/watch?v=TXjzwiHtGqc&amp;amp;t=5852s"&gt;Terraform Bootcamp&lt;/a&gt; by Andrew Brown and Andrew Bayko, together with Chris Williams(I am also using his resources that he published &lt;a href="https://www.freecodecamp.org/news/terraform-certified-associate-003-study-notes/#preparation-materials"&gt;here&lt;/a&gt; and the beloved Shala Warner. I am also using some other resources from &lt;a href="https://www.youtube.com/@mastermnd"&gt;Aaron Brooks&lt;/a&gt; so that I can better explain new terms. And a special shout out to &lt;a href="https://medium.com/@gwenleigh/terraform-cloud-project-bootcamp-with-andrew-brown-complete-learning-journal-3640cebc74b5"&gt;Gwen Leigh&lt;/a&gt; for such a helpful outline that I used as a guide to create this series so that the documentation is easy to read!&lt;/p&gt;

&lt;p&gt;As I learn more about Terraform, feel free to follow &lt;a href="https://www.youtube.com/@ExamProChannel"&gt;Andrew Brown on Youtube&lt;/a&gt; and see their free (and paid) content . I Now let's jump in. &lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install and use the AWS Terraform provider&lt;/li&gt;
&lt;li&gt;
Create a bucket name using the random resource string

&lt;ul&gt;
&lt;li&gt;Creating the &lt;code&gt;main.tf&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;1. Required providers blocks&lt;/li&gt;
&lt;li&gt;2. Configure the credentials&lt;/li&gt;
&lt;li&gt;3. The resource &lt;code&gt;random_string&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;4. The resource &lt;code&gt;aws_s3_bucket&lt;/code&gt; &lt;/li&gt;
&lt;li&gt;5. Gives the output &lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Resources&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install and use the AWS Terraform provider
&lt;/h2&gt;

&lt;p&gt;To refresh our memory about providers, they are Direct interfaces to APIs for providers. Find more info about them from &lt;a href=""&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will create an AWS S3 bucket using Terraform. S3 is an object storage service from AWS that allows us to store items, referred to as objects in containers known as buckets in AWS terminology.&lt;/p&gt;

&lt;p&gt;The "random" provider allows the use of randomness within Terraform configurations. This is a logical provider, which means that it works entirely within Terraform's logic, and doesn't interact with any other services.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a bucket name using the random resource string
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Creating the &lt;code&gt;main.tf&lt;/code&gt; file
&lt;/h3&gt;

&lt;p&gt;Create a &lt;code&gt;main.tf&lt;/code&gt; file(a module) and add the code below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="k"&gt;terraform&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;required_providers&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;random&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/random"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"3.5.1"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="nx"&gt;aws&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;source&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"hashicorp/aws"&lt;/span&gt;
      &lt;span class="nx"&gt;version&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"5.19.0"&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"aws"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;# Configuration options&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;provider&lt;/span&gt; &lt;span class="s2"&gt;"random"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;# Configuration options&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;#https://registry.terraform.io/providers/hashicorp/random/latest/docs/resources/string&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"random_string"&lt;/span&gt; &lt;span class="s2"&gt;"bucket_name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;lower&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
  &lt;span class="nx"&gt;upper&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
  &lt;span class="nx"&gt;length&lt;/span&gt;           &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;32&lt;/span&gt;
  &lt;span class="nx"&gt;special&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;#Terraform AWS S3 &lt;/span&gt;
&lt;span class="c1"&gt;#https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket&lt;/span&gt;
&lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"aws_s3_bucket"&lt;/span&gt; &lt;span class="s2"&gt;"example"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;#bUCKET NAMING RULES&lt;/span&gt;
  &lt;span class="c1"&gt;#https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html&lt;/span&gt;
  &lt;span class="nx"&gt;bucket&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;random_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="k"&gt;output&lt;/span&gt; &lt;span class="s2"&gt;"random_bucket_name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;random_string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bucket_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1. Required providers blocks
&lt;/h3&gt;

&lt;p&gt;In the required providers block, we need to add to use the aws provider as we will be creating a resource S3 in AWS and we also have to add an &lt;em&gt;aws provider block random_string&lt;/em&gt; to create a random string for the bucket name. &lt;br&gt;
&lt;code&gt;&lt;br&gt;
terraform {&lt;br&gt;
  required_providers {&lt;br&gt;
    random = {&lt;br&gt;
      source = "hashicorp/random"&lt;br&gt;
      version = "3.5.1"&lt;br&gt;
    }&lt;br&gt;
    aws = {&lt;br&gt;
      source = "hashicorp/aws"&lt;br&gt;
      version = "5.26.0"&lt;br&gt;
    }&lt;br&gt;
  }&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Configure the credentials
&lt;/h3&gt;

&lt;p&gt;We will now configure the credentials for the AWS provider within the &lt;code&gt;main.tf&lt;/code&gt; file. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
provider "aws" {&lt;br&gt;
  AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE&lt;br&gt;
  AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY&lt;br&gt;
  AWS_DEFAULT_REGION=us-west-2&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
 Afterwards we can set the credentials as environment variables in the terminal.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Make sure to delete them before committing the file to VCS and let the provider look like the code block above.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. The resource &lt;code&gt;random_string&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;We are following the S3 bucket naming convention i.e making sure all letters are lowercase, have no special characters and have 32 characters.&lt;/p&gt;

&lt;p&gt;Generates a random permutation of alphanumeric characters and optionally special characters.&lt;/p&gt;

&lt;p&gt;This resource does use a cryptographic random number generator.&lt;br&gt;
&lt;code&gt;&lt;br&gt;
resource "random_string" "bucket_name" {&lt;br&gt;
  lower = true&lt;br&gt;
  upper = false&lt;br&gt;
  length           = 32&lt;br&gt;
  special          = false&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The resource &lt;code&gt;aws_s3_bucket&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;A resource that creates the S3 bucket with the bucket name as the output of the random-string resource above.&lt;br&gt;
&lt;code&gt;&lt;br&gt;
resource "aws_s3_bucket" "example" {&lt;br&gt;
   bucket = random_string.bucket_name.result&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  5. The output
&lt;/h3&gt;

&lt;p&gt;Gives the random string which is the S3 bucket name.&lt;br&gt;
&lt;code&gt;&lt;br&gt;
output "random_bucket_name" {&lt;br&gt;
  value = random_string.bucket_name.result&lt;br&gt;
}&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Now run &lt;code&gt;terraform init&lt;/code&gt; and get the out put below. The command will create 2 files: a &lt;code&gt;.terraform file&lt;/code&gt; and a &lt;code&gt;terraform.lock.hcl&lt;/code&gt;.
&lt;/li&gt;
&lt;/ul&gt;

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

Initializing provider plugins...
- Finding hashicorp/random versions matching "3.5.1"...
- Installing hashicorp/random v3.5.1...
- Installed hashicorp/random v3.5.1 (signed by HashiCorp)

Terraform has created a lock file .terraform.lock.hcl to record the provider
selections it made above. Include this file in your version control repository
so that Terraform can guarantee to make the same selections by default when
you run "terraform init" in the future.

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;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Whenever we make a change to the main.tf file, we need to make sure that we always run terraform init to add the new providers/resources to state file.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;terraform.lock.hcl&lt;/code&gt; is a package lock file that locks in the current version of terraform that we are using. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Then run &lt;code&gt;terraform plan&lt;/code&gt; creates a changeset, which shows the infrastructure that IaC plans to change. It should appear as below. If no issues show up, then run terraform apply.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;
&lt;span class="nx"&gt;Terraform&lt;/span&gt; &lt;span class="nx"&gt;used&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;selected&lt;/span&gt; &lt;span class="nx"&gt;providers&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;generate&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;following&lt;/span&gt; &lt;span class="nx"&gt;execution&lt;/span&gt; &lt;span class="nx"&gt;plan&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Resource&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;indicated&lt;/span&gt; &lt;span class="nx"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt;
&lt;span class="nx"&gt;following&lt;/span&gt; &lt;span class="nx"&gt;symbols&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
  &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;create&lt;/span&gt;

&lt;span class="nx"&gt;Terraform&lt;/span&gt; &lt;span class="nx"&gt;will&lt;/span&gt; &lt;span class="nx"&gt;perform&lt;/span&gt; &lt;span class="nx"&gt;the&lt;/span&gt; &lt;span class="nx"&gt;following&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;

  &lt;span class="c1"&gt;# random_string.bucket_name will be created&lt;/span&gt;
  &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="k"&gt;resource&lt;/span&gt; &lt;span class="s2"&gt;"random_string"&lt;/span&gt; &lt;span class="s2"&gt;"bucket_name"&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;          &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;known&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;length&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;16&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;lower&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;min_lower&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;min_numeric&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;min_special&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;min_upper&lt;/span&gt;   &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;number&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;numeric&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt;      &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;known&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;special&lt;/span&gt;     &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
      &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;upper&lt;/span&gt;       &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Plan&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;add&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;change&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;destroy&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;Changes&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;Outputs&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;
  &lt;span class="err"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;random_bucket_name&lt;/span&gt; &lt;span class="err"&gt;=&lt;/span&gt; &lt;span class="err"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;known&lt;/span&gt; &lt;span class="nx"&gt;after&lt;/span&gt; &lt;span class="nx"&gt;apply&lt;/span&gt;&lt;span class="err"&gt;)&lt;/span&gt;

&lt;span class="err"&gt;────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────&lt;/span&gt;

&lt;span class="nx"&gt;Note&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;didn&lt;/span&gt;&lt;span class="s1"&gt;'t use the -out option to save this plan, so Terraform can'&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt; &lt;span class="nx"&gt;guarantee&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;take&lt;/span&gt; &lt;span class="nx"&gt;exactly&lt;/span&gt; &lt;span class="nx"&gt;these&lt;/span&gt; &lt;span class="nx"&gt;actions&lt;/span&gt; &lt;span class="nx"&gt;if&lt;/span&gt;
&lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;run&lt;/span&gt; &lt;span class="s2"&gt;"terraform apply"&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Now run &lt;code&gt;terraform apply&lt;/code&gt; and enter &lt;code&gt;Yes&lt;/code&gt; when prompted. It generates a &lt;code&gt;terraform.tfstate&lt;/code&gt; file. (o use &lt;code&gt;terraform apply --auto-approve&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Now run &lt;code&gt;terraform destroy --auto-approve&lt;/code&gt; to remove resources.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket"&gt;S3 bucket providers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; &lt;a href="https://docs.aws.amazon.com/AmazonS3/latest/userguide/bucketnamingrules.html"&gt;S3 BUCKET NAMING RULES&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html"&gt;Configuring env vars in AWS&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>terraform</category>
      <category>aws</category>
      <category>s3</category>
      <category>providers</category>
    </item>
    <item>
      <title>Terraform Cloud Project Bootcamp with Andrew Brown - Configuring Terraform &amp; AWS CLI on Gitpod</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Mon, 13 Nov 2023 18:32:16 +0000</pubDate>
      <link>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-configuring-terraform-on-gitpod-5fc9</link>
      <guid>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-configuring-terraform-on-gitpod-5fc9</guid>
      <description>&lt;p&gt;Hi guys , in this piece we will be figuring out how to configure our Gitpod workspace for a project i.e installing Terraform in this case. The content will be broad enough to cove any other projects or languages that you might need.&lt;/p&gt;

&lt;p&gt;This article is part of my Terraform journey with &lt;a href="https://www.youtube.com/watch?v=TXjzwiHtGqc&amp;amp;t=5852s" rel="noopener noreferrer"&gt;Terraform Bootcamp&lt;/a&gt; by Andrew Brown and Andrew Bayko, together with Chris Williams(I am also using his resources that he published &lt;a href="https://www.freecodecamp.org/news/terraform-certified-associate-003-study-notes/#preparation-materials" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the beloved Shala Warner. I am also using some other resources from &lt;a href="https://www.youtube.com/@mastermnd" rel="noopener noreferrer"&gt;Aaron Brooks&lt;/a&gt; so that I can better explain new terms. And a special shout out to &lt;a href="https://medium.com/@gwenleigh/terraform-cloud-project-bootcamp-with-andrew-brown-complete-learning-journal-3640cebc74b5" rel="noopener noreferrer"&gt;Gwen Leigh&lt;/a&gt; for such a helpful outline that I used as a guide to create this series so that the documentation is easy to read!&lt;/p&gt;

&lt;p&gt;As I learn more about Terraform, feel free to follow &lt;a href="https://www.youtube.com/@ExamProChannel" rel="noopener noreferrer"&gt;Andrew Brown on Youtube&lt;/a&gt; and see their free (and paid) content . Now let's jump in. &lt;/p&gt;

&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Why create a gitpod.yml file?&lt;/li&gt;
&lt;li&gt;
Install the Terraform CLI

&lt;ul&gt;
&lt;li&gt;Considerations with the Terraform CLI changes&lt;/li&gt;
&lt;li&gt;Refactoring into Bash scripts&lt;/li&gt;
&lt;li&gt;Shebang Considerations &lt;/li&gt;
&lt;li&gt;Execution considerations &lt;/li&gt;
&lt;li&gt;Considerations for different Linux distributions.&lt;/li&gt;
&lt;li&gt;Linux Permissions Considerations&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Creating a bash script to install Terraform&lt;/li&gt;

&lt;li&gt;

Creating a bash script to install the AWS CLI

&lt;ul&gt;
&lt;li&gt;Add AWS credentials to our Gitpod environment&lt;/li&gt;
&lt;li&gt;Create the script that automatically installs AWS&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;

The structure of the &lt;code&gt;.gitpod.yml&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;Github Lifecycle (Init, Before, Command)&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Resources&lt;/li&gt;

&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why create a gitpod.yml file?
&lt;/h2&gt;

&lt;p&gt;A &lt;code&gt;gitpod.yml&lt;/code&gt; file is a configuration file that is written in YAML that installs dependencies needed for your environment.&lt;br&gt;
This makes it easier for continuing projects as you only need to configure the file once for a particular project and it automatically reloads as it is also stored in your preferred Version Control. &lt;br&gt;
There is a base &lt;code&gt;.gitpod.yml&lt;/code&gt; file that is automatically created whenever we launch a new workspace for anew project. Or you can run in the terminal the command below to generate the YAML file if it has not been automatically created.&lt;br&gt;
&lt;code&gt;gp init&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Install the Terraform CLI
&lt;/h2&gt;

&lt;p&gt;As we already learnt in the Git Basics, we will:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create a new issue and add a label and comment.
Since we had already copied the template from Andrew Brown's Github, we already have the &lt;code&gt;.gitpod.yml&lt;/code&gt; created however, we will go through the steps when creating a new project so as to properly configure your workspace.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Considerations with the Terraform CLI changes
&lt;/h3&gt;

&lt;p&gt;Using the Terraform CLI installation instructions to install a local version of Terraform. We need to refer to the latest install CLI&lt;sup&gt;1&lt;/sup&gt; instructions via Terraform documentation and change the scripting for install.&lt;/p&gt;
&lt;h3&gt;
  
  
  Refactoring into Bash scripts
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;While fixing the Terraform CLI gpg deprecation issues, we noticed that the Bash script steps had a considerable amount more of code and we decided to create a bash script to install the Terraform CLI.&lt;/li&gt;
&lt;li&gt;This will keep the Gitpod Task file &lt;code&gt;.gitpod.yml&lt;/code&gt; tidy.&lt;/li&gt;
&lt;li&gt;This allows us an easier to debug and executes manually Terraform CLI install .&lt;/li&gt;
&lt;li&gt;This will allow for better portability for other projects that need to install the Terraform CLI.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Shebang Considerations
&lt;/h3&gt;

&lt;p&gt;A shebang (#!) tells the bash script what program will interpret the script e.g &lt;code&gt;#!/bin/bash&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;ChatGPT recommend this format for bash: &lt;code&gt;#!/usr/bin/env bash&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;for portability for different OS distributions&lt;/li&gt;
&lt;li&gt;will allow us to search the user's PATH for the bash executable&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Execution considerations
&lt;/h3&gt;

&lt;p&gt;When executing the bash scripts we can use the &lt;code&gt;./&lt;/code&gt; shorthand notation to execute the bash script as opposed to the '$ source gdjshh.sh' notation. &lt;/p&gt;

&lt;p&gt;If we are using a script in Gitpod YAML, we need to point the script to a program to interpret it e.g &lt;code&gt;$ source gdjshh.sh&lt;/code&gt; notation. &lt;/p&gt;
&lt;h3&gt;
  
  
  Considerations for different Linux distributions.
&lt;/h3&gt;

&lt;p&gt;This project is built on Ubuntu.&lt;br&gt;
Please check your distribution to check then change accordingly to distribution needs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$cat /etc/os-release

&amp;gt;output
PRETTY_NAME="Ubuntu 22.04.3 LTS"
NAME="Ubuntu"
VERSION_ID="22.04"
VERSION="22.04.3 LTS (Jammy Jellyfish)"
VERSION_CODENAME=jammy
ID=ubuntu
ID_LIKE=debian
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
UBUNTU_CODENAME=jammy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Linux Permissions Considerations
&lt;/h3&gt;

&lt;p&gt;Linux permissions works as follows:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In order to make a bash script executable, we need to change the Linux permissions for the file to be executable
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;chmod &lt;/span&gt;u+x ./bin/install_terraform_cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;
&lt;span class="nb"&gt;chmod &lt;/span&gt;744 ./bin/install_terraform_cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a bash script to install Terraform
&lt;/h2&gt;

&lt;p&gt;Creating a bash script to automate the installation of Terraform in our Gitpod Linux environment.&lt;/p&gt;

&lt;p&gt;But before we create the script we need to set the &lt;code&gt;PROJECT_ROOT&lt;/code&gt; working directory. When we start our Gitpod workspace an example can be &lt;code&gt;/workspace/terraform-beginner-bootcamp=2023&lt;/code&gt;&lt;br&gt;
which we can now set in the terminal as an environment variable making it easy for us to access in the bash scripts. &lt;br&gt;
We can set it using &lt;br&gt;
&lt;code&gt;&lt;br&gt;
echo $THEIA_WORKSPACE_ROOT&lt;br&gt;
export PROJECT_ROOT='/workspace/terraform-beginner-bootcamp=2023'&lt;br&gt;
echo $PROJECT_ROOT&lt;br&gt;
&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/usr/bin/env bash&lt;/span&gt;

&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;workspace&lt;/span&gt;

&lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;apt-get&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt; &lt;span class="err"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;apt-get&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="nx"&gt;-y&lt;/span&gt; &lt;span class="nx"&gt;gnupg&lt;/span&gt; &lt;span class="nx"&gt;software-properties-common&lt;/span&gt; &lt;span class="nx"&gt;curl&lt;/span&gt; 

&lt;span class="nx"&gt;wget&lt;/span&gt; &lt;span class="nx"&gt;-O-&lt;/span&gt; &lt;span class="nx"&gt;https&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt;&lt;span class="c1"&gt;//apt.releases.hashicorp.com/gpg | \&lt;/span&gt;
&lt;span class="nx"&gt;gpg&lt;/span&gt; &lt;span class="nx"&gt;--dearmor&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; 
&lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;tee&lt;/span&gt; &lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;usr&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;share&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;keyrings&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;hashicorp-archive-keyring&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gpg&lt;/span&gt;

&lt;span class="nx"&gt;gpg&lt;/span&gt; &lt;span class="nx"&gt;--no-default-keyring&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
&lt;span class="nx"&gt;--keyring&lt;/span&gt; &lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;usr&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;share&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;keyrings&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;hashicorp-archive-keyring&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;gpg&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
&lt;span class="nx"&gt;--fingerprint&lt;/span&gt;

&lt;span class="nx"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] &lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="s2"&gt;
https://apt.releases.hashicorp.com &lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="s2"&gt;(lsb_release -cs) main"&lt;/span&gt; &lt;span class="err"&gt;|&lt;/span&gt; &lt;span class="err"&gt;\&lt;/span&gt;
&lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;tee&lt;/span&gt; &lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;etc&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;apt&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;sources&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;d&lt;/span&gt;&lt;span class="err"&gt;/&lt;/span&gt;&lt;span class="nx"&gt;hashicorp&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;list&lt;/span&gt;

&lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;apt&lt;/span&gt; &lt;span class="nx"&gt;update&lt;/span&gt;

&lt;span class="nx"&gt;sudo&lt;/span&gt; &lt;span class="nx"&gt;apt-get&lt;/span&gt; &lt;span class="nx"&gt;install&lt;/span&gt; &lt;span class="k"&gt;terraform&lt;/span&gt;
&lt;span class="nx"&gt;cd&lt;/span&gt; &lt;span class="nx"&gt;$PROJECT_ROOT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This will avoid us downloading junk files into our workspace&lt;br&gt;
&lt;code&gt;&lt;br&gt;
cd /workspace&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;This line of code will update the system, ensure that &lt;code&gt;gnupg&lt;/code&gt;, &lt;code&gt;curl&lt;/code&gt; has been installed;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install -y gnupg software-properties-common curl&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;We now install the Hashicorp GPG key&lt;br&gt;
&lt;code&gt;&lt;br&gt;
wget -O- https://apt.releases.hashicorp.com/gpg | \&lt;br&gt;
gpg --dearmor | \&lt;br&gt;
sudo tee /usr/share/keyrings/hashicorp-archive-keyring.gpg&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Verify the Hashicorp security key&lt;br&gt;
&lt;code&gt;&lt;br&gt;
gpg --no-default-keyring \&lt;br&gt;
--keyring /usr/share/keyrings/hashicorp-archive-keyring.gpg \&lt;br&gt;
--fingerprint&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Add the official HashiCorp repository to your system. The lsb_release -cs command finds the distribution release codename for your current system, such as buster, groovy, or sid.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;&lt;br&gt;
echo "deb [signed-by=/usr/share/keyrings/hashicorp-archive-keyring.gpg] \&lt;br&gt;
https://apt.releases.hashicorp.com $(lsb_release -cs) main" | \&lt;br&gt;
sudo tee /etc/apt/sources.list.d/hashicorp.list&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Download the package information from HashiCorp and Install Terraform from the new repository.&lt;br&gt;
&lt;code&gt;&lt;br&gt;
sudo apt update&lt;br&gt;
sudo apt-get install terraform -y&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will now make the script executable by running the instructions above and then run the file using:&lt;br&gt;
&lt;code&gt;&lt;br&gt;
source ./bin/install-terraform_cli&lt;br&gt;
or&lt;br&gt;
./bin/install-terraform_cli&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;To go back to the working directory&lt;br&gt;
&lt;code&gt;&lt;br&gt;
cd $PROJECT_ROOT&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We will reference this file in &lt;code&gt;.gitpod.yml&lt;/code&gt; to install the dependencies and store away the binary files whenever we (re)start a new workspace.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  Creating a bash script to install the AWS CLI
&lt;/h2&gt;
&lt;h3&gt;
  
  
  1. Add AWS credentials to our Gitpod environment
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Add our AWS credentials that we want to set for the workspace&lt;br&gt;
&lt;code&gt;&lt;br&gt;
export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE&lt;br&gt;
export AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY&lt;br&gt;
export AWS_DEFAULT_REGION=us-west-2&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirm that they are set&lt;br&gt;
&lt;code&gt;env |grep AWS&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Set them to Gitpod by adding&lt;br&gt;
&lt;code&gt;&lt;br&gt;
gp env AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE&lt;br&gt;
gp env AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY&lt;br&gt;
gp env AWS_DEFAULT_REGION=us-west-2&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We avoid using the &lt;code&gt;aws configure&lt;/code&gt; to set the credentials for our workspace, as we do not want to use/create a credentials files that might be easily leaked when we forget to add it to &lt;code&gt;.gitignore&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  2. Create the script that automatically installs AWS
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env bash

cd /workspace

rm -f '/workspace/awscliv2.zip'
rm -rf '/workspace/aws'

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install

aws sts get-caller-identity

cd $PROJECT_ROOT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;This will avoid us downloading junk files into our workspace&lt;br&gt;
&lt;code&gt;cd /workspace&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We remove previous aws cli installations in the workspace&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;rm -f '/workspace/awscliv2.zip'
rm -rf '/workspace/aws'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Installs the goes to the https address and downloads the file, unzips it then installs it.&lt;br&gt;
&lt;code&gt;&lt;br&gt;
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"&lt;br&gt;
unzip awscliv2.zip&lt;br&gt;
sudo ./aws/install&lt;br&gt;
&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Confirms that we are using the 'correct' AWS account/credentials in &lt;code&gt;json&lt;/code&gt;&lt;br&gt;
&lt;code&gt;aws sts get-caller-identity&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Switch back to the working directory&lt;br&gt;
&lt;code&gt;cd $PROJECT_ROOT&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;We will reference this file in &lt;code&gt;.gitpod.yml&lt;/code&gt; to install the dependencies and store away the binary files whenever we (re)start a new workspace.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;
  
  
  The structure of the &lt;code&gt;.gitpod.yml&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Gitpod has tasks that allow it to launch terminals&lt;br&gt;
Take a look at the sample &lt;code&gt;gitpod.yml&lt;/code&gt; file below,&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tasks:
  - name: terraform
    before: |
      source ./bin/install_terraform_cli

  - name: aws-cli
    env:
      AWS_CLI_AUTO_PROMPT: on-partial
    before: |
      source ./bin/install_aws_cli

vscode:
  extensions:
    - amazonwebservices.aws-toolkit-vscode
    - hashicorp.terraform
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For new workspaces, we need to install the dependencies therefore we need the before first.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxl8kbb3twp1artjsyxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftxl8kbb3twp1artjsyxt.png" alt="Gitpod before, init, command"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;We will install the terraform CLI from using the bash script that we created above. (we use source to run the Terraform CLI  script as it does not care if the file is to be made executable)
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tasks:
  - name: terraform
    before: |
      source ./bin/install_terraform-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Github Lifecycle (Init, Before, Command)
&lt;/h3&gt;

&lt;p&gt;We need to be mindful when using &lt;code&gt;init&lt;/code&gt; as it will not run if we restart an existing workspace.&lt;/p&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://www.ionos.com/digitalguide/server/know-how/how-to-check-your-linux-version/" rel="noopener noreferrer"&gt;How to check your OS version in the Linux terminal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gitpod.io/docs/configure/workspaces/tasks" rel="noopener noreferrer"&gt;How to configure a Gitpod workspace&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://developer.hashicorp.com/terraform/tutorials/aws-get-started/install-cli" rel="noopener noreferrer"&gt;Install Terraform CLI&lt;/a&gt;&lt;sup&gt;1&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://linuxhint.com/switch-back-to-master-with-git/" rel="noopener noreferrer"&gt;Linux Permissions&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html" rel="noopener noreferrer"&gt;Installing the AWS CLI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-envvars.html" rel="noopener noreferrer"&gt;Setting AWS Environment Variables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.gitpod.io/docs/configure/workspaces/tasks" rel="noopener noreferrer"&gt;Gitpod Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>terraform</category>
      <category>hashicorp</category>
      <category>linux</category>
      <category>github</category>
    </item>
    <item>
      <title>Terraform Cloud Project Bootcamp with Andrew Brown - Week 0, 1 &amp; 2 Journal</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Fri, 10 Nov 2023 16:44:43 +0000</pubDate>
      <link>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-week-0-1-2-journal-40gn</link>
      <guid>https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-week-0-1-2-journal-40gn</guid>
      <description>&lt;p&gt;Hi guys. Welcome back. I recently decided to learn Terraform as I upskill for my first tech role. This article is part of my Terraform journey with &lt;a href="https://www.youtube.com/watch?v=TXjzwiHtGqc&amp;amp;t=5852s"&gt;Terraform Bootcamp&lt;/a&gt; by Andrew Brown and Andrew Bayko, together with Chris Williams(I am also using his resources that he published &lt;a href="https://www.freecodecamp.org/news/terraform-certified-associate-003-study-notes/#preparation-materials"&gt;here&lt;/a&gt; and the beloved Shala Warner. I am also using some other resources from &lt;a href="https://www.youtube.com/@mastermnd"&gt;Aaron Brooks&lt;/a&gt; so that I can better explain new terms. And a special shout out to &lt;a href="https://medium.com/@gwenleigh/terraform-cloud-project-bootcamp-with-andrew-brown-complete-learning-journal-3640cebc74b5"&gt;Gwen Leigh&lt;/a&gt; for such a helpful outline that I used as a guide to create this series so that the documentation is easy to read!&lt;/p&gt;

&lt;p&gt;As I learn more about Terraform, feel free to follow &lt;a href="https://www.youtube.com/@ExamProChannel"&gt;Andrew Brown on Youtube&lt;/a&gt; and see their free (and paid) content . I Now let's jump in. Follow the links below to be redirected to the respective week;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 0 - Prep week&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=TXjzwiHtGqc&amp;amp;t=5852s"&gt;Week 0 Live Stream&lt;/a&gt;&lt;br&gt;
0.0.0 &lt;a href="https://dev.to/msaghu/terraform-bootcamp-week-0-with-andrew-brown-basic-definitions-23l"&gt;Basic Definitions&lt;/a&gt;&lt;br&gt;
0.1.0 &lt;a href="https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-configuring-terraform-on-gitpod-5fc9"&gt;Configuring Terraform on Gitpod&lt;/a&gt;&lt;br&gt;
0.2.0 &lt;a href=""&gt;Git Basics&lt;/a&gt;&lt;br&gt;
0.3.0 &lt;a href="https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-creating-an-s3-bucket-and-bucket-name-using-terraform-providers-52ce"&gt;Creating an S3 bucket and bucket name using Terraform Providers&lt;/a&gt;&lt;br&gt;
0.4.0 &lt;a href="https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-storing-the-state-file-in-terraform-cloud-41cb"&gt;Storing the state file in Terraform Cloud&lt;/a&gt;&lt;br&gt;
0.4.0 &lt;a href="https://dev.to/msaghu/terraform-cloud-project-bootcamp-with-andrew-brown-creating-a-command-alias-4oa2"&gt;Creating a command alias&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 1&lt;/strong&gt;&lt;br&gt;
&lt;a href="https://www.youtube.com/watch?v=qIe3srQOQ8Q"&gt;Week 1 Live Stream&lt;/a&gt;&lt;br&gt;
1.0.0 Journal TOC and Major Version&lt;br&gt;
 Git basics&lt;br&gt;
1.1.0 Restructure Root Module&lt;br&gt;
1.3.0 Create AWS Terrahouse Module&lt;br&gt;
1.4.0 Static Website Hosting&lt;br&gt;
1.5.0 Content Delivery Network&lt;br&gt;
1.6.0 Terraform Data Content Version&lt;br&gt;
1.7.0 Invalidate Cache Local Exec&lt;br&gt;
1.8.0 Assets Upload For Each&lt;br&gt;
1.8.2 Working Through Git Graph Issues&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 2&lt;/strong&gt;&lt;br&gt;
Week 2 Live Stream&lt;br&gt;
2.0.0 Setting up TerraTown Mock Web Server&lt;br&gt;
2.1.0 Setup Skeleton for Custom Terraform Provider&lt;br&gt;
2.2.0 Provider Block for Custom Terraform Provider&lt;br&gt;
2.3.0 Resource Skeleton&lt;br&gt;
2.4.0 CRUD Resource&lt;br&gt;
2.5.0 Deploying to TerraTown&lt;br&gt;
2.6.0 Terraform Cloud and Multi Homes&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Week 3&lt;/strong&gt;&lt;br&gt;
Terraform&lt;br&gt;
AWS&lt;/p&gt;

</description>
      <category>terraform</category>
      <category>hashicorp</category>
      <category>iac</category>
      <category>exampro</category>
    </item>
    <item>
      <title>Terraform Bootcamp Week 0 with Andrew Brown: Basic Definitions</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Fri, 10 Nov 2023 16:43:45 +0000</pubDate>
      <link>https://dev.to/msaghu/terraform-bootcamp-week-0-with-andrew-brown-basic-definitions-23l</link>
      <guid>https://dev.to/msaghu/terraform-bootcamp-week-0-with-andrew-brown-basic-definitions-23l</guid>
      <description>&lt;p&gt;Hi guys. Welcome. I recently decided to learn Terraform as I upskill for my first tech role. This article is part of my Terraform journey with &lt;a href="https://www.youtube.com/watch?v=TXjzwiHtGqc&amp;amp;t=5852s" rel="noopener noreferrer"&gt;Terraform Bootcamp&lt;/a&gt; by Andrew Brown and Andrew Bayko, together with Chris Williams(I am also using his resources that he published &lt;a href="https://www.freecodecamp.org/news/terraform-certified-associate-003-study-notes/#preparation-materials" rel="noopener noreferrer"&gt;here&lt;/a&gt; and the beloved Shala Warner. I am also using some other resources from &lt;a href="https://www.youtube.com/@mastermnd" rel="noopener noreferrer"&gt;Aaron Brooks&lt;/a&gt; so that I can better explain new terms. And a special shout out to &lt;a href="https://medium.com/@gwenleigh/terraform-cloud-project-bootcamp-with-andrew-brown-complete-learning-journal-3640cebc74b5" rel="noopener noreferrer"&gt;Gwen Leigh&lt;/a&gt; for such a helpful outline that I used as a guide to create this series so that the documentation is easy to read!&lt;/p&gt;

&lt;p&gt;As I learn more about Terraform, feel free to follow &lt;a href="https://www.youtube.com/@ExamProChannel" rel="noopener noreferrer"&gt;Andrew Brown on Youtube&lt;/a&gt; and see their free (and paid) content . I Now let's jump in;&lt;/p&gt;

&lt;h1&gt;
  
  
  Table of Contents
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;
Basic Definitions

&lt;ul&gt;
&lt;li&gt;What is Terraform?&lt;/li&gt;
&lt;li&gt;What is IaC?&lt;/li&gt;
&lt;li&gt;Types of infrastructure&lt;/li&gt;
&lt;li&gt;Why use IAC?&lt;/li&gt;
&lt;li&gt;
What is Configuration Management?

&lt;ul&gt;
&lt;li&gt;Configuration Management vs Infrastructure Provisioning?&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;What is Hashicorp Vault?&lt;/li&gt;

&lt;li&gt;

Terraform Infrastructure Lifecycle

&lt;ul&gt;
&lt;li&gt;Idempotency.&lt;/li&gt;
&lt;li&gt;
Configuration Drift:

&lt;ul&gt;
&lt;li&gt;Mutable vs Immutable infrastructure&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;li&gt;

Terraform workflow

&lt;ul&gt;
&lt;li&gt;1. Code &lt;/li&gt;
&lt;li&gt;2. Terraform init&lt;/li&gt;
&lt;li&gt;3. Terraform plan&lt;/li&gt;
&lt;li&gt;4. Terraform validate &lt;/li&gt;
&lt;li&gt;5. Terraform apply&lt;/li&gt;
&lt;li&gt;6. Terraform destroy - unmakes the things! 😱&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Resources&lt;/li&gt;

&lt;/ul&gt;

&lt;/li&gt;

&lt;/ul&gt;

&lt;h1&gt;
  
  
  Basic Definitions
&lt;/h1&gt;

&lt;h2&gt;
  
  
  What is Terraform?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Terraform is an infrastructure as code tool that lets you build, change, and version cloud and on-prem resources safely and efficiently.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HashiCorp Terraform is an infrastructure as code tool that lets you define both cloud and on-prem resources in human-readable configuration files that you can version, reuse, and share. You can then use a consistent workflow to provision and manage all of your infrastructure throughout its lifecycle. &lt;sup&gt;1&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is IaC?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure as Code (IaC) is the blueprint of our infrastructure that allows managing and provisioning of infrastructure through code instead of through manual processes. This is because provisioning infrastructure at scale is prone to error. It allows us to &lt;strong&gt;provision the SAME INFRASTRUCTURE everytime.&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With IaC, configuration files are created that contain your infrastructure specifications, which makes it easier to edit and distribute configurations. It also ensures that you provision the same environment every time. By codifying and documenting your configuration specifications, IaC aids configuration management and helps you to avoid undocumented, ad-hoc configuration changes.&lt;/p&gt;

&lt;p&gt;Version control is an important part of IaC, and your configuration files should be under source control just like any other software source code file. Deploying your infrastructure as code also means that you can divide your infrastructure into modular components that can then be combined in different ways through automation. &lt;sup&gt;2&lt;/sup&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Types of infrastructure
&lt;/h2&gt;

&lt;p&gt;We have 2 types of infrastructure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Declarative &lt;/li&gt;
&lt;li&gt;Imperative&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1. Declarative&lt;/strong&gt; &lt;br&gt;
What you see is what you get. It's explicit with 0 chance of misconfiguration:&lt;/p&gt;

&lt;p&gt;Azure only -&amp;gt; ARM Templates, Azure Blueprints&lt;br&gt;
AWS only -&amp;gt; CloudFormation&lt;br&gt;
GCP only -&amp;gt; Cloud Deployment Manager&lt;br&gt;
All of the above (&amp;amp; many others) -&amp;gt; Terraform&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Imperative&lt;/strong&gt;&lt;br&gt;
Uses existing programming languages like Python, JS or Ruby:&lt;/p&gt;

&lt;p&gt;AWS only -&amp;gt; AWS CDK&lt;br&gt;
AWS, Azure, GCP, K8s -&amp;gt; Pulumi&lt;br&gt;
Terraform supports For loops, dynamic blocks, complex data structures – so it's declarative with some imperative benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why use IAC?
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Creates a consistent and reusable ways to deploy and manage infrastructure and configuration.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Help prevent configuration drift.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Provides free documentation i.e code and logs of current state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Share &amp;amp; reuse your configurations more easily&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Manage infra on multiple cloud platforms&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Track resource changes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use version control (Git, GitHub, etc..) to collaborate with team members&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What is Configuration Management?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;The primary goal of configuration management tools is to configure the server. Meaning, if you want to automate the installation and configuration of an application(e.g., Nginx) in a server, we use a &lt;strong&gt;tool like Ansible and Chef&lt;/strong&gt;. It does all the configurations in an &lt;strong&gt;idempotent manner&lt;/strong&gt;. It can be used to maintain computer systems, servers, applications, network devices, and other IT components in a desired state. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;They allow administrators to set up an IT system, such as a server or workstation, then build and maintain other servers and workstations with the same settings. IT teams use configuration assessments and drift analyses to continuously identify systems that have strayed from the desired system state and need to be updated, reconfigured, or patched. It’s a way to help ensure that a system performs as expected, even after many changes are made over time. &lt;sup&gt;3&lt;/sup&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Also, these tools help in managing the &lt;strong&gt;configuration drift&lt;/strong&gt;. &lt;em&gt;It ensures all the servers are running in the same configuration mentioned in the ansible-playbook or a chef cookbook&lt;/em&gt; .In the case of an agent-based chef/puppet, if someone changes the server config manually, the chef agent brings it back to the desired state, as mentioned in the cookbook.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;All the configuration management tools keep an inventory of the server’s IP address and SSH credentials to connect to the servers. However, in cloud environments where servers are dynamically provisioned, it uses an API-based dynamic inventory to get the server details.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Management vs Infrastructure Provisioning?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Infrastructure provisioning tool Terraform is responsible for providing the network and servers&lt;/li&gt;
&lt;li&gt;Configuration management tool Ansible configures applications inside servers provisioned by Terraform.&lt;sup&gt;4&lt;/sup&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vzo6yslow2zwgmqh0yf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5vzo6yslow2zwgmqh0yf.png" alt="Configuration Management vs Infrastructure Management"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Hashicorp Vault?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;HashiCorp Vault is an identity-based secrets and encryption management system. A secret is anything that you want to tightly control access to, such as API encryption keys, passwords, and certificates. Vault provides encryption services that are gated by authentication and authorization methods. Using Vault’s UI, CLI, or HTTP API, access to secrets and other sensitive data can be securely stored and managed, tightly controlled (restricted), and auditable.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Terraform Infrastructure Lifecycle
&lt;/h2&gt;

&lt;p&gt;The Infrastructure Lifecycle is having clearly defined work phases for planning, designing, building, testing, maintaining and retiring your infrastructure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Idempotency.
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;a property of some operations such that no matter how many times you execute them, you achieve the same result. Terraform is idempotent because, no matter how many times you run the same configuration file, you will end up with the same expected state.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configuration Drift:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;When your actual infrastructure deviates away from the desired infrastructure. Unexpected configuration change away from what is stated in the config file. Can be due to manual adjustment (console access in prod = BAD  😂), evil h@xx0rs, etc. that is done outside of the scripting tools i.e Hashicorp Terraform, AWS CloudFormation, Ansible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;.. How do we fix it?&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;By using configuration monitoring tools/compliance tools like AWS Config, or built-in support e.g. AWS CF Drift Detect&lt;/li&gt;
&lt;li&gt;They monitor your infrastructure and notify based on default and custom rules.
&amp;gt;PS: Most of these tools are not free&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;TF refresh &amp;amp; plan commands&lt;/li&gt;
&lt;li&gt;Manually correct (try not to do this)&lt;/li&gt;
&lt;li&gt;Reprovision (comes with it's own risks)&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;use immutable infrastructure&lt;/li&gt;
&lt;li&gt;always create &amp;amp; destroy, never reuse&lt;/li&gt;
&lt;li&gt;never share credentials&lt;/li&gt;
&lt;li&gt;run scheduled plans with tools like AWS Config  and use Terraform Import Blocks to import resources outside your Terraform State&lt;/li&gt;
&lt;li&gt;use drift detection tools like &lt;em&gt;driftctl&lt;/em&gt; and &lt;em&gt;Cloudquery&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;use GitOps to version control IaC i.e
&lt;em&gt;Create tf file
commit
Pull Request
peer review
commit to main
GitHub action triggers build&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Mutable vs Immutable infrastructure
&lt;/h4&gt;

&lt;p&gt;Think of mutable infrastructure as (1) building a base image (2) Deploying that base image then (3) configuring the software after deploy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Terraform workflow
&lt;/h2&gt;

&lt;p&gt;Most of the main Terraform files end with the .tf extension.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Code
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;create or edit your terraform config file&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Terraform init
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This command initializes a working directory containing Terraform configuration files, pull providers and modules.&lt;/li&gt;
&lt;li&gt;This is the first command that should be run after writing a new Terraform configuration or cloning an existing one from version control. It is safe to run this command multiple times.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight terraform"&gt;&lt;code&gt;&lt;span class="nx"&gt;Terraform&lt;/span&gt; &lt;span class="nx"&gt;has&lt;/span&gt; &lt;span class="nx"&gt;been&lt;/span&gt; &lt;span class="nx"&gt;successfully&lt;/span&gt; &lt;span class="nx"&gt;initialized&lt;/span&gt;&lt;span class="err"&gt;!&lt;/span&gt;

&lt;span class="nx"&gt;You&lt;/span&gt; &lt;span class="nx"&gt;may&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="nx"&gt;begin&lt;/span&gt; &lt;span class="nx"&gt;working&lt;/span&gt; &lt;span class="nx"&gt;with&lt;/span&gt; &lt;span class="nx"&gt;Terraform&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;Try&lt;/span&gt; &lt;span class="nx"&gt;running&lt;/span&gt; &lt;span class="s2"&gt;"terraform plan"&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;see&lt;/span&gt;  
&lt;span class="nx"&gt;any&lt;/span&gt; &lt;span class="nx"&gt;changes&lt;/span&gt; &lt;span class="nx"&gt;that&lt;/span&gt; &lt;span class="nx"&gt;are&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="nx"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;infrastructure&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;All&lt;/span&gt; &lt;span class="nx"&gt;Terraform&lt;/span&gt; &lt;span class="nx"&gt;commands&lt;/span&gt;  
&lt;span class="nx"&gt;should&lt;/span&gt; &lt;span class="nx"&gt;now&lt;/span&gt; &lt;span class="nx"&gt;work&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;

&lt;span class="nx"&gt;If&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;ever&lt;/span&gt; &lt;span class="nx"&gt;set&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;change&lt;/span&gt; &lt;span class="nx"&gt;modules&lt;/span&gt; &lt;span class="nx"&gt;or&lt;/span&gt; &lt;span class="nx"&gt;backend&lt;/span&gt; &lt;span class="nx"&gt;configuration&lt;/span&gt; &lt;span class="nx"&gt;for&lt;/span&gt; &lt;span class="nx"&gt;Terraform&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;      
&lt;span class="nx"&gt;rerun&lt;/span&gt; &lt;span class="nx"&gt;this&lt;/span&gt; &lt;span class="nx"&gt;command&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;reinitialize&lt;/span&gt; &lt;span class="nx"&gt;your&lt;/span&gt; &lt;span class="nx"&gt;working&lt;/span&gt; &lt;span class="nx"&gt;directory&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt; &lt;span class="nx"&gt;If&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;forget&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;other&lt;/span&gt;
&lt;span class="nx"&gt;commands&lt;/span&gt; &lt;span class="nx"&gt;will&lt;/span&gt; &lt;span class="nx"&gt;detect&lt;/span&gt; &lt;span class="nx"&gt;it&lt;/span&gt; &lt;span class="nx"&gt;and&lt;/span&gt; &lt;span class="nx"&gt;remind&lt;/span&gt; &lt;span class="nx"&gt;you&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt; &lt;span class="nx"&gt;do&lt;/span&gt; &lt;span class="nx"&gt;so&lt;/span&gt; &lt;span class="nx"&gt;if&lt;/span&gt; &lt;span class="nx"&gt;necessary&lt;/span&gt;&lt;span class="err"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Terraform plan
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Moves items from current state to the configuration state described in the &lt;code&gt;main.tf&lt;/code&gt; file.&lt;/li&gt;
&lt;li&gt;It creates an execution plan, which lets you preview the changes that Terraform plans to make to your infrastructure. By default, when Terraform creates a plan it:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;Reads the current state of any already-existing remote objects to make sure that the Terraform state is up-to-date.&lt;/li&gt;
&lt;li&gt;Compares the current configuration to the prior state and noting any differences.&lt;/li&gt;
&lt;li&gt;Proposes a set of change actions that should, if applied, make the remote objects match the configuration.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  4. Terraform validate
&lt;/h3&gt;

&lt;p&gt;Ensure types, values, and required attributes are valid and present&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Terraform apply
&lt;/h3&gt;

&lt;p&gt;After making our plan we can now execute it.&lt;/p&gt;

&lt;h3&gt;
  
  
  6. Terraform destroy - unmakes the things! 😱
&lt;/h3&gt;

&lt;h2&gt;
  
  
  Resources
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;a href="https://developer.hashicorp.com/terraform/intro" rel="noopener noreferrer"&gt;What is Terraform&lt;/a&gt; &lt;sup&gt;1&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.redhat.com/en/topics/automation/what-is-infrastructure-as-code-iac" rel="noopener noreferrer"&gt;What is IaC?&lt;/a&gt; &lt;sup&gt;2&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.redhat.com/en/topics/automation/what-is-configuration-management" rel="noopener noreferrer"&gt;What is Configuration Management?&lt;/a&gt;&lt;sup&gt;3&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://devopscube.com/infrastructure-as-code-configuration-management/" rel="noopener noreferrer"&gt;Configuration Management vs Infrastructure Management&lt;/a&gt;&lt;sup&gt;4&lt;/sup&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.thoughtworks.com/insights/blog/why-configuration-management-and-provisioning-are-different" rel="noopener noreferrer"&gt;A great read too&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/vault/docs/what-is-vault" rel="noopener noreferrer"&gt;What is Hashicorp Vault?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.hashicorp.com/terraform/cli/commands/init" rel="noopener noreferrer"&gt;What is Terraform init&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.theserverside.com/blog/Coffee-Talk-Java-News-Stories-and-Opinions/git-branch-change-example-tutorial-github-gitlab-bitbucket" rel="noopener noreferrer"&gt;Creating Git branches&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.freecodecamp.org/news/terraform-certified-associate-003-study-notes/#preparation-materials" rel="noopener noreferrer"&gt;Terraform Certified Associate (003) by Chris Williams&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://morethancertified.com/cloud-infrastructure-drift/" rel="noopener noreferrer"&gt;What is Configuration Drift?&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>terraform</category>
      <category>aws</category>
      <category>iac</category>
      <category>ansible</category>
    </item>
    <item>
      <title>Free AWS BootCamp WEEK 4 PART 2: PostgreSQL Databases in AWS</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Wed, 15 Mar 2023 09:08:13 +0000</pubDate>
      <link>https://dev.to/msaghu/free-aws-bootcamp-week-4-part-2-postgresql-databases-59ig</link>
      <guid>https://dev.to/msaghu/free-aws-bootcamp-week-4-part-2-postgresql-databases-59ig</guid>
      <description>&lt;p&gt;Hi guys, we will now cover how to install PostgreSQL on our local machine for use to run SQL commands. But first, we will have go through some basic definitions:&lt;/p&gt;

&lt;h3&gt;
  
  
  What is AWS Relational Database Service(RDS)?
&lt;/h3&gt;

&lt;h3&gt;
  
  
  What are the advantages of AWS Relational Database Service(RDS)?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Allows you to create and scale relational databases in the cloud.&lt;/li&gt;
&lt;li&gt;RDS runs on virtual machines (can’t log in to the OS or SSH in).&lt;/li&gt;
&lt;li&gt;AWS handles admin tasks for you like hardware provisioning, patching &amp;amp; backups.&lt;/li&gt;
&lt;li&gt;RDS is not serverless — (one exception Aurora Serverless)&lt;/li&gt;
&lt;li&gt;Allows you to control network access to your database
Offers encryption at rest — done with KMS (data stored, automated backups, read replicas and snapshots all encrypted)&lt;/li&gt;
&lt;li&gt;AWS Aurora is the managed version of SQL databases that is fully managed by AWS.&lt;/li&gt;
&lt;li&gt;When create a database we need to be sure that it has been created in the same region where our account is.&lt;/li&gt;
&lt;li&gt;You can create and modify a DB instance by using the AWS Command Line Interface (AWS CLI), the Amazon RDS API, or the AWS Management Console.&lt;/li&gt;
&lt;li&gt;Amazon RDS is responsible for hosting the software components and infrastructure of DB instances and DB cluster. We are responsible for query tuning, which is the process of adjusting SQL queries to improve performance.&lt;/li&gt;
&lt;li&gt;We can run our DB instance in several Availability Zones, an option called a Multi-AZ deployment. When we choose this option, Amazon automatically provisions and maintains one or more secondary standby DB instances in a different Availability Zone. Your primary DB instance is replicated across Availability Zones to each secondary DB instance.&lt;/li&gt;
&lt;li&gt;We use security groups to control the access to a DB instance. It does so by allowing access to IP address ranges or Amazon EC2 instances that you specify.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Supported RDS Database engines
&lt;/h4&gt;

&lt;p&gt;A DB engine is the specific relational database software that runs on your DB instance. Amazon RDS currently supports the following engines:&lt;br&gt;
-MariaDB&lt;/p&gt;

&lt;p&gt;-Microsoft SQL Server&lt;/p&gt;

&lt;p&gt;-MySQL&lt;/p&gt;

&lt;p&gt;-Oracle&lt;/p&gt;

&lt;p&gt;-PostgreSQL&lt;/p&gt;
&lt;h3&gt;
  
  
  RDS Main Features
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Multi AZ Recovery
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Have a primary and secondary database, if you lose the primary database, AWS would detect and automatically update the DNS to point at the secondary database.&lt;/li&gt;
&lt;li&gt;Used for DISASTER RECOVERY, it doesn’t improve performance.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Read Replicas
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Every time you write to the main database, it is replicated in the secondary database.&lt;/li&gt;
&lt;li&gt;If you lose the primary database there is no automatic failover, you need to manually update the URL to it yourself&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;IMPROVES PERFORMANCE&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Used for scaling&lt;/li&gt;
&lt;li&gt;Automatic backups must be turned on&lt;/li&gt;
&lt;li&gt;Up to 5 read replicas of any database&lt;/li&gt;
&lt;li&gt;It is possible to have read replicas of read replicas - but this can introduce latency.&lt;/li&gt;
&lt;li&gt;Each read replica has its own DNS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Can have multi AZ&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  RDS Backups
&lt;/h3&gt;
&lt;h4&gt;
  
  
  Automated Backups
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Allows you to recover your database to any point in time within the specified retention period (Max 35 days)&lt;/li&gt;
&lt;li&gt;Takes daily snapshots and stores transition logs&lt;/li&gt;
&lt;li&gt;When recovering AWS will choose the most recent backup&lt;/li&gt;
&lt;li&gt;Enabled by default&lt;/li&gt;
&lt;li&gt;Backup data is stored in S3&lt;/li&gt;
&lt;li&gt;May experience latency when backup is being taken&lt;/li&gt;
&lt;li&gt;Backups are deleted once you remove the original RDS instances&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;
  
  
  Database Snapshot
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;User-initiated, must be manually done by yourself&lt;/li&gt;
&lt;li&gt;Stored until you explicitly delete them, even after you delete the original RDS instance they are still persisted. However this is not the case with automated backups.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Install PostgreSQL&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Go to the link below&lt;br&gt;
&lt;a href="https://www.postgresql.org/download/windows/"&gt;Follow the link&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Select click on the installer and choose the latest version to begin the download process.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Follow the prompts, and finish download(do not choose the Stack driver for this purpose).&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;From Windows , open Postgresql and copy the shell and pgadmin4 onto the desktop.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Connect to the DB client.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We can connect using 2 options:

&lt;ol&gt;
&lt;li&gt;GUI Client - i.e using DataGrip, Postico(for MAC users), pgAdmin(for Windows users).&lt;/li&gt;
&lt;li&gt;Terminal/CMD - allows us to use the commands to access the DB.&lt;/li&gt;
&lt;li&gt;Application - we write a server side application to return data from our database.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Startup the Database Server to connect to our local server.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We will open the PostgreSQL shell, we can also use this to connect to a remote server by pasting in the url during
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server[localhost]: --paste in url here--
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;So we will press enter to cycle through the following
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Server[localhost]:
Database[postgres]:  
Port[5432]: 
Username[postgres]:
Password for user postgres:  (now enter the password we used when configuring our system)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;To use the GUI , click on pgAdmin4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 4: Create a Database&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;While using the Postgres shell, type the following commands
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;psql: \l                    --------&amp;gt; lists all databases
psql: CREATE DATABASE test; --------&amp;gt; creates a database with the name test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;Step 5: Connect to a Database&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;To be able to use Postgresql in our cmd, we need to add Postgresql to PATH, we can do this by adding C:\Program Files\PostgreSQL\15\bin and C:\Program Files\PostgreSQL\15\lib to path&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Therefore to access the postgres client from the CMD type&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;Users&amp;gt; psql --help

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

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;In the command below postgres is the default username and test is the database we created above. The command will drop us into the postgres shell for the existing DB.
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Users&amp;gt; psql -h localhost -p 5432 -U postgres test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;-To connect to the database when we are in the postgres shell, we will run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;test=# \l                      ----&amp;gt; lists all databases
test=# \c test
test=# \c killmonger           ----&amp;gt; to connect to another database called killmonger, we simply use the command
test=# DROP DATABASE test;     ----&amp;gt; to permanently delete a database

Step 6: Creating tables and adding data in PostgreSQL
- While logged into our database above we will run the following
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;test=# CREATE TABLE person(&lt;br&gt;
test(# id INT,&lt;br&gt;
test(# first_name VARCHAR(50),&lt;br&gt;
test(# last_name VARCHAR(50),&lt;br&gt;
test(# gender VARCHAR(7),&lt;br&gt;
test(# date_of_birth DATE);&lt;/p&gt;

&lt;p&gt;-- To se the table we will run &lt;br&gt;
test=# \d                     ----&amp;gt; to describe the table&lt;br&gt;
test=# \d person              ----&amp;gt; shows the table schema&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- To create a table with constraints i.e we must have values
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;test=# CREATE TABLE person(&lt;br&gt;
test(# id BIGSERIAL NOT NULL PRIMARY KEY,&lt;br&gt;
test(# first_name VARCHAR(50) NOT NULL,&lt;br&gt;
test(# last_name VARCHAR(50) NOT NULL,&lt;br&gt;
test(# gender VARCHAR(7) NOT NULL,&lt;br&gt;
test(# date_of_birth DATE) NOT NULL,&lt;br&gt;
test(# email VARCHAR(150) );&lt;/p&gt;

&lt;p&gt;-- To se the table we will run &lt;br&gt;
test=# \d                     ----&amp;gt; to describe the table&lt;br&gt;
test=# \d person              ----&amp;gt; shows the table schema&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- To add records(which are rows) into tables
INSERT INTO person(
    first_name,
    last_name,
    gender,
    date_of_birth)
VALUES ('Anne', 'Smith', 'FEMALE', DATE '1988-01-09');

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

&lt;/div&gt;



&lt;p&gt;test=# \dt       ----&amp;gt; to see just the table&lt;br&gt;
test=# INSERT INTO person(first_name, last_name, gender, date_of_birth)&lt;br&gt;
test=#  VALUES( 'Anne', 'Smith', 'FEMALE', '1988-01-09');&lt;/p&gt;

&lt;p&gt;--To add a value with the email column:&lt;br&gt;
test=# \dt       ----&amp;gt; to see just the table&lt;br&gt;
test=# INSERT INTO person(first_name, last_name, gender, date_of_birth, email)&lt;br&gt;
test=#  VALUES( 'Jake', 'James', 'MALE', '1988-01-09', '&lt;a href="mailto:jake@gmail.com"&gt;jake@gmail.com&lt;/a&gt;');&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- As we have seen so far, physically typing in the data is time-consuming, therefore, if we need to work with large datasets , the exercise will be almost impossible to achieve, therefore to add multiple people we can use websites such as **Mockaroo**

- We will create our file there and open it with VSCode to ensure that some values are NOT NULL as below
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create table person (&lt;br&gt;
    first_name VARCHAR(50) NOT NULL,&lt;br&gt;
    last_name VARCHAR(50) NOT NULL,&lt;br&gt;
    email VARCHAR(150),&lt;br&gt;
    gender VARCHAR(15) NOT NULL,&lt;br&gt;
    date_of_birth DATE NOT NULL,&lt;br&gt;
    country_of_birth VARCHAR(50)&lt;br&gt;
);&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- To import/ open it in postgres we will run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;--be sure to copy the file path from where our file is located and make use of the slash as shown below and wrap in single quotes&lt;/p&gt;

&lt;p&gt;test=# \i 'C:/path/path/person.sql'&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- To make sure that we only have current values, we can drop the previous table and create a new table 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;test=# \d person&lt;br&gt;
test=# DROP TABLE person;  ---&amp;gt; since some values in our imported table are not in the existing table, we will delete the existing table &lt;br&gt;
test=# \d &lt;br&gt;
test=# \i 'C:/path/path/person.sql'&lt;br&gt;
test=# SELECT * FROM person;     ---&amp;gt;all values are now pulled in&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- To ensure that they are automatically numbered, add id into the code in VSCode
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;create table person (&lt;br&gt;
    id BIGSERIAL NOT NULL PRIMARY KEY,&lt;br&gt;
    first_name VARCHAR(50) NOT NULL,&lt;br&gt;
    last_name VARCHAR(50) NOT NULL,&lt;br&gt;
    email VARCHAR(150),&lt;br&gt;
    gender VARCHAR(15) NOT NULL,&lt;br&gt;
    date_of_birth DATE NOT NULL,&lt;br&gt;
    country_of_birth VARCHAR(50)&lt;br&gt;
);&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
- We will repeat the following commands:
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;test=# DROP TABLE person;  ---&amp;gt; since some values in our imported table are not in the existing table, we will delete the existing table &lt;br&gt;
test=# \i 'C:/path/path/person.sql'&lt;br&gt;
test=# SELECT * FROM person;     ---&amp;gt;all values are now pulled including the id&lt;/p&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;


**Step 7: Using commands**
test=# SELECT * FROM person;  ----&amp;gt; shows all columns/fields in the table
test=# SELECT first_name, last_name FROM person;

***Sorting using the ORDER BY keyword***

test=# SELECT * FROM person ORDER BY country_of_birth;  ----&amp;gt; sort by ascending order by default
test=# SELECT DISTINCT(country_of_birth) FROM person ORDER BY country_of_birth;        ----&amp;gt; to only get the country value once

***Sorting using the WHERE keyword***
test=# SELECT * FROM person WHERE gender = 'Female';
test=# SELECT * FROM person WHERE gender = 'Female' AND (country_of_birth='Poland' OR country_of_birth='China');
test=# SELECT * FROM person WHERE gender = 'Female' AND (country_of_birth='Poland' OR country_of_birth='China') AND last_name = 'Kimble';

***Comparison operators***
test=# SELECT 1 &amp;lt; 1;
test=# SELECT 1 &amp;gt;= 2;
test=# SELECT 1 &amp;lt;&amp;gt; 1;   ----&amp;gt; 1 not equal to 2
test=# SELECT 1 + 1;

***LIMIT and OFFSET keywords***
test=# SELECT * FROM person LIMIT 12;
test=# SELECT * FROM person OFFSET 5 LIMIT 5;   ----&amp;gt; starts from id 6 to 10
SELECT * FROM person OFFSET 5 FETCH FIRST 5 ROW ONLY;
test=# SELECT * FROM person OFFSET 5 FETCH FIRST 1 ROW ONLY;

***IN keywords***
test=# SELECT * FROM person WHERE country_of_birth='China' OR country_of_birth='Brazil' OR country_of_birth='France';
test=# SELECT * FROM person WHERE country_of_birth IN('China', 'Brazil', 'France');
test=# SELECT * FROM person WHERE country_of_birth IN('China', 'Brazil', 'France', 'Kenya', 'Cambodia') ORDER BY gender;
test=# SELECT * FROM person WHERE country_of_birth IN('China', 'Brazil', 'France', 'Kenya', 'Cambodia') ORDER BY country_of_birth;

***BETWEEN keyword to get data from a range***
test=# SELECT * FROM person WHERE date_of_birth BETWEEN DATE '2022-01-01' AND '2022-03-30';

***LIKE keyword values against a pattern using wildcards***
- % is a wildcard thus accepts all entries
- ILIKE accepts both uppercase and lowercase
test=# SELECT * FROM person WHERE email LIKE '%@google.com'; 
test=# SELECT COUNT(*) FROM person WHERE email LIKE '%@google.%'; 
test=# SELECT COUNT(*) FROM person WHERE country_of_birth ILIKE 'p%';       ----&amp;gt; ignores the case

***GROUP BY ***
test=# SELECT country_of_birth, COUNT(*) FROM person GROUP BY country_of_birth;
test=# SELECT country_of_birth, COUNT(*) FROM person GROUP BY country_of_birth ORDER BY country_of_birth; 

***HAVING keyword***
test=# SELECT country_of_birth,COUNT(*) FROM person GROUP BY country_of_birth HAVING COUNT(*)&amp;lt;=140 ORDER BY country_of_birth;





####RESOURCES
1. [Adding to environment variables to PATH in Windows](https://www.youtube.com/watch?v=2oAM4Q-9DMU)
2. [PostgreSQL Data types - Documentation](https://www.postgresql.org/docs/current/datatype.html)
3. [PostgreSQL Aggregate Function Documentation](https://www.postgresql.org/docs/9.5/functions-aggregate.html)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

</description>
      <category>postgres</category>
      <category>sql</category>
      <category>aws</category>
      <category>programming</category>
    </item>
    <item>
      <title>Free AWS BootCamp WEEK 4: SQL Databases</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Tue, 14 Mar 2023 14:20:01 +0000</pubDate>
      <link>https://dev.to/msaghu/free-aws-bootcamp-week-4-sql-databases-4hkg</link>
      <guid>https://dev.to/msaghu/free-aws-bootcamp-week-4-sql-databases-4hkg</guid>
      <description>&lt;p&gt;Hi guys, welcome back!!!&lt;br&gt;
This is week 4 of the Andrew Brown AWS Free code camp that you can also follow on Youtube and LinkedIn.&lt;/p&gt;

&lt;p&gt;This week we will be handling:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;SQL&lt;/li&gt;
&lt;li&gt;PostgreSQL&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What are Databases?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;A database is a server where we can store, manipulate and retrieve data.&lt;/li&gt;
&lt;li&gt;A relational database defines relationships between tables of data inside the database.&lt;/li&gt;
&lt;li&gt;Therefore PostgreSQL is the database engine and SQL is the Structured Query Language/the programming language.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What are the advantages of databases?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They have more storage capabilities than spreadsheets e.g Google spreadsheets or Excel sheets.&lt;/li&gt;
&lt;li&gt;Are more secure as data is encrypted.&lt;/li&gt;
&lt;li&gt;Multiple users can write queries to gather insight from the data at the same time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  What is SQL?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;SQL stands for Structured Query Language.&lt;/li&gt;
&lt;li&gt;This is the most widely used programming language for databases.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What are the basics of SQL?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SQL is not processed in the order in which it is written i.e. it starts from FROM ==&amp;gt; SELECT ==&amp;gt; LIMIT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What are tables in SQL?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;These are the main building blocks of Databases.&lt;/li&gt;
&lt;li&gt;Databases are organized into tables which hold related data about a particular subject.&lt;/li&gt;
&lt;li&gt;Tables can have both columns and rows , &lt;em&gt;rows&lt;/em&gt; are referred to as &lt;strong&gt;&lt;em&gt;records&lt;/em&gt;&lt;/strong&gt; and &lt;em&gt;columns&lt;/em&gt; are referred to as &lt;strong&gt;&lt;em&gt;fields&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;A tables fields are limited to the number created during database creation.&lt;/li&gt;
&lt;li&gt;While there is no limit to the number of records.&lt;/li&gt;
&lt;li&gt;Table names should be &lt;strong&gt;&lt;em&gt;lowercase&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;should not include spaces(use underscores instead)&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;can be plural&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Field names should be &lt;strong&gt;&lt;em&gt;lowercase&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;should not include spaces(use underscores instead)&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;should be singular&lt;/em&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;em&gt;each field should have different names&lt;/em&gt;&lt;/strong&gt; and &lt;strong&gt;&lt;em&gt;should not share names with the table name&lt;/em&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;em&gt;Unique identifiers/keys&lt;/em&gt;&lt;/strong&gt; help identify records in a table, are unique and are often numbers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Data types in SQL&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Data types are chosen depending on the type of data the field will hold i.e numbers, text, dates.&lt;/li&gt;
&lt;li&gt;Data types are necessary as they are stored differently and they take up different amounts of space.&lt;/li&gt;
&lt;li&gt;A &lt;em&gt;string&lt;/em&gt; refers to a sequence of characters such as letters or punctuation.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;VARCHAR&lt;/em&gt; is a flexible and popular string data type in SQL.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;INT&lt;/em&gt; is a flexible and popular integer data type in SQL.&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;NUMERIC&lt;/em&gt; is a flexible and popular float data type in SQL.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What are Schemas?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Are blueprints of databases.&lt;/li&gt;
&lt;li&gt;Schemas show database design i.e tables included in the database and the relationships between the tables.&lt;/li&gt;
&lt;li&gt;Schemas also inform the data type each field can hold.&lt;/li&gt;
&lt;li&gt;Information in a database table is stored in a hard disk of a server.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Basic SQL queries
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;This is the basic structure of an SQL query
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name  ------------------&amp;gt; chooses the field name
FROM patrons; -----------------&amp;gt; chooses the table in which the fields are listed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Selecting multiple fields
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT card_num, name
FROM patrons;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Selecting all fields
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT *
FROM patrons;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Renaming columns using aliasing(temporarily)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name AS first_name, year_hired
FROM employees;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To show a value i.e year_hired only once using DISTINCT.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT DISTINCT year_hired
FROM employees;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To show multiple fields i.e year_hired .
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT dept_id, year_hired
FROM employees;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To show multiple fields i.e year_hired using DISTINCT.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT DISTINCT dept_id, year_hired
FROM employees;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;view&lt;/strong&gt; is a virtual table that is a query code stored for future use. &lt;/li&gt;
&lt;li&gt;To save a SQL query as a view;
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;CREATE VIEW employee_hire_years AS
SELECT id, name, year_hired
FROM employees;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Querying databases
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;COUNT() - returns number of records with a value in a field
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT COUNT(birthdate) AS count_birthdates 
FROM people;

-- to count multiple fields from a table
SELECT COUNT(name) AS count_names, COUNT(birthdate) AS count_birthdates 
FROM people;

-- to count the number of records in a table
SELECT COUNT(*) AS total_records
FROM people;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To find distinct values in table
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT COUNT(DISTINCT birthdate) AS count_distinct_birthdates
FROM people;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Filtering data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using WHERE
-n Comparison operators &amp;gt;, &amp;lt;, =, &amp;lt;=, &amp;gt;=, &amp;lt;&amp;gt;(not equal to)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;WHERE with comparison operators

SELECT title
FROM films
WHERE release_year &amp;gt; 1960;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To use a comparison operator from a films table  to find is a film language could be English
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Count the Spanish-language films
SELECT COUNT(language) AS count_spanish
FROM films
WHERE language = 'Spanish';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To use multiple criteria with : OR, AND, BETWEEN
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Using OR operator
SELECT *
FROM films
WHERE language = 'Spanish' OR length = 120;

-- Using AND operator
SELECT *
FROM films
WHERE language = 'Spanish' AND length = 120;

-- Using AND, OR
SELECT title
FROM films
WHERE (release_year = 1994 OR release_year = 1995) AND (certification = "PG" OR certification = "R");

-- Using BETWEEN operator(shorthand for the AND operator)
SELECT title
FROM films
WHERE length BETWEEN 120 AND 180;

-- Using BETWEEN operator(shorthand for the AND operator)
SELECT title
FROM films
WHERE length BETWEEN 120 AND 180 AND country='Kenya';

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Filtering text&lt;/strong&gt; &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Its usually recommended to filter with a pattern rather than specific text.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We will then use: LIKE, NOT LIKE, IN.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use Like for records that match the specified pattern&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;- LIKE use like with % to match zero, one or many characters 

SELECT name
FROM people
WHERE name LIKE 'Ade%';

- LIKE use like with _ to match a single character
SELECT name
FROM people
WHERE name LIKE 'Ev_';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Use NOT LIKE for records that do not match the specified pattern
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT name
FROM people
WHERE name NOT LIKE 'A.%';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;To filter across many conditions or a range of numbers with WHERE, OR  or WHERE, IN
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT title
FROM films
WHERE release_year = 1920
OR release_year = 1930
OR release_year = 1940;

SELECT title
FROM films
WHERE release_year IN (1920, 1930, 1940);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Filtering Data with NULL values&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use IS NULL incase of missing data
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--Gives the titles where release_year was not provided 
SELECT title
FROM films
WHERE release_year IS NULL;

--Gives the total number of titles where release_year was not provided 
SELECT COUNT(*) AS not_released
FROM films
WHERE release_year IS NULL;

--Gives the total number of titles where release_year was provided
SELECT COUNT(title) AS not_released
FROM films
WHERE release_year IS NOT NULL;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Summarizing Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For numerical data AVG(), SUM()
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT AVG(budget)
FROM films;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;For non-numerical data MIN(), MAX(), COUNT()&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  &lt;strong&gt;Summarizing subsets&lt;/strong&gt;
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT AVG(budget) AS avg_budget
FROM films
WHERE release_year &amp;gt;= 2010;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ROUND()
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;--number_to_round, decimal_places

SELECT ROUND(AVG(budget), 2) AS avg_budget
FROM films
WHERE release_year &amp;gt;= 2010;

--to round to a whole number
SELECT ROUND(AVG(budget)) AS avg_budget
FROM films
WHERE release_year &amp;gt;= 2010;

--to round using a negative number
SELECT ROUND(AVG(budget), -5) AS avg_budget
FROM films
WHERE release_year &amp;gt;= 2010;

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

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Basic Arithmetic&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Basic arithmetic is +, -, * and /
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT (4 + 3);

SELECT (4 / 3);  --------------&amp;gt; 1

SELECT (4.0 / 3.0); -----------&amp;gt; 1.3333
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Sorting results&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using ORDER BY(sorts in ascending order)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Using ORDER BY
SELECT title, budget
FROM films
ORDER BY budget;

-- Using ORDER BY and ASCending order
SELECT title, budget
FROM films
ORDER BY budget ASC;

-- Using ORDER BY and DESCending order
SELECT title, budget
FROM films
WHERE budget IS NOT NULL
ORDER BY budget DESC;

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

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;ORDER BY multiple fields
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Using ORDER BY and DESCending order
SELECT title, wins, imdb_score
FROM best_movies
ORDER BY wins DESC, imdb_score DESC;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Grouping data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GROUP BY single fields,
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Grouping by certification, then counting
SELECT certification, COUNT(title) AS title_count
FROM films
GROUP BY certification;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;GROUP BY multiple fields,
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- Grouping by certification, then counting
SELECT certification, language COUNT(title) AS title_count
FROM films
GROUP BY certification, language;

-- Modify the query to also list the average budget and average gross
SELECT release_year, AVG(budget) AS avg_budget, AVG(gross) AS avg_gross
FROM films
WHERE release_year &amp;gt; 1990
GROUP BY release_year;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Using Grouping BY with ORDER BY
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SELECT certification, COUNT(title) AS title_count
FROM films
GROUP BY certification
ORDER BY title_count DESC;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Filtering Grouped Data&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Since we cant filter aggregate functions with WHERE
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-- This will not work
SELECT certification, COUNT(title) AS title_count
FROM films
GROUP BY certification
WHERE COUNT(title) &amp;gt; 10;

--This WILL work
SELECT certification, COUNT(title) AS title_count
FROM films
GROUP BY certification
HAVING COUNT(title) &amp;gt; 10;

--This WILL work
SELECT release_year
FROM films
GROUP BY release_year
HAVING AVG(duration) &amp;gt; 10;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  RESOURCES
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://app.datacamp.com/learn/courses/intermediate-sql"&gt;DataCamp Beginner SQL &amp;amp; Intermediate Courses &lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;a href="https://www.youtube.com/watch?v=qw--VYLpxG4"&gt;FreeCodecamp - Learn PostgreSQL Tutorial&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>sql</category>
      <category>postgres</category>
      <category>aws</category>
      <category>docker</category>
    </item>
    <item>
      <title>Free AWS Bootcamp: Week 1 - App Containerization</title>
      <dc:creator>Msaghu</dc:creator>
      <pubDate>Tue, 21 Feb 2023 12:10:41 +0000</pubDate>
      <link>https://dev.to/msaghu/free-aws-bootcamp-week-1-app-containerization-11lk</link>
      <guid>https://dev.to/msaghu/free-aws-bootcamp-week-1-app-containerization-11lk</guid>
      <description>&lt;p&gt;Hi guys, welcome back to week 2.&lt;/p&gt;

&lt;p&gt;This week we will be learning about Docker and containers.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is a container?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;An isolated environment for running an application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It can also be described as a running instance of an image.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Are more lightweight compared to VMs, as they do not require/or contain a full OS and they use the OS of the host, thus allowing them to start quickly.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We need less hardware resources unlike VMs thus allowing us to run even 100s of containers side-by-side.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is Docker?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A platform for building, running and shipping applications and all its dependencies in a consistent manner.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Virtual Machines allow us to run applications in isolation inside a VM.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is the Docker Architecture?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Uses the &lt;strong&gt;Client-Server Architecture&lt;/strong&gt;, where the Client talks to the Server(This is the Docker Engine) using a RESTful API.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Containers use the Kernel of the Host, and each kernel has its own APIs thus making it hard to run windows applications on Mac and vice versa, however we can run Linux applications natively on Windows due to WSL. &lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What are the differences between docker desktop and Docker?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Docker desktop makes use of a hidden VM(virtual machine)/subsystem depending on your OS or subsystem to run an isolated instance of Docker.&lt;/li&gt;
&lt;li&gt;Docker then uses the hidden instance to configure a Linux OS with the Docker runtime. Once its installed we will then have the Docker CLI and User Interface.&lt;/li&gt;
&lt;li&gt;Docker desktop Is segmented from your main OS.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What is a Docker image?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A template for creating an environment of your choice i.e a database, a web application, an application.&lt;/li&gt;
&lt;li&gt;An image is a Snapshot, which is a version of our image. &lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What is the process of dockerizing an application?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;This means that we add a Docker file to the application.&lt;/li&gt;
&lt;li&gt;A dockerfile is a plain text file that includes instructions to package the application into an image.&lt;/li&gt;
&lt;li&gt;An image contains everything an application needs to run e.g:&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A cut-down OS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A runtime environment&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Application files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Third-party libraries&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Environment variables&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Then Docker starts a container with the image, thus making a container a process with its own file system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;We can then post our application image to Docker hub which can then be downloaded and started on any other machine.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Traditional environment for a JavaScript application&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Start with an OS&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Install Node (the execution environment for JS code)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy app files&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Run node app.js&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;What are Container Volumes?&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Allows us to share data between host and container or between containers which can be a file or  folder.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;strong&gt;Key Terms&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;VM&lt;/strong&gt; - Virtual Machines&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API&lt;/strong&gt; - Application Programming Interface&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Client-Server Architecture&lt;/strong&gt; - A client can be a web browser or desktop application that a person interacts with to make requests to computer servers. A server can be a type of virtual server.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Kernel&lt;/strong&gt; - Manages applications and hardware resources eg. memory, CPU.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For example, suppose that a client makes a request for a news article, the score in an online game, or even you clicking the links in the resources below. The server evaluates the details of this request and fulfills it by returning the information to the client. &lt;/p&gt;




&lt;p&gt;&lt;strong&gt;&lt;u&gt;Resources&lt;/u&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=7y50rZItKCQ" rel="noopener noreferrer"&gt;Docker Desktop Complete Setup Guide (Mac/Windows) + Kubernetes!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/watch?v=pTFZFxd4hOI" rel="noopener noreferrer"&gt;Docker Tutorial for Beginners&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>opensource</category>
    </item>
  </channel>
</rss>
