<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Joel Jean-Claude on Medium]]></title>
        <description><![CDATA[Stories by Joel Jean-Claude on Medium]]></description>
        <link>https://medium.com/@joeljean-claude?source=rss-5ac96a65f994------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*TPrac8FmGTkxNmg_3n7VXg.png</url>
            <title>Stories by Joel Jean-Claude on Medium</title>
            <link>https://medium.com/@joeljean-claude?source=rss-5ac96a65f994------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 23 May 2026 16:03:30 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@joeljean-claude/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Deployment of Cloud Load Balancing between Regions in the USA and Europe for global high…]]></title>
            <link>https://medium.com/@joeljean-claude/deployment-of-cloud-load-balancing-between-regions-in-the-usa-and-europe-for-global-high-8d479fc89c68?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/8d479fc89c68</guid>
            <category><![CDATA[gcp-load-balancer]]></category>
            <category><![CDATA[gcloud-commands]]></category>
            <category><![CDATA[google-cloud-run]]></category>
            <category><![CDATA[docker]]></category>
            <category><![CDATA[google-artifact-registry]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Sun, 08 Mar 2026 14:16:47 GMT</pubDate>
            <atom:updated>2026-03-08T14:16:47.280Z</atom:updated>
            <content:encoded><![CDATA[<h3>Deployment of Cloud Load Balancing between Regions in the USA and Europe for global high availability and intelligent traffic distribution based on user proximity and location</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jclI8rTzNYQiVKSXOkdusg.png" /></figure><p>In this project based on a real-world scenario, I acted as a Cloud Specialist to implement a solution to handle incoming traffic accessing the main page of an application available in 2 regions: Finland and United States.<br> <br> The prerequisites established were to create a 100% Serverless architecture with high global availability, present in two distinct continents so that, in case a Failover is needed from one continent to the other, the application in Production running on the Cloud Run service and stored in Containers is always available.<br> <br> In addition, to distribute traffic intelligently and based on the proximity and location of the end user, once the client requests access he will be directed to the home page that is geographically closest.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a1-2cU7JlEismttCWMbTug.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/999/1*cmd4iEkYM3_ckU906pHtSQ.png" /><figcaption><strong>Figure 1</strong> — Application files staged for both regions</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YXZtIsyBybTrSwbGdjWu_A.png" /><figcaption><strong>Figure 2</strong> — Application build started for primary region</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4nQt0QCrPwh8gCC0oWAl0g.png" /><figcaption><strong>Figure 3 </strong>— Application build complete for primary region</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8Dy9xrxMoyDQRxBc-sYJtg.png" /><figcaption><strong>Figure 4</strong> — Application image hosted in Artifact Registry</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2QmNTHujByJ9mYlPy1khMw.png" /><figcaption><strong>Figure 5 </strong>— Application build started for secondary region</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ecKYkvsi0UBPoAXAFwUssw.png" /><figcaption><strong>Figure 6</strong> — Application build complete for secondary region</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jFvwpwxU2ECX_shPG8LwUQ.png" /><figcaption><strong>Figure 7</strong> — Application image hosted in Artifact Registry</figcaption></figure><p>Using the <em>gcloud</em> CLI, the application has been implemented as a docker image. The Google Cloud Run service will then automatically push the docker images to a new Artifact Registry in Google Cloud. Although the images are hosted in a US region, they are available for use in any region worldwide. We can proceed now to deploy the primary instance of the application</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*M0xuYJsuObkPdmYV3R7Niw.png" /><figcaption><strong>Figure 8</strong> — Start of application deployment, region selection</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9IX4ryZ420gBunGiLJygWQ.png" /><figcaption><strong>Figure 9</strong> — Application deployment in primary instance, region selection</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*H9EL5q-KeoPZPw7fMaXAQA.png" /><figcaption><strong>Figure 10</strong> — Application deployment complete in EU North region</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*hoDSOwDH7Re-f36hzH06OA.png" /><figcaption><strong>Figure 11</strong>- Application deployment started for secondary instance</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pPEN-qvW56Ca5nXw3hQIcQ.png" /><figcaption><strong>Figure 12</strong> — Application deployment complete in US Region</figcaption></figure><p>The application is now running in containers in both EU and US regions. Each one is associated with its own URL.</p><p>Primary — <a href="https://appkidsflixfinland-910998002388.eu-north2.run.app">https://appkidsflixfinland-910998002388.eu-north2.run.app</a></p><p>Secondary — <a href="https://appkidsflixusa-910998002388.us-central1.run.app">https://appkidsflixusa-910998002388.us-central1.run.app</a></p><p>The application is a media site similar to Netflix, called KidsFlix. It will provide content tailored for children based in different regions.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mk-ByXB3cxhkhMzP0UYaqQ.png" /><figcaption><strong>Figure 13</strong> — Frontend for primary instance</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e_rdNHRz90iaLnOn4xtV8Q.png" /><figcaption><strong>Figure 14</strong> — Region marker for primary instance</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zNPsDelokThFpvnwyeXJjg.png" /><figcaption><strong>Figure 15</strong> — Frontend for secondary instance</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8JqUCoOmZ0BD5APCTBprlw.png" /><figcaption><strong>Figure 16</strong> — Region marker for secondary instance</figcaption></figure><p>With both instances up and running. Next step is to deploy a load balancer to handle the incoming requests. The load balancer should redirect requests to the instance closest to the client. This way, requests are served with the lowest latency possible. The routing should be based on geographical proximity to the load balancer.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qlSrkHhU9_Qp64C5PyPkkg.png" /><figcaption><strong>Figure 17</strong> — Network Endpoint Group creation for primary instance</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WTg0bW-5RvzKjpFRbZwGVw.png" /><figcaption><strong>Figure 18</strong> — Network Endpoint Group creation for secondary instance</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aL6VIOmYmw0dWvz-BdL6uA.png" /><figcaption><strong>Figure 19</strong> — Network Endpoint Groups</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*F0IuDuHoqx7Wyd5xu-6iqg.png" /><figcaption><strong>Figure 20</strong> — Backend creation, primary instance</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FiWbrM9eDZkAfZmE2ZY2zA.png" /><figcaption><strong>Figure 21</strong> — Backend association to network endpoint group</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YeSGGJrrY6BPbAjeZSxq5Q.png" /><figcaption><strong>Figure 22 </strong>- URL Mapping to load balancing service</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*59vEhhfAnrjzqqGtVscDuQ.png" /><figcaption><strong>Figure 23</strong> — Load balancing configuration</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*STJfpxAY5LCPdWVdruVRag.png" /><figcaption><strong>Figure 24</strong> — Load balancer up and running</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AhUlUpPraAGwTb_Lv-kqUw.png" /><figcaption><strong>Figure 25</strong> — Load balancer backend services</figcaption></figure><p>The load balancer is set up to serve requests. To properly test this out, there are two general options</p><p>Single user — One person can use a proxy of some sort to forward requests in such a way that the load balancer will redirect it to the specific region.</p><p>Multiple users — Different people that are within each region can initiate requests to the load balancer.</p><p>This article will reference the results for the first one.</p><p>A VPN tunnel was used to forward the request to the EU region to simulate a client in that area, so that the primary instance would be served back to the client. Browsers like Opera, provide this capability out of the box. See below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/417/1*JcSHAAULHLh7EJueuSdOTQ.png" /><figcaption><strong>Figure 26</strong> — VPN Extension for Opera web browser</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/890/1*x2BRSXIWlin-ez7KiRDgXQ.png" /><figcaption><strong>Figure 27</strong> — Application access through load balancer, primary instance</figcaption></figure><p>Here you can see that from the US, I was able to reach the instance in Europe.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mfwpMSkuh1tvWkDfLatPpQ.png" /><figcaption><strong>Figure 28</strong> — Application access through load balancer, secondary instance</figcaption></figure><p>To test access to the other instance, it is just a matter of disabling the VPN connection. Since I am already located in the US, the request was forwarded to the US instance.</p><p>This article was a demonstration of the Google Cloud Run service. A simple web application was containerized and deployed in two separate regions. A load balancer was deployed to provide routing of requests to the two instances. Due to the nature of the application, the routing was designed to forward requests based on geographical location. The application contains content tailored for users that reside in the configured regions.</p><p>For other use cases, load balancers are used to provide fault tolerance in the event that the primary instance becomes unresponsive. There are different operating modes for the failover</p><ul><li>Active-Active — Both instances are up and running</li><li>Active-Standby — Primary instance is running and serving requests, while the standby instance is online, but is not open to requests</li></ul><p>This was a project showcasing the ability to deploy an application through a managed service with Google Cloud Run. Additionally, it leveraged a multi-region deployment with the use of an application load balancer. The Google Cloud Run service will create a docker image, and host it in an registry automatically, preparing it for deployment.</p><p>This project demonstrated extended use of <em>gcloud</em> CLI, which performs the same steps that could be done in the Google Cloud console. This method of configuration lends itself to automation, which can provide the ability to deploy multiple instances of this application stack with consistency. Additionally, the code can be added to version control, to help with on-going maintenance.</p><p>Lastly, this project showcased the load balancing service. This enabled the ability to respond to requests based on geographical location. For this use case, its main purpose was to redirect users to content tailored for them. For others, it can provide fault tolerance with a similar configuration.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=8d479fc89c68" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deployment of a Web Application to automate talent onboarding using HTML / CSS / JS / BS…]]></title>
            <link>https://medium.com/@joeljean-claude/deployment-of-a-web-application-to-automate-talent-onboarding-using-html-css-js-bs-fdf6f172dae0?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/fdf6f172dae0</guid>
            <category><![CDATA[python]]></category>
            <category><![CDATA[html5]]></category>
            <category><![CDATA[moodle]]></category>
            <category><![CDATA[google-storage]]></category>
            <category><![CDATA[google-cloud-functions]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Thu, 05 Mar 2026 01:01:00 GMT</pubDate>
            <atom:updated>2026-03-05T01:01:00.687Z</atom:updated>
            <content:encoded><![CDATA[<h3>Deployment of a Web Application to automate talent onboarding using HTML / CSS / JS / BS (Front-end) + Python Flask (Back-end) with Cloud Storage and Cloud Functions 100% Serverless — Part 2</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*DbVsaeqlTz83GEizm2M8tw.png" /><figcaption><strong>Figure 1</strong> — Overview: GCP Functions, Python runtime, frontend using Node and HTML5</figcaption></figure><p>In this project based on a real-world scenario, I acted as a Cloud Expert in the deployment of a Web Application to automate the HR onboarding process. By filling out a form, the user is created in the Training Portal in a fully automated way.<br> <br> To deploy this solution, I used a Moodle image available on GCP Marketplace, where the REST API had been enabled, running on Compute Engine, front-end on Cloud Storage, and the back-end on Cloud Run.<br> <br> I deployed the back-end using Python Flask using Cloud Functions, 100% Serverless. Then, I deployed the front-end using HTML/CSS/JS/BS on Cloud Storage to store the static files of the Web Application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*EqdutnDB5oErljrWUXclmA.png" /><figcaption><strong>Figure 2</strong> — Architecture Diagram</figcaption></figure><p>This is the second portion of the Moodle project. As a base, it currently has a home page that all employees will see, and one course. In this section, you will see further customization of the Moodle app to add a backend implemented as a serverless function, along with a separate frontend that will be accessed by a course administrator. As a reminder, in this scenario, the Moodle application will be used as a training system at a company.</p><p>We’ll start with the backend. It will be a new webservice in Moodle</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NcWYojLI7-Ov3yqW0Upp4g.png" /><figcaption><strong>Figure 3 </strong>— New webservice</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rEP_7c1Y9s-b4X-OXsjNUQ.png" /><figcaption><strong>Figure 4</strong> — New webservice enabled</figcaption></figure><p>Next, a protocol is selected to enable API access</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*g1ah3waiYD_fgPdQunHuRg.png" /><figcaption><strong>Figure 5 </strong>— Configuration of API</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-jRuSOk19kSveA8XfDetnA.png" /><figcaption><strong>Figure 6</strong> — Enabled API access</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*V3pwV-h8-UR1W9hLCLQirg.png" /><figcaption><strong>Figure 7 </strong>— Custom services</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oU-5hUYzBPwmYcQlnXYzlA.png" /><figcaption><strong>Figure 8</strong> — Custom service configuration</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*evwMu5BAuWkcEXRA9ty9Ag.png" /><figcaption><strong>Figure 9 </strong>— Custom webservice fully configured</figcaption></figure><p>The webservice is set up to be integrated with a serverless function.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3qQnMo4wGTtRy-X9XDTjNg.png" /><figcaption><strong>Figure 10</strong> — Webservice association to operation for user creation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Nl505ETd-yaa59_1qJdDBw.png" /><figcaption><strong>Figure 11</strong> — Webservice operation selected</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Nl505ETd-yaa59_1qJdDBw.png" /><figcaption><strong>Figure 12 </strong>— Webservice configured</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NAOxWrQ8IYDk6w4kgc6WKQ.png" /><figcaption><strong>Figure 13</strong> — User association for webservice</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*i_w04LTBaxPl8U_0b0P6Cg.png" /><figcaption><strong>Figure 14</strong> — Admin user associated to webservice</figcaption></figure><p>As a best practice, it is proper to set a webservice to be controlled by designated user account. This prevents unauthorized access by malicious actors and protect the backend of the Moodle application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YpxB80_xfadJBgh_45ktsA.png" /><figcaption><strong>Figure 15</strong> — Access token creation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*HvhVlvQa64dxxp_JMpBQ9g.png" /><figcaption><strong>Figure 16 </strong>— Token configuration</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3q0SrfSErRPBCq0i4jRKhg.png" /><figcaption><strong>Figure 17</strong> — Token confirmation</figcaption></figure><p>As with any user account, a password is set to secure it. For production environments, there are two schools of thought;</p><ul><li>Set an expiration date for the access key. This is for security purposes to prevent malware from retaining access to production resources. Risk is that production workloads can be disrupted if someone forgets to rotate the token</li><li>Not setting an expiration, and having an external tool or other automation perform the token rotation. This usually means a secondary account would be created to perform the token rotation on the first. This would spread the risk of compromise across two accounts, and add maintenance overhead.</li></ul><p>I went with the expiration route, as this is what I’ve done in the past.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mn80fezhuIhZKsOlcBsE5g.png" /><figcaption><strong>Figure 18 </strong>— Validating API call with the access token</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OvLyEUJG7zU8fg1OxRk8Mg.png" /><figcaption><strong>Figure 19</strong> — Validation API call: User creation successful</figcaption></figure><p>The webservice was successfully created. To validate it, an API call was triggered from the GCP Cloud Shell using <em>curl</em> against the endpoint.</p><p>With this in place, now we can proceed to implement the next component of the backend. A serverless function to call the same endpoint that was just validated, using a python script.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oBqxnLd80Awjeul1SOfzOw.png" /><figcaption><strong>Figure 20</strong> — Function configuration</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*WpW3R7GgbPT8fVUWo2QDHA.png" /><figcaption><strong>Figure 21</strong> — Environment variables to store the Moodle server IP and the access token</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8lpmYVYPEr3VHF1Qc3rFoQ.png" /><figcaption><strong>Figure 22 </strong>— Function deployed</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oDLKazNElaCCxaOtN5FBHA.png" /><figcaption><strong>Figure 23</strong> — Function logs</figcaption></figure><p>The serverless function was created successfully, <em>moodleusercreate</em>. As of this writing, this service got migrated to the Cloud Run service. This is function considered to be Generation 2 (aka ‘Gen 2’). Legacy functions that were created before the move are Generation 1 (aka ‘Gen 1’). Logs show the function being deployed.</p><p>The function is assigned a URL that will be used to pass an incoming request, and process the operation defined the python code. In this case, the code is going to call the API endpoint to create a new user.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PGaEP6675Hh6l9qgXNGqIQ.png" /><figcaption><strong>Figure 24</strong> — Function triggered</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Fl6qXJoYReJ8iQJD0LoUsw.png" /><figcaption><strong>Figure 25</strong> — Function logs</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5zF3rQVVifYnyKVb5vmpTg.png" /><figcaption><strong>Figure 26</strong> — Function validation</figcaption></figure><p>You now see a successful trigger of the function. This was done via the GCP cloud shell, using the curl command. The logs show how the function was called, and what the response was (200 — success). In the cloud shell the response was a human-readable message. In this case, since the operation was obvious, creating a new user, this would have been enough to confirm the API worked properly. The logs show additional detail, in this case, the data that was added to the database</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*kHZpjPZw4oClLgxaiF1JqA.png" /><figcaption><strong>Figure 27</strong> — Function validation: parameters set in GCP serverless function referenced in python code</figcaption></figure><p>In the image above, you see a portion of the python code that makes up the core of the serverless function. The main pieces to take note of here is the following:</p><ul><li>Python function that takes in a person’s name and email address as parameters</li><li>Python code retrieves the environment variables from GCP to retrieve the access token and IP address to establish a connection to the server</li><li>Python code triggers the serverless function, and passes the inputs to the API endpoint (user name and email)</li></ul><p>With the serverless function fully established, the next step is to add the secondary frontend for use by the HR administrator. The main purpose is to enable an HR admin to register new hires to the training system. This way, the user has access to training materials necessary to get fully onboarded.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5Cjp3pV72CvCVSEFnJicZQ.png" /><figcaption><strong>Figure 28</strong> — GCP cloud shell session. Using gsutil to create a new bucket and uploading files</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IN8jED8BoCvifJ4aRJU9mA.png" /><figcaption><strong>Figure 29 </strong>— GCP Console. Reviewing contents of the new storage bucket</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BaPYY7iGsShws0BY7V7YTA.png" /><figcaption><strong>Figure 30 </strong>— Configuring IAM settings to bucket and files</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yz4vhmpJnt2oNobHcq6ABg.png" /><figcaption><strong>Figure 31</strong> — Overview of the index.html file</figcaption></figure><p>At this point, the frontend service is fully configured. This is essentially a static website based on a cloud storage bucket. This website will integrate with the Moodle application. Trainees would log in (once they’ve been registered) and select courses to complete. This front end would trigger the same serverless function that was set up in the previous section.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*aa3Rk0YKVsqcM7O7_Dg9xw.png" /><figcaption><strong>Figure 32</strong> — Static website homepage</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ORDcQ3zL9MKHd35lS2i0Ew.png" /><figcaption><strong>Figure 33</strong> — Static website homepage. Title display</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1WaOtOZz8GO6AvGVWzXTHA.png" /><figcaption><strong>Figure 34</strong> — Cross-referencing public URL with the display shown in the web browser</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8qivQF85zN1-NbFrGknJpA.png" /><figcaption><strong>Figure 35</strong> — New user registration</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0Mn2TMzCp4RGhXKh3O1SEA.png" /><figcaption><strong>Figure 36</strong> — Successful user registration</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NtLfABwOLK-cJXTzz4rsBg.png" /><figcaption><strong>Figure 37 </strong>— New user validation in the Admin panel of Moodle app</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*u6z2Ju2-5fPq1jAMyziZEA.png" /><figcaption><strong>Figure 38</strong> — New user validation in the logs for the serverless function</figcaption></figure><p>Now, the system is fully implemented:</p><ol><li>Moodle application deployed from the Marketplace</li><li>Moodle application customized with company logos, course added, and backend services</li><li>Moodle application integrated with a GCP serverless function</li><li>Moodle application extended with another integration to cloud storage bucket</li></ol><p>This is an example of a cloud-native application that provides a training portal to a company to assist in onboarding new employees. For what was implemented here, courses administrator would create courses that employees can use, and an HR administrator is able to register users in a frontend. Once they confirm their access, the employees would log in to the portal would browse the course library and complete the sections relevant to their role.</p><p>To expand the scenario further, course administrators would maintain, and update courses on the Moodle app to ensure that the content stays relevant and useful for the trainees.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fdf6f172dae0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deployment of Corporate Training Portal on Google Cloud Platform using Deployment Manager, Google…]]></title>
            <link>https://medium.com/@joeljean-claude/deployment-of-corporate-training-portal-on-google-cloud-platform-using-deployment-manager-google-6954b44ac1e8?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/6954b44ac1e8</guid>
            <category><![CDATA[gcp-compute-engine]]></category>
            <category><![CDATA[gcp-storage]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[moodle]]></category>
            <category><![CDATA[google-deployment-manager]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Sat, 28 Feb 2026 18:34:34 GMT</pubDate>
            <atom:updated>2026-02-28T18:34:34.568Z</atom:updated>
            <content:encoded><![CDATA[<h3><strong>Deployment of Corporate Training Portal on Google Cloud Platform using Deployment Manager, Google Compute Engine &amp; Cloud Storage — Part 1</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bUz7YLnvGcdlz0XkSiRXlg.png" /><figcaption><strong>Figure 1 </strong>— Project Overview: GCP Deployment Manager, Compute Engine, Cloud Storage and Moodle application</figcaption></figure><p>In another real-world based project, I acted as a Cloud Specialist to implement a corporate training portal for employees. Moodle was the platform chosen to provide the training, and it’s one of the most popular e-Learning platforms among companies and universities around the world.<br> <br> We used the Deployment Manager and a Moodle image, available on GCP Marketplace, using the resources of a Compute Engine. To store the training files, in order to comply with high availability (HA) issues, we used the Cloud Storage bucket service.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ZwAOuBMBVgXP-sNYa8ijeA.png" /><figcaption><strong>Figure 2</strong> — System Architecture</figcaption></figure><p>It all starts in the Marketplace. This is an area where you can get third party application packages, or standalone OS images with specific customizations. Some examples are:</p><ul><li>Wordpress</li><li>Apache Web Server</li><li>RedHat Linux</li><li>SUSE OpenLeap</li><li>NVIDIA Enterprise Workstation</li></ul><p>Many of what you will find in the Marketplace is free to use, but there’s also plenty licensed content. The license information will be described in the Pricing tab.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/958/1*Fw11h0hh-3JfxOw_9K5vdg.png" /><figcaption><strong>Figure 3</strong> — Moodle Marketplace image</figcaption></figure><p>This example uses a paid application package called Moodle, a popular online courseware platform. This is an example of the traditional LAMP stack, <strong>L</strong>inux <strong>A</strong>pache <strong>M</strong>ySql and <strong>P</strong>HP.</p><p>The specific image that will be used for this project will leverage a GCP service called Deployment Manager. It is a system that uses infrastructure as code to deploy resources in the cloud environment.</p><p>Separately, if you are doing something like this for the first time in your account, bear in mind that a billing account is required (few simple steps). A prompt will appear to provide a place where that can be created. Additionally, an API will also need to be enabled for the Deployment Manager service (one step).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AZOe_Skuaqu7aNApZjGs9w.png" /><figcaption><strong>Figure 4</strong> — Moodle app deployment process</figcaption></figure><p>By clicking the Launch button, the deployment process kicks off. Under the hood, a template is being deployed that sets up a compute instance that includes the Moodle application stack. This will be initialized in the Deployment Manager service.</p><p>As of this writing, this service will be deprecated in March of 2026. The replacement service is called Infrastructure Manager.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GdOxJjnrjihCgbYunGIFxg.png" /><figcaption><strong>Figure 5</strong> — Moodle deployment details</figcaption></figure><p>Once the application is deployed, the details tab will contain the information necessary to configure the application. Some of the settings include</p><ul><li>Server IP address</li><li>Database credentials</li><li>Application administrator credentials</li><li>Application URL</li><li>Instance Size</li><li>etc</li></ul><p>Before proceeding to customize the application, some of the content needs to be staged. A storage bucket is created and set up to enable the Moodle application to connect to it and load content to the web frontend.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dX6C-GgtqhyXJ3Kh6gH3vA.png" /><figcaption><strong>Figure 6 </strong>— GCP Storage bucket, and files</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5azGtQND_j4d0BWE7Zs8WA.png" /><figcaption><strong>Figure 8</strong> — Access configuration for the content used in the Moodle application</figcaption></figure><p>The storage bucket is ready to host the media content. The storage bucket enables public access so that Moodle users are able to see the content that is configured for the course that will be configured shortly. Files have been staged, and also exposed for public consumption. In GCP, the ‘allUsers’ option will enable public access to the objects in a storage bucket.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jPeDUewMt58d21ppZJe_Sw.png" /><figcaption><strong>Figure 9</strong> — Moodle application with one course added</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NBeZt2DvOa-eG0c1uUNJvw.png" /><figcaption><strong>Figure 10 </strong>— Course content customization</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*TFQ_SK0jf8bay6E-Xpg7ZQ.png" /><figcaption><strong>Figure 11</strong> — Course setup complete</figcaption></figure><p>To set up the course the following steps were completed:</p><ol><li>Add a new course</li><li>Customized the course to have the following (Site administration → Courses → Add a new course)<br>- Title of ‘Introduction’<br>- Use the iLearn logo<br>- Display a greeting video animation<br>- Provide a download link to a PDF document</li><li>Add a new home page (Site administration → General → Site home → Site home settings)<br>- Site Name ‘Corporate Training Portal’<br>- Short name ‘iLearn’<br>- Site home summary ‘iLearn — Corporate Training Portal’</li></ol><p>Step 2 involved setting references to the files stored in the storage bucket (2.3 and 2.4).</p><p>This was a walkthrough of a deployment of marketplace content in a Google Cloud project. This scenario leverages several cloud services like Compute Engine, Storage buckets, and the Deployment Manager (soon to be replaced by Infrastructure Manager). This application will be extended to use Cloud Functions, and other GCP tools to enable the ability to use automation to perform routine tasks, like onboarding new users to the Moodle platform.</p><p>Stay tuned for the next part of the two-part series. Thank you</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6954b44ac1e8" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Automation Using Python on Google Cloud — IAM Service Accounts]]></title>
            <link>https://medium.com/@joeljean-claude/automation-using-python-on-google-cloud-iam-service-accounts-864705985791?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/864705985791</guid>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[python]]></category>
            <category><![CDATA[gcp-iam]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Tue, 10 Feb 2026 01:56:01 GMT</pubDate>
            <atom:updated>2026-02-10T01:56:01.186Z</atom:updated>
            <content:encoded><![CDATA[<h3><strong>Automation Using Python on Google Cloud — IAM Service Accounts</strong></h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RfNXWkLFnncEYV6HEg824g.png" /></figure><p>In this real-world based project, I acted as a Cloud Specialist and used IAM services to create a Service Account. This service account allowed communication via scripts within the architecture through Cloud SDK and Python Scripts.<strong><br> <br> </strong>To have it deployed, I had to:</p><ul><li>Set up a Python environment on your local machine.</li><li>Install and configure the Google Cloud SDK.</li><li>Create and manage IAM service accounts.</li><li>Automate storage operations using Python scripts.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-GtXpq65JVCRAnaQyXsw6w.png" /></figure><h3>1. Python Installation</h3><p>Python is a versatile programming language widely used for scripting and automation tasks. I am using a Mac mini for this project, so I used brew to install the packages</p><p><em>brew install python</em></p><p>I had version 3.14 and pip 25. I then set up a virtual environment for use with the script that I will be staging shortly</p><h3>2. Google Cloud SDK</h3><p>Installed the gcloud CLI on my machine. Reference: <a href="https://docs.cloud.google.com/sdk/docs/install-sdk#mac">https://docs.cloud.google.com/sdk/docs/install-sdk#mac</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/279/1*OLReiz_E9_QhGF2uSW7W5g.png" /><figcaption>GCloud CLI Installed</figcaption></figure><h3>3. Create IAM Service Account</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PXhR8EUbwrZnkTpWJLTGfw.png" /><figcaption>GCP IAM: Service Account</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*UBSGA7IIMgvhwcESYDCPfg.png" /><figcaption>GCP IAM: Service Account Key</figcaption></figure><h3>4. Stage Python Script</h3><p>This script requires the use of the storage library from the GCP repository. This will be installed</p><p><em>pip3 install –upgrade google-cloud-storage</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qk3U0EwVBvfRWOy2obmNlw.png" /><figcaption>Python Pip: GCP Cloud Storage module installed</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/995/1*tFd80zV9mO4Cu0Wzxkt4Kg.png" /><figcaption>Python script staged</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/638/1*SgzfUkHaX-HWJhEEMO3zyA.png" /><figcaption>Contents of python script</figcaption></figure><h3>5. Execute Python Script</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*e6fyJYcqETlRE60xRurVkw.png" /><figcaption>Execution of python script</figcaption></figure><p>Running the python script successfully retrieves the list of buckets that exist in the cloud account.</p><h3>Conclusion</h3><p>This was a walkthrough of the GCP IAM Service. In this article, a service account was created to perform an automated task. This involved setting up a Python environment, installed necessary tools and libraries, created an IAM service account, download its key, and executed a sample script to interact with Google Cloud Storage. This process forms the foundation for automating various tasks on Google Cloud using Python.</p><p>This script will now enable more advanced automation workflows, such as uploading, downloading, and managing Cloud Storage objects programmatically. By adding additional permissions, other services can be leveraged with this python script</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=864705985791" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Migration of Intercontinental VM (USA Region > Australia Region) using Storage Snapshot through…]]></title>
            <link>https://medium.com/@joeljean-claude/migration-of-intercontinental-vm-usa-region-australia-region-using-storage-snapshot-through-15836a6bff75?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/15836a6bff75</guid>
            <category><![CDATA[gcp-compute-engine]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[gcp-storage]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Sun, 08 Feb 2026 18:20:17 GMT</pubDate>
            <atom:updated>2026-02-08T18:20:17.066Z</atom:updated>
            <content:encoded><![CDATA[<h3>Migration of Intercontinental VM (USA Region &gt; Australia Region) using Storage Snapshot through Google Cloud Internal Private Network in less than 30 minutes</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*xKNRFS2XvaF_x5z1Z-OFIg.png" /><figcaption>GCP Server migration to new region</figcaption></figure><p>In this real-world based project, I acted as a Cloud Specialist in a project to migrate application and database into an intercontinental (US → Australia Region) in a fully private way using Google Cloud infrastructure.</p><p>The application being migrated is a patient registration application of a large US clinic. It is a 2-tier application stack with a NodeJS frontend and a MySQL database for the backend. This migration will leverage the private network backbone of GCP together with the Storage service; specifically, VM snapshots.<br> <br> The objective was to create disk snapshots, new disks in Australia region, provision new instances, and achieve a successful migration in a secure and fast manner.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3uJcUDnmCAKSt8i9Tioofw.png" /><figcaption>Map of GCP datacenters around the world</figcaption></figure><p><em>Baseline</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RoA678deE6gecesh6QVAmQ.png" /><figcaption><strong><em>Figure 1</em></strong><em>: Two virtual machines hosted in US West 1 Region</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/889/1*5XCNs8tEixVmRs2ab0QqXQ.png" /><figcaption><strong><em>Figure 2</em></strong><em>: Database installed</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/691/1*RjARVV4Y74goFYZKsT2JNQ.png" /><figcaption><strong><em>Figure 3</em></strong><em>: Database configured</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/465/1*y10Fj31nncecUZ2-Rc9aog.png" /><figcaption><strong><em>Figure 4</em></strong><em>: Database user created and privileges set for frontend application</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/468/1*k_U03EHTs6hqara8cvnCdg.png" /><figcaption><strong><em>Figure 5</em></strong><em>: Validate permissions configuration</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/691/1*8emyNIxYbL-A0mDqgTNaag.png" /><figcaption><strong><em>Figure 6</em></strong><em>: Database schema validation</em></figcaption></figure><p>The database server is fully prepared:</p><ol><li>Virtual machine deployed</li><li>MySQL database installed</li><li>MySQL database configured</li></ol><p>— Application user created</p><p>— Permissions configured for application user</p><p>— Database schema created</p><p>— Table created</p><p>4. Validate user permissions</p><p>5. Validate database schema</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/397/1*UiIVfCQepRktshNPZ4_9HQ.png" /><figcaption><strong><em>Figure 7</em></strong><em>: NodeJS installed</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/633/1*6Xt_ITNutzTpVusWcwhBWA.png" /><figcaption><strong><em>Figure 8</em></strong><em>: Application staged on server</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MX3nOEuyzsiIR-3sF3rxMw.png" /><figcaption><strong><em>Figure 9</em></strong><em>: Application configured. Using the private IP address of the database instance</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/820/1*EuLsnAsZ-Yt5QcDKgOwrLQ.png" /><figcaption><strong><em>Figure 10</em></strong><em>: Application launched successfully</em></figcaption></figure><p>The application server is fully prepared:</p><ol><li>Virtual machine deployed</li><li>NodeJS installed</li><li>Application package staged</li><li>Application configured</li><li>NodeJS dependencies installed (npm)</li><li>Security scan performed</li><li>Start the application</li><li>Confirm application initialized properly</li></ol><p>At this point the server is listening on port 3000. It is ready to receive traffic. However, due to the fact that it is not using the traditional web ports (HTTP / HTTPS), traffic will not reach the server due to GCP firewall rules. By default, only HTTP/S is allowed. A custom firewall rule would need to be set up to enable traffic to the NodeJS frontend.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FzTQZgEkvCiYYp0EwU5nOg.png" /><figcaption><strong><em>Figure 11</em></strong><em>: Default firewall rules in GCP. Does not include ingress for NodeJS</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*maoUxm_Tq3wf_HaQAEshmQ.png" /><figcaption><strong><em>Figure 12</em></strong><em>: Firewall rule allowing ingress on port 3000</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tFmESLVeZ-mlr1TZaliXzA.png" /><figcaption><strong><em>Figure 13</em></strong><em>: Application is up and running</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PcNi_To4bx5hp7c1bI5jUg.png" /><figcaption><strong><em>Figure 14</em></strong><em>: New patient records added</em></figcaption></figure><p>At this point, the 2-tier application is fully operational. This is the basis for the migration that will be done to relocate the infrastructure to a different region.</p><p><em>Pre-flight steps</em></p><p>The migration will be done by leveraging snapshots of the VMs. They will be copied to the Australia region, where they will be attached to VMs that are deployed to that region.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eyXI5T0Fse7sfsivNsAwYg.png" /><figcaption><strong><em>Figure 15</em></strong><em>: Listing of all disks</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*s4bOAyEdjDEwMqOPplBs1g.png" /><figcaption><em>Figure 16: Snapshots created</em></figcaption></figure><p><em>Migration</em></p><p>New disks are created in the Australia region. They are based on the snapshots created in the US region</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OKvjvYMmq-kz6zn7oBJDHQ.png" /><figcaption><em>Figure 17: New disks created</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*q58IY5PDemKeyCjdydCqJw.png" /><figcaption><em>Figure 18: New VMs created</em></figcaption></figure><p>The servers are successfully deployed in the Australia region:</p><ol><li>Disks cloned from US to Australia</li><li>Servers deployed and attached to disks</li><li>Confirmed disks have the expected contents</li></ol><p><em>New environment deployed</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RtzGxxrOTyJndbsvcP4gRA.png" /><figcaption><strong><em>Figure 19</em></strong><em>: Validate application server</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*01_cAIDuhXOb6ptUehEIFw.png" /><figcaption><strong><em>Figure 20</em></strong><em>: Update application to point to the new database server in Australia</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*G3WCOaVv3jJyBA3urKOcoQ.png" /><figcaption><strong><em>Figure 21</em></strong><em>: Application initialized</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tuO3p9YpBII8qlGcX7NgVw.png" /><figcaption><em>Figure 22: Application in Australia up and running. Migration complete</em></figcaption></figure><p><em>Migration successful</em></p><p>Application configuration was updated to use the new server’s private IP address in Australia. Upon launching the application, we observed that the same patient records were accessible as those from the US region instance, demonstrating a method for migrating servers using the private networking capabilities of GCP. The advent of virtualization allows this process to be completed within hours, rather than weeks or months required for physical server migrations. This procedure can be incorporated into a disaster recovery strategy and leverages Infrastructure as Code (IaC) to reliably establish a failover site when necessary. Terraform manages GCP infrastructure components such as VPC networks, virtual machines, and disks, while Ansible handles the installation and configuration of essential software like NodeJS and MySQL.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=15836a6bff75" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Deployment of a Private Communication in a MultiCloud Environment (AWS and GCP) 100% Automated…]]></title>
            <link>https://medium.com/@joeljean-claude/deployment-of-a-private-communication-in-a-multicloud-environment-aws-and-gcp-100-automated-dc36740574bb?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/dc36740574bb</guid>
            <category><![CDATA[bash-script]]></category>
            <category><![CDATA[vpn]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[google-cloud-platform]]></category>
            <category><![CDATA[terraform]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Sat, 31 Jan 2026 03:30:10 GMT</pubDate>
            <atom:updated>2026-01-31T14:38:56.517Z</atom:updated>
            <content:encoded><![CDATA[<h3>Deployment of a Private Communication in a MultiCloud Environment (AWS and GCP) 100% Automated Using Terraform</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RN6rnJtP2_3rEvN1TPKPvA.png" /><figcaption>AWS to GCP Interconnect</figcaption></figure><p>In another project based on a real-world scenario, I acted as a Cloud Specialist in a company that used Google Cloud and AWS services in separate architectures.<br> <br> The company decided to interconnect the two environments, in a completely private way, using the Virtual Private Gateway, Customer Gateway, Cloud Routers, Cloud VPN, among other services.<br> <br> However, they needed it in production in a week. So, once GCP and AWS accounts were created, to save time, I decided to deploy it in a 100% automated way using Terraform.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IHQse3tWNsEcw6C25kTijw.png" /><figcaption>Architecture diagram: GCP to AWS</figcaption></figure><p>To get things started, a new service account was created, with a service account key. This will be needed to create the network infrastructure later on.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*j-5zIT7_v4qAwzp0mXjzZg.png" /><figcaption>GCP Service Account</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*cz2N-heqZarGkIWTwHii_g.png" /><figcaption>GCP Service Account Key</figcaption></figure><p>A new IAM user will also be set up in AWS as well, with the accompanying Access Key</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4t-IQFFReV6U2MUubnOOjw.png" /><figcaption>AWS: New IAM created for use with automation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1IfWZCmb88zBVGz9PTr5qw.png" /><figcaption>AWS automation user Access Key</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*FBrIr_1GVTg6C4Ht1Docpw.png" /><figcaption>AWS IAM key added Terraform script in GCP gcloud SDK bastion server</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*O2tu0htCfhMtjgdSGQU5Rw.png" /><figcaption>GCP set project</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*yY6u6BukNkXFYJICI-95UQ.png" /><figcaption>GCP: Terraform validation</figcaption></figure><p>Both sets of credentials were staged in the gcloud CLI where helper scripts were deployed to set up the following:</p><ul><li>GCP project assignment — see the yellow text in the screenshot above</li><li>Terraform scripts to deploy resources both in GCP and AWS</li></ul><p>Next, is to prepare an SSH key. Since we are interconnecting servers in two different cloud environments, it will be necessary to generate the key on one end, import the public key on the other, and vice versa. The general steps will be outlined below:</p><ol><li>Generate SSH key in GCP</li><li>Import the public key from step 1 to the ‘Key Pairs’ list in AWS EC2</li><li>Generate an SSH key in AWS</li><li>Import the public key from step 4 to the Compute Engine Metadata page in GCP</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0e3MOAdlHybX8hbRatziTw.png" /><figcaption>GCP: New SSH key created</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*oDuO68cH2PadL9jm7VhUvQ.png" /><figcaption>GCP: Added public key to metadata in Compute Engine service</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Bni-Udru9rt66z8EuUTz-Q.png" /><figcaption>GCP: Validation public key is successfully added to Compute Engine service</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*19mx-618laLXnxcXlOV_SQ.png" /><figcaption>AWS: Private SSH from GCP imported to AWS account “<em>vm-ssh-key”</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/615/1*vwlySCL-H3tpgmg9j5PROg.png" /><figcaption>GCP: Terraform script</figcaption></figure><p>Quick sidebar here. The image above shows all the files that are associated with Terraform. All of it could have been included in the single file <em>main.tf</em>. However, it would have been a very large file, and would have been difficult to maintain. It is best practice to split out the code to multiple files to make it easier to manage variables, and other infrastructure components. When the code is modular, it makes it easier to make changes to one portion of the code without impacting the core pieces.</p><p>For this project, the components of interest are the networking piece, because they define the VPN tunnels that will implement the interconnect between GCP and AWS, <em>aws_networking.tf</em>. An excerpt is included below:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BJI3TL5xSPDxFTLQooM-Zw.png" /><figcaption>GCP: Terraform script — Networking definitions for vpn tunnels</figcaption></figure><p>One more thing: you will also notice that the state file is also present in this folder, <em>terraform.tfstate</em>. For this type of scenario, it is ok implement the initial deployment with the state file on the local machine. However, in a real-life scenario, it’s likely that there would be several DevOps engineers that would be managing the infrastructure in AWS moving forward, therefore, after initial validation is complete, the state file should be moved to an S3 bucket. This way, the state of the infrastructure is properly tracked and managed to prevent conflicts. I only mention this here since this scenario deals with AWS, and remote state management is only supported in AWS due to specific features AWS S3 provides (object lock, versioning, etc). For the other cloud providers, the Terraform Cloud service can provide the same functionality.</p><p>Back to the main thread. With the pre-flight check complete, now we can proceed to run the terraform script.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tDfJ8XvTvDFjmbJTTBH8dQ.png" /><figcaption>GCP: Terraform initialized</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/921/1*lrAUMXXRQZQEPckh073VOg.png" /><figcaption><em>GCP: Terraform plan. Total counts of added resources, any changes or removals</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fbCVasHvmk4uYgrBuYT3PQ.png" /><figcaption>GCP: <em>Terraform deployment complete. Counts of resources added, with a display of IP addresses of the VMs that were spun up in AWS and GCP</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rZY2ncvgPFVn9XkHqiQGYg.png" /><figcaption>AWS: VPC</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RzvGuzRSWck3CDI2jZqD4w.png" /><figcaption>AWS EC2 Instance</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*naO7Aa6gJ7dY5p1E3crJ4A.png" /><figcaption><em>GCP VPN Tunnels connecting GCP to AWS</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*sgvddDxmUjzfaVrH_eTtvA.png" /><figcaption><em>GCP VPN Routers</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*dsCpWAYHKMHT8RdvsZB3gA.png" /><figcaption><em>GCP VPN Network Gateway</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*tGvO0krX1f8NqcA36N933Q.png" /><figcaption><em>GCP Peer VPN Gateway</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BNTBCmXQgoZClAYG5YN-bg.png" /><figcaption>GCP: Compute Engine Instance, network and storage view</figcaption></figure><p>At this point, all of the foundation is in place, and we can now proceed to validate the communication between the two environments.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/825/1*YJc48DhLYYAXfd8OgvR56w.png" /><figcaption>GCP: SSH Session with a ping executed to AWS EC2 instance</figcaption></figure><p>Here, a ping is initiated from the VM in GCP, to the VM in AWS. The operation is successful.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XMZS-MBAYrDNrlzxAb6_pw.png" /><figcaption><em>GCP Service to troubleshoot and validate network connections</em></figcaption></figure><p>Although the VM-to-VM communication is successful, it’s important to perform other types oof tests. GCP has a service that provides other types of network probes, which provide more details, <em>Network Intelligence</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MX6EEIARWTbfr2Q8qm5OWw.png" /><figcaption><em>Connectivity test details</em></figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/757/1*wiv61lj8-HCzGTCm0w5yQQ.png" /><figcaption>GCP: Outbound network trace to AWS</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/757/1*Sm8rqbl1J2brrJURpg91EQ.png" /><figcaption>GCP: Inbound network trace from AWS</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*9rHhkPEwF3rRzqE_mu0UzA.png" /><figcaption><em>Terraform cleanup</em></figcaption></figure><p>This was a walkthrough of an interconnect deployment of a GCP Project to an AWS account. A VPN was deployed to link the two environments together using Terraform. This enables a speedy and consistent deployment for different regions. The terraform script is configurable and can be adjusted as needs change. This leverages several cloud services to implement the interconnect:</p><ul><li>IAM</li><li>Network</li><li>Compute</li></ul><p>Terraform did the heavy lifting, and was supported by BASH scripts. This is an example where multiple scripting solutions work together to implement a business need to enable the deployment of cloud infrastructure in multiple sites.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=dc36740574bb" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Implementation of an E-Commerce System on AWS in an automated way using Terraform and Ansible]]></title>
            <link>https://medium.com/@joeljean-claude/implementation-of-an-e-commerce-system-on-aws-in-an-automated-way-using-terraform-and-ansible-aa77f4702b15?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/aa77f4702b15</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[apache]]></category>
            <category><![CDATA[aws-ec2]]></category>
            <category><![CDATA[ansible]]></category>
            <category><![CDATA[magento-2]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Sun, 11 Jan 2026 15:11:00 GMT</pubDate>
            <atom:updated>2026-01-11T15:11:00.781Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*c42Po6Sq_9iP_uAJ_-l6Xw.png" /><figcaption>AWS foundation for the e-commerce application</figcaption></figure><p>In another project based in a real-world scenario, I worked as Cloud Engineer using DevOps, where I created and implemented an e-Commerce website on AWS in less than 2 hours and in an automated way using Terraform and Ansible (Infrastructure as Code — IaC).<br> <br> I provisioned the infrastructure in an automated way using Terraform and Ansible to automate the configuration management process, software installation and package management of the EC2 instance. I also used Magento, PHP, MySQL, and Redis to complete this project.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*maPof0YhnzOd4K1M8kIS2Q.png" /><figcaption>Terraform and Ansible work together to deploy the infrastructure and applications</figcaption></figure><p><em>E-Commerce Account Creation</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a3OntFtbBjUsIWPEx8T0-w.png" /><figcaption>New account created on Adobe Magento platform</figcaption></figure><p>Went to <em>marketplace.magento.com</em> and created a new account. Saved and secured the API key for later use.</p><p><em>AWS — Infrastructure Creation</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/758/1*RhXJNlLmBkbDg-oAsnvDsg.png" /><figcaption>Terraform deployment of infrastructure</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0WpZ14FL6JjJ3CMSEBm7lw.png" /><figcaption>EC2 instance information</figcaption></figure><p>Used Terraform to deploy a new EC2 instance on an existing VPC with a security group allowing ingress on HTTP and SSH. EC2 instance has a public IP address and a tag with a name to help make it easy to spot in the server list, <em>ecommerce1</em>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/758/1*V2pChybZuawapRCRxDLBPA.png" /><figcaption>AWS EC2 instance SSH session</figcaption></figure><p>At this point, the server is ready for the deployment of several dependencies required to host the ecommerce site. Ansible is a great tool to manage large batches of configuration settings, which we’ll walk through here. This is going to be a LAMP stack with the Magento application</p><p>LAMP:</p><ul><li><strong>L</strong>inux — Amazon Linux — Ubuntu 22.04</li><li><strong>A</strong>pache 2.4</li><li><strong>M</strong>ySQL 8.0</li><li><strong>P</strong>HP 8.2</li></ul><p>Additional packages</p><ul><li>OpenSearch</li><li>Composer</li></ul><p><em>IaC — Ansible</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4JxvTEHqo_2HcS11unYJ-w.png" /><figcaption>Ansible role — initial attempt</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Xt2RKD93ibwYGhqx1MW43w.png" /><figcaption>Ansible role — subsequent attempt</figcaption></figure><p>As you can see, the Ansible playbook did not complete successfully. Most the roles that were in place were executed successfully, it was only the last two that failed</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0gSXs-ScN9zytF849oJUfQ.png" /><figcaption>Ansible — List of roles and their completion status</figcaption></figure><p>After troubleshooting, it appears that the required packages were no longer available in the AWS AMI. I pivoted over to an Ubuntu AMI, and performed the deployment manually.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*y2myxknTDd32xxmlhgjA5Q.png" /><figcaption>Manual deployment — List of tools and completion status</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*W-QY8em7vpaiSe-twVDZBw.png" /><figcaption>Magento Deployment Successful</figcaption></figure><p>The application was properly deployed and initialized successfully. As is common with these types of deployments, the cache needs to be flushed immediately upon deployment. It will be flushed several times as configuration changes are applied.</p><p><em>E-Commerce Store Configuration</em></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KJqLNVJ0eZCz-WWIl_wxLQ.png" /><figcaption>Magento — Start of customizations for the home page</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eQFqlMgbhe1VLBwMpdpYEA.png" /><figcaption>Magento — New widget</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*AipMKg0wL_ZdXorJXxoQAg.png" /><figcaption>Magento — Widget configuration</figcaption></figure><p>With the base in place, now the E-Commerce site can be customized to bring it to life. The home page has been configured with basic text and headers.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*2F2x9NZnQJJGrjs7KVBsyA.png" /><figcaption>e-commerce app up and running</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PYfUJMl6M9T9uqV2SW7i7Q.png" /><figcaption>Product view 1</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Wtt9RBgMiKoKDMv0Zac2SA.png" /><figcaption>Product view 2</figcaption></figure><p>Now, we have a fully functional e-Commerce site. From here, some additional testing can be done to get it ready for live traffic</p><ul><li>UAT</li><li>Stress testing</li><li>Security measures</li><li>etc</li></ul><p>This would involve several groups of users</p><ul><li>Program Managers</li><li>Prospective customers (Proof of Concept, Proof of Value)</li><li>Relevant stakeholders (Project Managers, Sales, etc)</li><li>etc</li></ul><p>Some of this can be automated as well, with tools like Selenium, that simulate user traffic. Depending on the project, the backend can also be stress tested as well (database). The level of testing would be determined based on many factors, like seasonal demand, geographical location of the target users, etc.</p><p>Since this ended up being a manual deployment, the idea is to capture the steps and create a new ansible role. Since the original role was based on Amazon Linux (a RedHat / CentOS derivative), an entirely new set of Ansible code would need to be created for Ubuntu. This will then be re-usable moving forward. Whenever there’s a breaking change with the underlying OS image, the deployment process would become manual again to determine another successful deployment procedure.</p><p>Terraform can handle basic application installations, however due to the level of configuration required for the LAMP stack, it’s better to capture all of that in Ansible.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=aa77f4702b15" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Elaboration of Executive Presentation of Infrastructure costs for an SAP Migration project from…]]></title>
            <link>https://medium.com/@joeljean-claude/elaboration-of-executive-presentation-of-infrastructure-costs-for-an-sap-migration-project-from-453d080052e9?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/453d080052e9</guid>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[aws-pricing-calculator]]></category>
            <category><![CDATA[presentations]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Tue, 06 Jan 2026 00:32:28 GMT</pubDate>
            <atom:updated>2026-01-06T00:32:28.056Z</atom:updated>
            <content:encoded><![CDATA[<h3>Elaboration of Executive Presentation of Infrastructure costs for an SAP Migration project from On-Premises to AWS</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zMSfjs3oRtaM-isZHBrPzw.png" /><figcaption>AWS Pricing Calculator</figcaption></figure><p>In this project based on a real-world scenario, I acted as a Cloud Architect and created an executive presentation of infrastructure costs for a SAP migration project from On-Premises to AWS.<br> <br> SAP workloads were running in a corporate DataCenter with the environment divided into Production, Quality Assurance — QA and Development/Test layers.<br> <br> My mission was to estimate the costs of migration to AWS, considering that this infrastructure will be running on AWS for at least the next 3 years.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YAWiEB6UsU4Npr2a7D_c8w.png" /><figcaption>Infrastructure for all environments</figcaption></figure><p>I used a calculator tool that is provided by AWS. It’s on a public-facing page that anyone can use to build a detailed estimate. This does not require an AWS account.</p><p><a href="https://calculator.aws/#/">AWS Pricing Calculator</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ldZClrNK37so87LmhVyYcg.png" /><figcaption>Cost estimation tool</figcaption></figure><p>However, if you happen to have an AWS account, you can login to get a more tailored estimate.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/601/1*7E1FOHCgHSjAyDvumazEmg.png" /><figcaption>List of all infrastructure components</figcaption></figure><p>The list above shows all the infrastructure that will be used. Note that this includes testing and production environments. Additionally, we have the Enterprise support plan listed; this will be necessary to have the proper level of support from AWS for any major issues that may come up.</p><p>An estimate will be generated for each of the components</p><ul><li>EC2 instances</li><li>Elastic Load Balancers</li><li>Databases</li><li>Storage</li><li>Support Plan</li></ul><p>An aggregated estimate will be created as a result, as you’ll see shortly.</p><p><strong>EC2</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Iammb41gtg1ASvlxUKV6ug.png" /><figcaption>Start of an estimate for EC2 instances</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*L09BQ79HNCQ4fZZUlOs09w.png" /><figcaption>Selected instance type</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BUImw33sHEcsIPvldhSqTQ.png" /><figcaption>Breakeven projections</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MMa2Wefz6-_OoIteqchtBg.png" /><figcaption>Completed estimate for EC2 instances</figcaption></figure><p>What is important to consider here is that the tool is able to provide projections on the breakeven point of the expenses. This is a very important metric that stakeholders will be looking for when it comes to getting a proper approximation of ROI.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*t3niw7goL5qFP_nJ3FHz0g.png" /><figcaption>Payment plan selection</figcaption></figure><p>Since the requirement is to maintain this infrastructure for 3 years, we are leveraging the best option available, the Savings Plan. It provides the opportunity to defer operational expenses to the go-live phase (Payment Options — ‘No upfront’). All the initial testing and validation can be completed with no immediate financial impact.</p><p><strong>Storage</strong> — EBS</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*bBgOhcD4VBr1KHKN-oHHSQ.png" /><figcaption>Estimate for storage devices used by EC2 instances in test environment</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vFm1q69Hvrj35RYGKDBfxw.png" /><figcaption>Estimate for storage devices used by EC2 instances in production environment</figcaption></figure><p><strong>Load Balancing</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*S8H-ibcck7l5rL9yUWtusw.png" /><figcaption>Estimates for 3 application load balancers for all environments</figcaption></figure><p><strong>Database</strong></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*jLhlu1EnuHsd2kKDj8fXoA.png" /><figcaption>Estimate for database instances</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Na30HYfkgXLtwoxN2c3ZLg.png" /><figcaption>Estimate for database instances for all environments</figcaption></figure><p>Full Estimate</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NCVQSr00eMYuZDs3H2fZWQ.png" /><figcaption>Full estimate of all infrustructure and Enterprise support</figcaption></figure><p>With the estimate complete, I proceeded to export it, so that I can create a Powerpoint slide deck.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Dnn4iyVTEj_TNmmklw0KYg.png" /><figcaption>CSV Export of the pricing estimate</figcaption></figure><p>To make this data presentable to executives, it must be presented in a graphical way to provide a quick glance at all the costs, relative to the budgeted amount. It enables me to be concise, speak to key points, and provide opportunities for discussion on any items that may be of interest:</p><ul><li>AWS Support plan</li><li>Sizing for dev and staging environments</li><li>etc</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CAWLmy9ytdNGKPhhECaUTw.png" /><figcaption>Executive presentation — cover page</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*NCDgw3fB8NOU50E4nAMM7g.png" /><figcaption>Executive presentation — Monthly cost breakdown</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KZ_EhJOkCGn8EPGmZD9d5w.png" /><figcaption>Executive presentation — Yearly cost breakdown</figcaption></figure><p>This was a walkthrough of the AWS Price Calculator, which demonstrates the capability to generate a detailed pricing estimate for an infrastructure deployment used to prepare an executive presentation. The tool is open to the public and free to use. One of the main highlights of the tool is the breakeven projections, which help in helping submit requests for approval to the Finance department, as well as help decision makers when looking at the cost-benefit analysis. Estimates from the tool can be further tailored when an administrator is logged in to the AWS console.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=453d080052e9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Implementation of a set of EC2 instances using Terraform and AWS Systems Manager configuration with…]]></title>
            <link>https://medium.com/@joeljean-claude/implementation-of-a-set-of-ec2-instances-using-terraform-and-aws-systems-manager-configuration-with-7e195b1054a0?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/7e195b1054a0</guid>
            <category><![CDATA[terraform]]></category>
            <category><![CDATA[aws-ec2]]></category>
            <category><![CDATA[aws-ssm]]></category>
            <category><![CDATA[aws-sns]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Sat, 27 Dec 2025 00:46:39 GMT</pubDate>
            <atom:updated>2025-12-28T20:57:53.071Z</atom:updated>
            <content:encoded><![CDATA[<h3>Implementation of a set of EC2 instances using Terraform and AWS Systems Manager configuration with Amazon Simple Notification Service for automated installation of security agents</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vKdof7cu7jfz9EzF6PRNpw.png" /><figcaption>Project Overview</figcaption></figure><p>In this project based on a real-world scenario, I acted as DevSecOps Engineer, and I deployed a set of EC2 instances and infrastructure in an automated way using Terraform (infrastructure as code — IaC). Also, it was necessary to install a specific security agent on all these instances in an automated fashion as well.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*l5nIFDSszczl4WNhBGpnYA.png" /><figcaption>Infrastructure as Code in Action, used in combination with cloud-native automation tools</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/681/1*_3jvy_HbDt5RIrlEKGI7eA.png" /><figcaption>Terraform: Deployed an EC2 instance in existing VPC</figcaption></figure><p>Here, you can see two new virtual servers have been deployed to an existing AWS VPC, along with a security group configured to allow ingress on port 22 (SSH).</p><p>Once I provisioned the infrastructure, AWS System Manager and its component Command Run were used to install the security agents in an automated way. I used the Amazon Simple Notification Service — SNS to send an email informing the whole process status.</p><p>To continue the process, an IAM role was created to enable the ability to enable the System Manager service to send notifications to an SNS topic.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1003/1*L1ZJ39PevvfvSpl2Vh_PQQ.png" /><figcaption>IAM: Role created for use with SNS</figcaption></figure><p>Then, a new subscription was created in the Simple Notification Service (SNS) to associate a topic to an email address.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*65Wf5RGn1XTCaOGsUlTyzQ.png" /><figcaption>SNS: Topic to send notifications to user email</figcaption></figure><p>Some details were redacted, as this is an active AWS account used for production use cases.</p><p>With these things in place, a new configuration can be set up in Systems Manager.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*JE5jP5BdJvZUoiFlb3QuCg.png" /><figcaption>SSM: New configuration</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YpgApejUE9PZ64NLErD9yA.png" /><figcaption>SSM: On-boarding in progress</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XhsHC3WG-oCf8aeFc3z0BA.png" /><figcaption>SSM: On-boarding complete</figcaption></figure><p>It took about 15 minutes to show all green for the configuration associations to take place. This enabled me to proceed to the next step, which is to deploy the security agents.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CQA0TRAUSMiHEXgonQn58A.png" /><figcaption>SSM: Target selection</figcaption></figure><p>I selected the two servers, and kicked off a command to install the agent.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Qfe4D4LY4SBV8gja-Eykuw.png" /><figcaption>SNS: Email notifications</figcaption></figure><p>After letting the job run for some time, I checked my email, and found notifications for the successful deployment of the servers</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*MCWxhYY1S8q5MuhngVXjcw.png" /><figcaption>SSM: Job details</figcaption></figure><p>The image above shows an overview of a job that was triggered. You see the commands that were run, and the servers it was applied to. Job completed successfully on all targets.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qIb7ApuhjwDUv2pzKXhXGw.png" /><figcaption>SSM: Command history</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PKoZ3Z1vxbuPwZ4K4rPG5Q.png" /><figcaption>SSM: Command logs</figcaption></figure><p>Here, I’m taking a closer look at one of the servers, and checking the logs. This was additional confirmation that the deployment of the agents was successful.</p><p>With all of the validation completed, it was time to spin down the deployment.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/681/1*m4ikkL-wyd2ScNP_xj75VA.png" /><figcaption>Terraform: Cleanup</figcaption></figure><p>The command <em>terraform destroy</em> proceeds to shut down and terminate the EC2 instances, removes the security group. By default, this command removes all resources that have been defined in the configuration file. In this case, it was just three resources, the underlying VPC, subnets and other networking infrastructure will persist for future use.</p><p>There are other options to selectively remove resources, and those are done under specific circumstances (dev environment where different people are working on specific parts of the infrastructure: web, db, middleware, etc). This way, certain things can be retained so as to not disrupt other user’s work.</p><p>This was a walkthrough of automation using Terraform along with cloud-native services like Systems Manager to deploy servers with agents. The SNS service was used as a way to provide external notifications for the status of the deployment. In this case, security agents we deployed to the servers. In other cases, other agents can be deployed; monitoring, queue manager, or other types. Terraform enables the use of configuration files to define cloud infrastructure that makes it possible to track via version control, and execute consistent deployments in the cloud. For simpler use cases like the one covered here, some bootstrap commands can be included in the Terraform configuration. For more elaborate ones, tools like Ansible or Puppet may be more appropriate. Terraform can be used in conjunction with Ansible. An example of this will be covered in another post.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=7e195b1054a0" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Implementation of a Scalable Web Application using the services of AWS Elastic Beanstalk, DynamoDB…]]></title>
            <link>https://medium.com/@joeljean-claude/implementation-of-a-scalable-web-application-using-the-services-of-aws-elastic-beanstalk-dynamodb-921de905f04a?source=rss-5ac96a65f994------2</link>
            <guid isPermaLink="false">https://medium.com/p/921de905f04a</guid>
            <category><![CDATA[elastic-beanstalk]]></category>
            <category><![CDATA[aws-dynamodb]]></category>
            <category><![CDATA[aws-ec2]]></category>
            <category><![CDATA[aws-cloudfront]]></category>
            <dc:creator><![CDATA[Joel Jean-Claude]]></dc:creator>
            <pubDate>Tue, 23 Dec 2025 22:38:52 GMT</pubDate>
            <atom:updated>2025-12-23T22:57:27.031Z</atom:updated>
            <content:encoded><![CDATA[<h3>Implementation of a Scalable Web Application using the services of AWS Elastic Beanstalk, DynamoDB, CloudFront and Edge Location</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*vyyUmMJxKPSGow2Ns1FIsw.png" /><figcaption>Project Overview</figcaption></figure><p>In this project based on a real-world scenario, I was responsible for implementing an application that needs to support the high demand of a large number of users accessing it simultaneously.</p><p>This application has been used in a large conference that had more than 10,000 people, in-person and online, with participants from all over the world. This event was broadcast online and in person and 10 vouchers were drawn for 3 Cloud certifications. At that moment, more than 10,000 people in the audience registered their e-mails to guarantee their participation in the raffle.</p><p>In AWS, several services were used: Elastic Beanstalk to deploy the web application, DynamoDB to store emails, CloudFront to cache static and dynamic files in an Edge Location close to the user.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Fh-2rrUNSN2eMAFC2HaBsQ.png" /><figcaption>Scenario: Users in live conference, and separate streams running in parallel. Data is sent to AWS infrastructure through various services</figcaption></figure><p>Starting with DynamoDB, the table was set up, so that it could be ready to receive write requests from the Beantstalk application.</p><p>Next, was the Beanstalk instance. This part took multiple attempts, as I’ll explain shortly.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/755/1*SJj9S-uOP9HY5daC-8uY1Q.png" /><figcaption>EC2 Instance supporting Beanstalk application</figcaption></figure><p>Here you see the underlying EC2 instance up and running. This is where the application will be deployed.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*VNYU68rASFUlt0qDpPaXtQ.png" /><figcaption>First attempt: Load balancer configuration is not correct</figcaption></figure><p>Image above shows the issue of the first attempt to deploy the instance. I had selected all available subnets (public and private in multiple Availability Zones — AZs). I rolled this deployment back, and tried again…</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*wMGTczLglulE6q17PtFYrw.png" /><figcaption>Second attempt: Chose subnets in different AZs</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*iMXZBk27n1kgVZcvh-eo1A.png" /><figcaption>2nd attempt: Results, failed again</figcaption></figure><p>I had selected just private subnets this time around. This, still, was not a proper configuration. So therefore, I rolled back again, and deployed a new instance.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*og0KBe-TbEoP3xrLjif3Yw.png" /><figcaption>3rd attempt: Chose one public and one private subnet</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*YAAZANMkHYN58AEvwE8zZg.png" /><figcaption>3rd attempt: Successful deployment</figcaption></figure><p>Based on the errors reported in the previous attempts, I made different selections (1 public subnet in one AZ, and the private subnet in another AZ).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nnyKBsW_u6BKaOHqf1jEtw.png" /><figcaption>Application Load Balancer (ALB) deployed by the Beanstalk service</figcaption></figure><p>With the instance up and running I proceeded to perform validation.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*OgnDaf3HorOFB-IbToI2vA.png" /><figcaption>Beanstalk front end</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/996/1*tvbrYy5x2AgEj2e13dbqLw.png" /><figcaption>Beanstalk: New user registration confirmation</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ybgJiIpgfNe_ad4B6cztrw.png" /><figcaption>DynamoDB table: New user entry</figcaption></figure><p>For brevity, I have skipped a few steps to update the IAM role to enable the Beanstalk service to write to the DynamoDB . Above you can see that a new user has been successfully registered in the app, and a new entry exists in the DynamoDB table.</p><p>Now, we’ll take things a step further to host the application behind a CloudFront distribution. As, shown in the architecture diagram at the start of this article, this will enable users in different parts of the world to get access to the site. Additionally, this will enable us add additional layers of security by leveraging Web Application Firewall (WAF) and protections against Distributed Denial of Service (DDoS) attacks.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*rrGbcXpYG77JrZblwJ0kmg.png" /><figcaption>CloudFront distribution</figcaption></figure><p>This distribution uses the load balancer from the Elastic Beanstalk instance as an origin. CloudFront distributions can also use S3 buckets as an origin to create a static website.</p><p>Navigating to the distribution domain name URL, we’re able to see the application again</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Hc5WYzHhg_ieOeHcX-LAKQ.png" /><figcaption>Beanstalk: Now accessible via CloudFront</figcaption></figure><p>Notice that the site is now secured with HTTPS</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*fvahaJg3W_oQ1_IRiixONw.png" /><figcaption>Beanstalk / CloudFront — New user registered</figcaption></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/988/1*ehsQXyyrFuEILeYSHBpoNA.png" /><figcaption>DynamoDB: New users registered</figcaption></figure><p>As you can see, more users have been successfully registered.</p><p>After this, I performed some load tests using the <em>stress</em> utility, to see how CloudFront would handle failover, triggering a scaling event, etc. I was able to see that in the monitoring page for the target group in the Load Balancing page, as well as Instances page for the Beanstalk application.</p><p>Biggest takeaway from this project was the load balancing configuration. Even though I picked multiple subnets (public/private), they needed to be in different Availability Zones. This helped to reinforce the fact that AZs are separate sites in one region. So in the event of a outage in one AZ (power failure, network disconnect, etc), the other one can step in to provide continuity.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=921de905f04a" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>