<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.2">Jekyll</generator><link href="https://conortolan.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://conortolan.com/" rel="alternate" type="text/html" /><updated>2023-01-12T11:01:49+00:00</updated><id>https://conortolan.com/feed.xml</id><title type="html">Conor Tolan</title><subtitle>Senior Cloud Engineer - Google Cloud Platform, from Ireland</subtitle><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><entry><title type="html">ChatGPT Game With Son</title><link href="https://conortolan.com/ChatGPT-Game-With-Son/" rel="alternate" type="text/html" title="ChatGPT Game With Son" /><published>2023-01-11T08:56:31+00:00</published><updated>2023-01-11T08:56:31+00:00</updated><id>https://conortolan.com/ChatGPT-Game-With-Son</id><content type="html" xml:base="https://conortolan.com/ChatGPT-Game-With-Son/">&lt;p&gt;Draft - Hello, First post of 2023 and its a good one. I am creating a Python based figthing game together with/for my son. With all the discussion of ChatGPT I decided to give it a go and see what it can do. &lt;img src=&quot;https://conortolan.com/images/ChatGPT-game-1.png&quot; alt=&quot;ChatGPT Game 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So the Python that came out looks pretty good to me (I’m no Python expert but I can read and work with it), I ran this in my cmdline and after fixing some spacing issues it worked great. I am honestly impressed. This was my second pass at requesting this game format so I had already learned that I needed to be very specific to get out what I wanted. Initially I got a game with just one attack and no input. It ran but was not fun as a game. It had the working logic which I could have edited manually, but instead I asked more a specific question and got a more specific answer.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;health&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attack1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attack2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attack3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;health&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attack&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attack1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attack2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;attack3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;choose_attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;, choose your attack (1, 2, or 3): &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reduce_health&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;


&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__init__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;damage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;
        &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;damage&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;damage&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;__str__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;


&lt;span class=&quot;n&quot;&gt;player1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Patrick&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Punch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Kick&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Uppercut&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;40&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;player2&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Conor&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Slash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Stab&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;35&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Smash&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;45&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;players&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;players&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;'s health: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;attack&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choose_attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;other_player&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;players&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;player&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;players&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;players&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; uses &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attack&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;other_player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reduce_health&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;attack&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;damage&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other_player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;health&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other_player&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s&quot;&gt; has been defeated!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Plays out as&lt;/p&gt;

&lt;div class=&quot;language-shell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;while &lt;/span&gt;True:
...     &lt;span class=&quot;k&quot;&gt;for &lt;/span&gt;player &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;players:
...         print&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;s2&quot;&gt;&quot;{player.name}'s health: {player.health}&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
...         attack &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; player.choose_attack&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
...         other_player &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; players[1] &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;player &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; players[0] &lt;span class=&quot;k&quot;&gt;else &lt;/span&gt;players[0]
...         print&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;s2&quot;&gt;&quot;{player.name} uses {attack}!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
...         other_player.reduce_health&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;attack.damage&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
...         &lt;span class=&quot;k&quot;&gt;if &lt;/span&gt;other_player.health &amp;lt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; 0:
...             print&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;f&lt;span class=&quot;s2&quot;&gt;&quot;{other_player.name} has been defeated!&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
...             &lt;span class=&quot;nb&quot;&gt;exit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
... 
Patrick&lt;span class=&quot;s1&quot;&gt;'s health: 100
Patrick, choose your attack (1, 2, or 3): 2
Patrick uses Kick!
Conor'&lt;/span&gt;s health: 70
Conor, choose your attack &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1, 2, or 3&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;: 3
Conor uses Smash!
Patrick&lt;span class=&quot;s1&quot;&gt;'s health: 55
Patrick, choose your attack (1, 2, or 3): 3
Patrick uses Uppercut!
Conor'&lt;/span&gt;s health: 30
Conor, choose your attack &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;1, 2, or 3&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;: 2
Conor uses Stab!
Patrick&lt;span class=&quot;s1&quot;&gt;'s health: 20
Patrick, choose your attack (1, 2, or 3): 2
Patrick uses Kick!
Conor has been defeated!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="GCP" /><summary type="html">Draft - Hello, First post of 2023 and its a good one. I am creating a Python based figthing game together with/for my son. With all the discussion of ChatGPT I decided to give it a go and see what it can do.</summary></entry><entry><title type="html">Connect to MIG Over IAP tunnel</title><link href="https://conortolan.com/Connect-to-MIG-IAP-tunnel/" rel="alternate" type="text/html" title="Connect to MIG Over IAP tunnel" /><published>2022-12-23T08:56:31+00:00</published><updated>2022-12-23T08:56:31+00:00</updated><id>https://conortolan.com/Connect-to-MIG-IAP-tunnel</id><content type="html" xml:base="https://conortolan.com/Connect-to-MIG-IAP-tunnel/">&lt;p&gt;Hello, The most obvious thing to try to do next is to SSH to the VM, but I do not want to be able to connect to these VMs openly over the internet. So I will use Google’s Identity Aware Proxy (IAP) to tunnel into the VMs without having to setup complicated VPN tunnels or opening firewalls to the internet. &lt;img src=&quot;https://conortolan.com/images/Terraform-Add-IAP-perms-1.png&quot; alt=&quot;Add IAP Permission 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Ok, I know I just started writing this up, but it took me three days to get to the bottom of why it wasn’t working. Classic d’uh moment.&lt;/p&gt;

&lt;p&gt;Loosely I was following the steps as &lt;a href=&quot;https://medium.com/google-cloud/how-to-ssh-into-your-gce-machine-without-a-public-ip-4d78bd23309e&quot;&gt;laid out here in this article&lt;/a&gt;, but I was going to do it completely in Terraform code. While it is clearly important to know how to enable service APIs via the UI, for Infrastructure As Code (IAC) you need to know how to do it with the code.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-add-IAP-service-1.png&quot; alt=&quot;Add IAP Permission 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I pulled together these few resource blocks on the first day, no big deal. Applied them with Terraform and expected everything to work like it does in work and like it said it would in the above linked article. Of course it did not work.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/IAP-SSH-self-test.png&quot; alt=&quot;IAP Self test 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I ran the connectivity tests multiple times, I checked again that I had actually see that SSH was open to the whole world by default.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Firewall-settings-1.png&quot; alt=&quot;Firewall Settings 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Tried to use the SSH via web browser, all failed to connect. I went back and looked at the created resources and permissions in the TF code. I tried to google what other authentication method I might be using that we do not use in work, but I could not make any progress. I even spun up a fresh VM from a GCP template via the UI incase it was something wrong in my deployment changes from the previous post. In some way I’m glad I didn’t find anything because I means I had followed these steps correctly, but in a more meaningful was I was frustrated that I was not working. That was until I looked again at the default firewall rule. I was going in there to confirm that it was an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;allow&lt;/code&gt; rule and maybe recreate the rule to prove I wasn’t crazy. This is when I saw that the network was configured as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default&lt;/code&gt;. This didn’t mean anything much except I was not deploying my VMs to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;default&lt;/code&gt; network and subnets. I had deployed my own network, so the firewall rules for the default network did not apply. I could not SSH because the firewall was not open.&lt;/p&gt;

&lt;p&gt;Whether or not now is a good time to write about importing existing resources such as the default network into your TF in order to destroy it, since it is not contained in your IAC, would be an interesting idea. But I’ll leave this post here because it took me way longer than I expected to be able to SSH to my deployed VMs over the IAP tunnel, which once allowed to connect did so as expected, mostly.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/SSH-works-kinda-1.png&quot; alt=&quot;SSH Works Kinda 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;Conor&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="GCP" /><summary type="html">Hello, The most obvious thing to try to do next is to SSH to the VM, but I do not want to be able to connect to these VMs openly over the internet. So I will use Google’s Identity Aware Proxy (IAP) to tunnel into the VMs without having to setup complicated VPN tunnels or opening firewalls to the internet.</summary></entry><entry><title type="html">GCP MIG deploy</title><link href="https://conortolan.com/GCP-MIG-deploy/" rel="alternate" type="text/html" title="GCP MIG deploy" /><published>2022-12-17T08:56:31+00:00</published><updated>2022-12-17T08:56:31+00:00</updated><id>https://conortolan.com/GCP-MIG-deploy</id><content type="html" xml:base="https://conortolan.com/GCP-MIG-deploy/">&lt;p&gt;Hello, so I’m thinking about what exactly to deploy, I have a few good ideas from recent work tasks but I would need to develop a few more bits of supporting infrastructure and services. So I am not sure what order to proceed. Today I’ll start with deploying a managed instance group (MIG). If you know AWS you can think of this like an auto-scaling group. Basically it is a set of VMs that are managed as a group to provide highly available services. &lt;img src=&quot;https://conortolan.com/images/GCP-Instance-Groups-1.png&quot; alt=&quot;MIG Deployed 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Sticking with the theme of this blog, I will deploy the example straight form GCP Cloud foundation fabric, the &lt;a href=&quot;https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/tree/v19.0.0/modules/compute-mig&quot;&gt;Compute-MIG&lt;/a&gt; bundles a few bits of infrastructure together with minimal TF code and understanding to implement. This method gets you off the ground quickly while you learn the components which work together behind the abstraction.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-plan-2.png&quot; alt=&quot;TF MIG Code 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here I have copied over the three Terraform resources from the &lt;a href=&quot;https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/tree/v19.0.0/modules/compute-mig#examples&quot;&gt;first example&lt;/a&gt; of a MIG. I changes the source to be Github and not the relative path in the example. In a real enterprise you will point to your own corporate source control repository. I do not recommend using a local copy of their repo as a relative path.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;module &quot;cos-nginx&quot; {
  source = &quot;./modules/cloud-config-container/nginx&quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;module &quot;cos-nginx&quot; {
  source = &quot;github.com/GoogleCloudPlatform/cloud-foundation-fabric//modules/cloud-config-container/nginx&quot;
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I am actually really glad I came back to look at these examples again because I had missed or overlooked or more likely under appreciated the next example of &lt;a href=&quot;https://github.com/GoogleCloudPlatform/cloud-foundation-fabric/tree/v19.0.0/modules/compute-mig#multiple-versions&quot;&gt;multiple versions&lt;/a&gt;, I am pretty sure this is something I have been looking for to complete a task at work. I’ll cover this when I get to a point of implementing it and I should add a link when the post is created [TODO].&lt;/p&gt;

&lt;p&gt;Oh yes, the other thing I changed here is the OS. I have been using Centos mostly so I replaced the boot image, will this work? I don’t know. I hope so.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-plan-error-2.png&quot; alt=&quot;TF plan error 2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Ok looks like there is more to update, I replaced the network and subnetwork references but I didn’t get it right the firs time. I needed to reference one of the two subnets I created in my &lt;a href=&quot;https://conortolan.com/Terraform-Connected-to-GCP/&quot;&gt;last post&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Subnet-code-1.png&quot; alt=&quot;TF plan error 2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is the final state I came to after a bit or trial and error. I should probably extract the region into a variable, that would make it better too, but I understand that it is easier to read the code when there are not too many abstractions all at once.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-apply-2.png&quot; alt=&quot;TF Apply 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;These three resources have been successfully applied to the project.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;Conor&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="GCP" /><summary type="html">Hello, so I’m thinking about what exactly to deploy, I have a few good ideas from recent work tasks but I would need to develop a few more bits of supporting infrastructure and services. So I am not sure what order to proceed. Today I’ll start with deploying a managed instance group (MIG). If you know AWS you can think of this like an auto-scaling group. Basically it is a set of VMs that are managed as a group to provide highly available services.</summary></entry><entry><title type="html">Terraform Connected to GCP</title><link href="https://conortolan.com/Terraform-Connected-to-GCP/" rel="alternate" type="text/html" title="Terraform Connected to GCP" /><published>2022-11-20T08:56:31+00:00</published><updated>2022-11-20T08:56:31+00:00</updated><id>https://conortolan.com/Terraform-Connected-to-GCP</id><content type="html" xml:base="https://conortolan.com/Terraform-Connected-to-GCP/">&lt;p&gt;With Terraform connecting to my GCP account I am able to start focusing on the infrastructure as code part of this project and less on the technical connectivity and setup which have been the focus of the previous posts. &lt;img src=&quot;https://conortolan.com/images/Cloud-foundation-fabric-1.png&quot; alt=&quot;Gcloud Init 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;What am I going to deploy? This is a question I have played around with quite a lot, and I think I have a good answer now. Previously I have thought about deploying some sort of app like an example app deployed in a container with all the pipeline bells and whistles that make it a cloud native app. These are quite common out there on the internet and usually come from software engineers who don’t really take the infrastructure as seriously. Yet my experience really is in the infrastructure and not the app side of things. I don’t really care about what application was going to be running and then those projects ran aground because it was not as interesting to me.&lt;/p&gt;

&lt;p&gt;So what will I do differently this time, I am aware I started this series of posts without actually going into it. Well now is the time.&lt;/p&gt;

&lt;p&gt;I have decided to deploy a mock enterprise datacenter using the &lt;a href=&quot;https://github.com/GoogleCloudPlatform/cloud-foundation-fabric&quot;&gt;GCP Cloud Foundation Fabric&lt;/a&gt;. This will give me a fast way to stand up some cool infrastructure and to explore topics that are current and interesting to me. GCP is still a relative newcomer but has scored some top tier &lt;a href=&quot;https://cloud.google.com/customers&quot;&gt;customers&lt;/a&gt; as enterprises try to balance out their cloud spend and not be totally beholden to AWS.&lt;/p&gt;

&lt;p&gt;So let me start now with the VPC Terraform module - for now right out of the documented examples as I don’t have a specific design in mind at this time.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/VPC-module-config-1.png&quot; alt=&quot;VPC module config 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Depending on your familiarity with Terraform, you may spot the source points to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;github.com&lt;/code&gt; directly, in a corporate environment you would fork the code into a local repo. This also allows you to make local copy changes where necessary. At this point I am not referencing a version tag, I am taking the latest. Ideally you will specify the specific version of the module which you have tested. I’ll mature this config in time, but this is ok for now.&lt;/p&gt;

&lt;p&gt;I have also improved the Terraform by moving some values into variables.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-variables-1.png&quot; alt=&quot;Terraform variables 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Variables make the code more reusable, I can define the project name in one location and then easily reference from now on as var.project. In each deployment folder I can then declare what variable may be different between folders such as the region or environment definition [prod] vs [nprd].&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-variables-2.png&quot; alt=&quot;Terraform variables 2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Here we also see the use of a terraform.tfvars file, this is an automatically loaded variables file. In contrast to a manually invoked variables file that could be called at run time on the command line.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;terraform plan -var=”env=prod” 
or 
terraform plan -var=”env=nprd”
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;terraform plan -var-file=”prod.tfvars” 
vs 
terraform plan -var-file=”nprd.tfvars”
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It all depends on how different you environments are, but you get the idea you can keep the code identical between environments and with switches in the code have different outcomes. In the variables.tf file you can see where I commented out the default value once I moved them into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;terraform.tfvars&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-plan-1.png&quot; alt=&quot;Terraform plan&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Terraform plan&lt;/code&gt; command and like the look of it, one VPC and two subnets as expected. So run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Terraform apply&lt;/code&gt; and answer ‘yes’.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/GCP-API-disabled.png&quot; alt=&quot;GCP API disabled&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Terraform apply&lt;/code&gt; throws this error - nothing big just I really am starting from scratch so the API has not been enabled. I followed the link and enabled my billing account. Redo the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;terraform apply&lt;/code&gt; and it works.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-apply-1.png&quot; alt=&quot;GCP API disabled&quot; /&gt;&lt;/p&gt;

&lt;p&gt;So that covered a couple of small technical things but we are also making progress. With a network we can move onto deploying VMs next.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;Conor&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="GCP" /><summary type="html">With Terraform connecting to my GCP account I am able to start focusing on the infrastructure as code part of this project and less on the technical connectivity and setup which have been the focus of the previous posts.</summary></entry><entry><title type="html">Connecting Terraform to GCP</title><link href="https://conortolan.com/Connecting-Terraform-to-GCP/" rel="alternate" type="text/html" title="Connecting Terraform to GCP" /><published>2022-11-14T08:56:31+00:00</published><updated>2022-11-14T08:56:31+00:00</updated><id>https://conortolan.com/Connecting-Terraform-to-GCP</id><content type="html" xml:base="https://conortolan.com/Connecting-Terraform-to-GCP/">&lt;p&gt;Next thing I want to get working is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Terraform Plan&lt;/code&gt; against my GCP project. I quickly swapped out of my blog volume to a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Code&lt;/code&gt; folder where I will keep my &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.tf&lt;/code&gt; files. &lt;img src=&quot;https://conortolan.com/images/GCloud-init-1.png&quot; alt=&quot;Gcloud Init 1&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  --volume=&quot;C:\Users\ctola\Documents\Blog&quot;:&quot;/blog&quot; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  --volume=&quot;C:\Users\ctola\Documents\Code&quot;:&quot;/code&quot; 
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I will create a folder for my data-center deployment code. I will distinguish between two types of code, deployment and configuration.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;em&gt;Deployment code&lt;/em&gt; is specific to resource deployment, the regions, resource names, specific IPs for VPNs in that region.&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Configuration code&lt;/em&gt;, is the TF module code which will do the configuration as defined by the deployment code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You should only have one copy of the configuration code and possibly many copies of the deployment code, each slightly different maybe for different regions or different uses such as Development versus Production.&lt;/p&gt;

&lt;p&gt;If I jump in and get ahead of myself and run Terraform plan now with only a skeleton configuration we will see the immediate issue which we need to address. Copying straight from the GCP Terraform documentation &lt;a href=&quot;https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/getting_started&quot;&gt;here&lt;/a&gt;, I will populate my project name in the provider block and I’ll accept the default region configuration. Just as an aside the US Central is a low carbon footprint region, apparently, so its a good default.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-main-tf-initial-1.png&quot; alt=&quot;TF Initial 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Below the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;provider&lt;/code&gt; block I copy paste a compute instance &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;resource&lt;/code&gt; block. I will not configure this at all now because I do not expect it to actually work.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-plan-error-1.png&quot; alt=&quot;TF Plan Error 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;With only these two blocks defined you can run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Terraform init&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Terraform plan&lt;/code&gt;. This is not a blog on how to use Terraform but init initialises the folder as a workspace and checks the files for a Terraform configuration, if access to the required modules is not avaialble this is where you will get an error. In my case, there is no issue initialising, but when Terraform tries to connect to GCP there is a permissions error. This makes sense I have not done any authentication yet.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Error: Attempted to load application default credentials since neither `credentials` nor `access_token` was set in the provider block.  No credentials loaded. To use your gcloud credentials, run 'gcloud auth application-default login'.
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To use gcloud credentials run ‘gcloud auth application-default login’. Ok so we have not yet added &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcloud&lt;/code&gt; to the container so now is the time.&lt;/p&gt;

&lt;p&gt;I will install gcloud cli as per instructions &lt;a href=&quot;https://cloud.google.com/sdk/docs/install#linux&quot;&gt;here&lt;/a&gt;, I will copy the commands into the Dockerfile in a new block for readability. Actually, gcloud cli need python, so that needs to be installed too. I’m copying from &lt;a href=&quot;https://computingforgeeks.com/install-latest-python-on-centos-linux/&quot;&gt;here&lt;/a&gt; for Python.&lt;/p&gt;

&lt;p&gt;I know I go on about this often but this is why I use the container approach. Too many times have I wanted to share a tool or piece of automation with a colleague but the pre-requirements are missing and it takes way longer than it should. With a shared team container, you only have to do all this setup once, no issues with missing dependancies or incompatible versions. Yes it is more work if taken in isolation for a single simple task but most thinks I do are not single simple tasks and by dragging out this blog with every step I hope I am helping top make that clearer. It a complex house of cards build up bit by bit relying on all the bits below.&lt;/p&gt;

&lt;p&gt;To run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcloud auth&lt;/code&gt; it means I need &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;glcoud cli&lt;/code&gt;, but also I need Python 3.5-3.9 and for that in CentOS 7 I will need a compatible gcc complier, for that I am best off installing Linux “Development Tools” and so on. After installing Python, to install the gcloud cli it is handy to have &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wget&lt;/code&gt; and then &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tar&lt;/code&gt; to unpack it. I am aware that there are now redundant tools used in commands to do similar things. For example curl and wget or unzip and tar. Why not re-write the example command? Having both of these common tools in my container is going to be useful down the road, so I will add them now.&lt;/p&gt;

&lt;p&gt;Right so after working through all that this is my current Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Dockerfile-4.png&quot; alt=&quot;Dockerfile 4&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I’ve added commands to get and remove the packages for Python 3.9 and GCloud Cli. I added some more yum package installs to facilitate it. I’ll collapse them into a single line shortly as it saves on container layers but that’s not important here and now.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Dockerfile-build-1.png&quot; alt=&quot;Dockerfile build 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;After the successful build (no I didn’t get it right the first time), then I can run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gcloud init&lt;/code&gt; in my container. Yay.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/GCloud-init-1.png&quot; alt=&quot;gCloud init 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;Conor&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="GCP" /><summary type="html">Next thing I want to get working is Terraform Plan against my GCP project. I quickly swapped out of my blog volume to a Code folder where I will keep my .tf files.</summary></entry><entry><title type="html">Adding TFEnv to Container</title><link href="https://conortolan.com/Adding-TFEnv-to-Container/" rel="alternate" type="text/html" title="Adding TFEnv to Container" /><published>2022-11-12T08:56:31+00:00</published><updated>2022-11-12T08:56:31+00:00</updated><id>https://conortolan.com/Adding-TFEnv-to-Container</id><content type="html" xml:base="https://conortolan.com/Adding-TFEnv-to-Container/">&lt;p&gt;Picking up from the end of the last post I needed to include my Git config inside my container so that I do not need to leave the container to use Git. I do this by mounting my .gitconfig file from my laptop into the container where it will be used while running in the container. This is how I get the right mix of disposability and persistence between my laptop and working container environment. &lt;img src=&quot;https://conortolan.com/images/TFenv.png&quot; alt=&quot;TFenv&quot; /&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run --rm /
  --volume=&quot;C:\Users\ctola\Documents\Blog&quot;:&quot;/blog&quot; /
  -it docker.io/library/mycontainer:local
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;to&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run --rm /
  --volume=&quot;C:\Users\ctola\Documents\Blog&quot;:&quot;/blog&quot; /
  --volume=&quot;C:/Users/me/.gitconfig&quot;:&quot;/root/.gitconfig&quot; /
  -it docker.io/library/mycontainer:local
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Again this is why I save this command, I don’t want to get deep into a repo update and then realise I haven’t go whatever setting configured and I need to go set it and lose my flow. This pattern can be use with other file configs too, and you do not need to mount an actual in use file, it could be a specific file that you place in a persistent location just for ease of use. You might have one .ssh config for one project and another in another folder. You would swap between them by changing the one mounted at run time.&lt;/p&gt;

&lt;p&gt;Project 1&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run --rm /
  --volume=&quot;C:\Users\ctola\Documents\Blog&quot;:&quot;/blog&quot; /
  --volume=&quot;C:/Users/me/configs/Project_1/.gitconfig&quot;:&quot;/root/.gitconfig&quot; /
  -it docker.io/library/mycontainer:local
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Project 2&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;docker run --rm /
  --volume=&quot;C:\Users\ctola\Documents\Blog&quot;:&quot;/blog&quot; /
  --volume=&quot;C:/Users/me/configs/Project_2/.gitconfig&quot;:&quot;/root/.gitconfig&quot; /
  -it docker.io/library/mycontainer:local
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Right with that working I want to get Terraform installed. I’m going to take the Dockerfile from yesterday and add some lines. &lt;a href=&quot;https://github.com/tfutils/tfenv&quot;&gt;TFEnv&lt;/a&gt;, this tool allows quick and easy version switching and handles the installation.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Dockerfile-2.png&quot; alt=&quot;Dockerfile-2&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I added a blank line to create a block of lines dedicated to installing and configuring TF. Starting with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ARG&lt;/code&gt; line, think of this as a variable. In this variable I will specify the Terraform version number that I want to use, having this defined in one place and then used in a few makes it easier to change in the future. I got these commands straight from the Github linked above.&lt;/p&gt;

&lt;p&gt;In the image you can see a commented line which i left in to make the following point. The off the shelf path for the bash profile didn’t match the OS version I have chosen, so the first time I built the container it errored on line 15 because the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tfenv&lt;/code&gt; binary was not in the path. Hence you can see that I put the full path to get it to build. I tried to source the profile but didn’t work until I realised it was the wrong filename for the bash profile. I added the correct path and it is working now.&lt;/p&gt;

&lt;p&gt;I will now remove the last &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;source&lt;/code&gt; line and the commented out line. Wether I bother to replace the full path with a short path I dont know, maybe.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Terraform-version-1.png&quot; alt=&quot;Terraform-Version-1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Bottom line Terraform is now installed in my container, in a way which makes up upgrading easy in the future.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;Conor&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="GCP" /><summary type="html">Picking up from the end of the last post I needed to include my Git config inside my container so that I do not need to leave the container to use Git. I do this by mounting my .gitconfig file from my laptop into the container where it will be used while running in the container. This is how I get the right mix of disposability and persistence between my laptop and working container environment.</summary></entry><entry><title type="html">VS Code Tips</title><link href="https://conortolan.com/VS-Code-Tips/" rel="alternate" type="text/html" title="VS Code Tips" /><published>2022-11-12T08:56:31+00:00</published><updated>2022-11-12T08:56:31+00:00</updated><id>https://conortolan.com/VS-Code-Tips</id><content type="html" xml:base="https://conortolan.com/VS-Code-Tips/">&lt;p&gt;Quick post - this page might become a page of tips.&lt;/p&gt;

&lt;p&gt;In VS Code configure a shortcut to “Run Selected Text” in the active terminal.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/VScode-Tip-1.png&quot; alt=&quot;Tip Files 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;It is not configured by default and it is a top tip, I use it all the time. Specifically just now I was able to highlight my saved Docker run command in my permanent scratch file and run it. No thinking about what parameters I need or which mount points that are required.&lt;/p&gt;

&lt;p&gt;I’ll leave this at this for now and get back to the main post.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;Conor&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="GCP" /><summary type="html">Quick post - this page might become a page of tips.</summary></entry><entry><title type="html">Starting New Project 2022</title><link href="https://conortolan.com/Starting-New-Project-2022/" rel="alternate" type="text/html" title="Starting New Project 2022" /><published>2022-11-06T08:56:31+00:00</published><updated>2022-11-06T08:56:31+00:00</updated><id>https://conortolan.com/Starting-New-Project-2022</id><content type="html" xml:base="https://conortolan.com/Starting-New-Project-2022/">&lt;p&gt;Time to start a new project - frequently while at work after finishing a piece of work it strikes me that this would make a great blog post. While I can’t directly write about what I do at work, I realized I can spin up a similar project on my own time and not risk giving anything away. So here we are.&lt;/p&gt;

&lt;p&gt;I am starting now on my new laptop so I really have to start from scratch, took me longer than I wanted this morning just to get the first word. This is a Windows laptop so as you probably know it does not play as well with tech tools as you would think. Having to install and use Git bash just to get use Git, that’s crazy. Hard pass, my preferred approach is to containerize your tools. Create a working environment that you can jump into and always has the required tools.&lt;/p&gt;

&lt;p&gt;The benefit to this approach when working within a team is that once you are all on the same container you all get the same work experience. You get to move passed the problems or it working on your computer but not your colleagues.&lt;/p&gt;

&lt;p&gt;So I will start at the start. Let’s build a Centos container and start adding the tools that will be used. The process is really simple and worth learning if you have never tried before.&lt;/p&gt;

&lt;p&gt;Download and install Visual Studio Code and Docker Desktop if you are trying to follow along. I will admit I installed Git for Windows and was simply not happy with the experience. I played around with Windows Subsystem for Linux (WSL) but again not happy with the experience compared to working with my work Mac. I am not a Mac fanboy - I can’t argue that the cross compatibility with Linux tools though is powerful. Since most of the tech world runs on Linux, if you want to gain experience with the tools you need to be able to run them. This is why I will run a Linux container on my Windows laptop and I do the same on my work Mac.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/VScode-Files-1.png&quot; alt=&quot;Files 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Wherever you keep you files create a new fold, I call my “Code”. In this I create another folder “Docker_Images” because I want to keep all my docker build related files together (it makes relative path references easier). In this folder I create a file called Dockerfile.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/VScode-Auto-Save-1.png&quot; alt=&quot;Auto-Save 1&quot; /&gt;
If Visual Studio is a fresh install I recommend turning on “Auto Save” in the settings.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/Dockerfile-1.png&quot; alt=&quot;Dockerfile 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;This is the Docker file I created to get me going.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;FROM centos:7.9.2009

LABEL maintainer=&quot;CTolan@gmail.com&quot;
RUN yum update -y
RUN yum upgrade -y
RUN yum install epel-release -y
RUN yum install git -y
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Top line is declaring what base image to start form, this is likely going to be a security hardened image at work, but at home I will use the official image from &lt;a href=&quot;https://hub.docker.com/_/centos&quot;&gt;DockerHub&lt;/a&gt;. The label line is not required, but if you are going to do this in work it might be worth keeping for a point of contact. The RUN commands are literally commands that are run building the container the way I want. At this point I want to get Git working, I use Yum commands exactly like I would in a running Centos Virtual Machine. I guess a difference here is that it has to be zero touch, I can not type Y during the install process, I need to pass the “-y” parameter.&lt;/p&gt;

&lt;p&gt;The only real addition to this dockerfile versus the off the shelf official image is that I’m adding Git. Sure I could have just run the container &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;docker run --rm -it centos:7&lt;/code&gt; and then installed git manually, but the point here is to setup the processes that’ll add up to a much easier experience when things do get more complicated.&lt;/p&gt;

&lt;p&gt;Right so lets build this container. Oh another top tip is to create a permanent scratch file, I have one where I keep all my complex command lines. Working out the correct syntax can take a while, so I like to keep an example of the commands I use so I can quickly use them again in the future. Hence I’ll save this Docker build command.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Docker build -t mycontainer:local .
&amp;gt;&amp;gt;
[+] Building 2.1s (9/10)
 =&amp;gt; [internal] load build definition from Dockerfile
 =&amp;gt; =&amp;gt; transferring dockerfile: 247B
 =&amp;gt; [internal] load .dockerignore
 =&amp;gt; =&amp;gt; transferring context: 2B  
 =&amp;gt; [internal] load metadata for docker.io/library/centos:7.9.2009
 =&amp;gt; [1/5] FROM docker.io/library/centos:7.9.2009
 =&amp;gt; CACHED [2/5] RUN yum update -y  
 =&amp;gt; CACHED [3/5] RUN yum upgrade -y
 =&amp;gt; CACHED [4/5] RUN yum install epel-release -y
 =&amp;gt; CACHED [5/5] RUN yum install git -y  
 =&amp;gt; exporting to image 
 =&amp;gt; =&amp;gt; exporting layers
 =&amp;gt; =&amp;gt; naming to docker.io/library/mycontainer:local   
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;In the terminal of Visual Studio Code I navigate to my Docker_Image folder and could type &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Docker build .&lt;/code&gt;, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.&lt;/code&gt; denotes current directory (where Docker will find the Dockerfile). In my Docker build command I included &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-t mycontainer:local&lt;/code&gt; to tag the container after building it. I use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local&lt;/code&gt; to denote I built it locally versus pulled from a build job. I like to tag containers with the build pipeline number if build in Jenkins for example, others use the Git commit hash but I find it easier to find a container build log by Jenkins build number. It makes it easier to tell which build is newer.&lt;/p&gt;

&lt;p&gt;If you read the output you can see the RUN commands being executed exactly as they were written in the Dockerfile.&lt;/p&gt;

&lt;p&gt;Next I want to run the container and I want to do a few things at once. Looking at the last line of the build output you see the full reference of the container. So that is how I will reference it.&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt; docker run --rm --volume=&quot;C:\Users\me\Documents\Blog&quot;:&quot;/blog&quot; -it docker.io/library/mycontainer:local
 [root@139efa6104cc /]# cd blog/
 [root@139efa6104cc blog]# git version
 git version 1.8.3.1
 [root@139efa6104cc blog]#
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;ul&gt;
  &lt;li&gt;I want to remove the container when I exit so add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--rm&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;I want to have an interactive session in the container so add &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-it&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;I want to mount my laptop Blog or Code folder so I use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--volume=&quot;laptop_folder&quot;:&quot;mount_point_in_container&quot;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As mentioned I will save this command into my scratch file since I will use it all the time. It drops me into the container shell where I can cd to the blog folder which is in shared with my laptop blog folder. Any file already in this folder on my laptop will be available in the container, and any files created or edited in the container folder will be available on my laptop.&lt;/p&gt;

&lt;p&gt;The first step I took was to clone down my github blog repository, so I could start writing this post, so if you are reading this, then it worked. There is more I wanted to get to today - I haven’t even started on the Terraform side of things, but this process is foundational to that work so it is important to get it setup on this new laptop. I might re-write this into a proper project description and a separate container setup article but I needed to get Git working first.&lt;/p&gt;

&lt;p&gt;P.S. of course I forgot a couple of steps. I didn’t mount my gitconfig (I don’t have one on this laptop) so my git push didn’t work, I really am starting from scratch. Ugh I really want to publish this so I might have to use git bash after all.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;Conor&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="GCP" /><summary type="html">Time to start a new project - frequently while at work after finishing a piece of work it strikes me that this would make a great blog post. While I can’t directly write about what I do at work, I realized I can spin up a similar project on my own time and not risk giving anything away. So here we are.</summary></entry><entry><title type="html">Monkey Bars Complete</title><link href="https://conortolan.com/Monkey-Bar-Project-Finished/" rel="alternate" type="text/html" title="Monkey Bars Complete" /><published>2021-06-07T08:56:31+00:00</published><updated>2021-06-07T08:56:31+00:00</updated><id>https://conortolan.com/Monkey-Bar-Project-Finished</id><content type="html" xml:base="https://conortolan.com/Monkey-Bar-Project-Finished/">&lt;p&gt;Finally I took the time to do a post on the completed monkey bar project. I am very happy with how it worked out. I learned a lot and got to use other skills that I don’t usually get to in my day job.
&lt;img src=&quot;https://conortolan.com/images/20210606_192600.png&quot; alt=&quot;Monkey bars 1&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/MonkeyBars.PNG&quot; alt=&quot;Monkey Bars image&quot; /&gt;
Compared to the orignal design I think I nailed it. I didn’t do the ladder of bars up between the pillars yet, I need to find a good way to accomplish it. So instead I tied them together with the step. The hammock was a great surprise pay off.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/20210606_192542.png&quot; alt=&quot;Monkey bars 2&quot; /&gt;
There was a bit in this for me, on the far end is a pull up bar where my feet don’t touch the ground. I am able to hang freely and I’m working on my pull ups. Note that the kids also get to use the bands as a bungee swing - it looks like great fun.&lt;/p&gt;

&lt;p&gt;Thanks for reading.
Conor&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="MonkeyBars" /><summary type="html">Finally I took the time to do a post on the completed monkey bar project. I am very happy with how it worked out. I learned a lot and got to use other skills that I don’t usually get to in my day job.</summary></entry><entry><title type="html">Day 2 vCenter Time</title><link href="https://conortolan.com/Day-2-vCenter-Time/" rel="alternate" type="text/html" title="Day 2 vCenter Time" /><published>2020-10-15T08:56:31+00:00</published><updated>2020-10-15T08:56:31+00:00</updated><id>https://conortolan.com/Day-2-vCenter-Time</id><content type="html" xml:base="https://conortolan.com/Day-2-vCenter-Time/">&lt;p&gt;As I had hoped it was actually quiet easy to get the vCenter installed and I did infact know what I was doing, mostly. I knew I’d need to get an ISO from VMware for the VCSA, I downloaded that and created a VM before having created a datastore. This is something I’ve really apreciated about the build, all the parts work out of the box. My thanks to those who have gone before and figured all this out. Hat tip to VMware and Intel for making it happen on the product side, so take my money.
&lt;img src=&quot;https://conortolan.com/images/add-host-to-vc-3.JPG&quot; alt=&quot;NUC Homelab image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/New-datastore.JPG&quot; alt=&quot;Datastore creation image&quot; /&gt;
&lt;img src=&quot;https://conortolan.com/images/New-datastore-2.JPG&quot; alt=&quot;Datastore created image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Datastore created, I figure 500GB would be enough. Next I went down the wrong path of copying the ISO to the datastore and then I created a new VM and tried to mounth the VCSA ISO. The VM didn’t boot, that’s not what I should be doing. After a bit of documentation reading I realised that I needed to mounth the VCSA ISO locally on my laptop and then open up either CLI installer or the GUI installer. I went with the GUI this time. Ran into a this error when clicking through the setup, its these little things, I didn’t know that for a production setup I’d need a full 500GB minimum for the VCSA. That could be trip up question in an exam for sure. It’d seperate those experienced installing vCenter from those who aren’t.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/deploy-vcenter-1.JPG&quot; alt=&quot;Datastore created image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;No big deal for my homelab to go with thin provisioning, so no issue. So we’re off with step one, deploying the vCenter VM to the homelab. Then step two configuring the vCenter appliance and then done. It is deployed and configured with an SSO domain and the config that I suplied via the GUI. Nothing exciting so I’ll not go into detail.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/deploy-vcenter-4.JPG&quot; alt=&quot;Install Stage 1 image&quot; /&gt;
&lt;img src=&quot;https://conortolan.com/images/deploy-vcenter-5.JPG&quot; alt=&quot;Install Stage 2 image&quot; /&gt;
&lt;img src=&quot;https://conortolan.com/images/deploy-vcenter-6.JPG&quot; alt=&quot;Install Stage 2 Complete image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;What I love about this is that the vCenter has no awareness of its host or the platform on which is runs. I have my own vCenter now running with no hosts and it has no idea that it is even a vitual machine. In one company we had many vCenters all run in the production environment for the other enviroments (not nested but same idea). The vCenter really is a control plane for the underlying compute layer where the VMs will exist and they are seperated. Sure you might lose all your visability into your environment if you lose your vCenter but you can always answer honestly that there will be no impact to the running workloads when asked in CAB. Logically then next step is to add the host to the vCenter.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/deploy-vcenter-7.JPG&quot; alt=&quot;Empty vCenter image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Whenever we do this we automate it and so I am enjoying the nuts and bolts feels of having to add this host myself, but it trust me you never want to have to do this for racks and racks of hardware. Maybe this is my appreciation for a handcrafted artifact when I know full well that our society relies on the success of mass production to sustain our world of abundance.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://conortolan.com/images/add-host-to-vc-2.JPG&quot; alt=&quot;Adding the host image&quot; /&gt;
&lt;img src=&quot;https://conortolan.com/images/add-host-to-vc-3.JPG&quot; alt=&quot;NUC Host in vCenter image&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Ohh now it is looking far more familiar, this is the view point I’ve spend way too much of my career. Not entirely sure what I need to do next, I clearly have some patching ahead of me. Ooh maybe I can play with the new Lifecycle Management features of vSphere 7. From what I saw at VMworld this is finally bringing all the pieces together and automated.&lt;/p&gt;

&lt;p&gt;Thanks for reading.
Conor&lt;/p&gt;</content><author><name>{&quot;twitter&quot;=&gt;&quot;ConorT&quot;}</name></author><category term="HomeLab" /><summary type="html">As I had hoped it was actually quiet easy to get the vCenter installed and I did infact know what I was doing, mostly. I knew I’d need to get an ISO from VMware for the VCSA, I downloaded that and created a VM before having created a datastore. This is something I’ve really apreciated about the build, all the parts work out of the box. My thanks to those who have gone before and figured all this out. Hat tip to VMware and Intel for making it happen on the product side, so take my money.</summary></entry></feed>