<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Ivan Camacho</title>
    <description>The latest articles on DEV Community by Ivan Camacho (@swe-pea).</description>
    <link>https://dev.to/swe-pea</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1133352%2F0acf5ce5-d1fa-4a52-8b9f-9e7e56988843.jpeg</url>
      <title>DEV Community: Ivan Camacho</title>
      <link>https://dev.to/swe-pea</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/swe-pea"/>
    <language>en</language>
    <item>
      <title>Self-host ASP.NET DevOps build server (K3S, Docker, GitHub Actions, ArgoCD)</title>
      <dc:creator>Ivan Camacho</dc:creator>
      <pubDate>Mon, 30 Oct 2023 17:11:54 +0000</pubDate>
      <link>https://dev.to/swe-pea/self-host-aspnet-devops-build-server-k3s-docker-github-actions-argocd-4hpf</link>
      <guid>https://dev.to/swe-pea/self-host-aspnet-devops-build-server-k3s-docker-github-actions-argocd-4hpf</guid>
      <description>&lt;h3&gt;
  
  
  Objectives
&lt;/h3&gt;

&lt;p&gt;My objectives when setting up K3s in my home lab were to play around with Kubernetes and save on cloud costs by utilizing the computing resources to host CI runners for GitLab and GitHub. However, once complete, I decided it'd be fun and good practice to configure a deployment system linked to my K3S cluster as well.&lt;/p&gt;

&lt;p&gt;This article is to possibly help anyone also interested in learning Kubernetes and setting up a CI/CD pipeline while saving on costs.&lt;/p&gt;

&lt;p&gt;Here are the steps I took!&lt;/p&gt;

&lt;h3&gt;
  
  
  Preparation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.proxmox.com/en/"&gt;Proxmox&lt;/a&gt; &amp;amp; K3s -&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I chose Proxmox as a hypervisor because it simplifies resource management and enables stable, scalable local Kubernetes environments.&lt;/li&gt;
&lt;li&gt;I'm using K3s because it offers Kubernetes features like scalability and security while using fewer resources and being quicker to deploy than K8s.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://metallb.org/"&gt;MetalLB&lt;/a&gt; -&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;MetalLB is a solution to ensure services within a locally hosted Kubernetes cluster are accessible, load-balanced, and have their networking traffic adequately managed.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Although MetalLB isn't recommended for production environments, it works well for this project as the objectives are focused on testing and development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For information on setting up MetalLB, take a look at their GitHub page here - &lt;a href="https://github.com/metallb/metallb"&gt;https://github.com/metallb/metallb&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TechnoTim has a great article &amp;amp; video covering how to automate the set-up and deployment of both K3s and MetalLB using &lt;strong&gt;Ansible&lt;/strong&gt;: &lt;a href="https://technotim.live/posts/k3s-etcd-ansible/"&gt;https://technotim.live/posts/k3s-etcd-ansible/&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Steps
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Example Code :&lt;br&gt;
&lt;em&gt;App CI Repo ~ &lt;a href="https://github.com/swe-pea/ASP-NET-TestApp"&gt;https://github.com/swe-pea/ASP-NET-TestApp&lt;/a&gt;&lt;br&gt;
Kubernetes Manifest/CD ~ &lt;a href="https://github.com/swe-pea/home-lab/tree/main/ASP-TestApp"&gt;https://github.com/swe-pea/home-lab/tree/main/ASP-TestApp&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Setting Up The ASP.NET CI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;I started off by creating a GitHub repo dedicated to storing application code and building new containerized versions of the application.&lt;/li&gt;
&lt;li&gt;To self-host a single GitHub runner for the CI repository, I first set up an ACR (Actions Runner Controller) on K3s by applying the following manifest and registering a GitHub PAT as a Kubernetes secret
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Applies kubernetes config to set up ARC
kubectl apply -f https://github.com/summerwind/actions-runner-controller/releases/latest/download/actions-runner-controller.yaml

kubectl create secret generic controller-manager \
    -n actions-runner-system \
    --from-literal=github_token=${GITHUB_TOKEN}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Then, create and apply the following .yml file. By creating the secret and applying the following manifest, a single GitHub runner is created and linked to the CI repo.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# runner.yaml
apiVersion: actions.summerwind.dev/v1alpha1
kind: Runner
metadata:
  name: example-runner
spec:
  repository: exampleUser/example-repo
  env: []
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Additionally, I created a DockerHub repository to store the application docker images built from the GitHub repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The GitHub &lt;a href="https://github.com/swe-pea/ASP-NET-TestApp/blob/main/.github/workflows/CI.yml"&gt;workflows&lt;/a&gt; pushed with the application code automatically run on the newly configured self-hosted runner. Using &lt;em&gt;docker/login-action@v3&lt;/em&gt; and &lt;em&gt;docker/build-push-action@v5&lt;/em&gt;, the containerized application is stored in DockerHub.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploying The ASP.NET Application
&lt;/h3&gt;

&lt;p&gt;Having successfully set up the CI pipeline and containerized the ASP.NET application, it's time to deploy it to the K3S cluster.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Deployment Repository:&lt;/strong&gt; I created a second GitHub repository with the sole purpose of deploying the ASP.NET application. This repository will use &lt;a href="https://github.com/swe-pea/home-lab/blob/main/ASP-TestApp/TestApp.yml"&gt;Kubernetes manifests&lt;/a&gt; (in .yml format) to define how the application should operate within the K3S cluster(replica count, ports, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ArgoCD:&lt;/strong&gt; Using a deployment tool like ArgoCD makes it seamless to connect repositories to your Kubernetes cluster and deploy applications. Although I won't go into the details of how to set ArgoCD up, as a Kubernetes amateur, this is the method I went with for quickly deploying my Kubernetes manifest from the repository to my cluster.&lt;/li&gt;
&lt;/ol&gt;

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

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Helm Charts:&lt;/strong&gt; Although Helm is a popular package manager tool for Kubernetes, with Helm charts offering pre-configured packages to make deployment quick and consistent, I decided to work with Kubernetes manifests directly to focus on the fundamentals.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Continuous Deployment:&lt;/strong&gt; Since the project objectives weren't focused on deployment strategies like rolling update, canary, or blue-green, continuous deployment was not configured. However, you can create a continuous deployment from this solution by using webhooks if you are interested.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;In conclusion, this journey has provided insights into setting up a cost-effective, self-hosted CI/CD pipeline in a home lab, utilizing K3S and other OSS. I've learned a lot while also having lots of fun, so I'm hoping by sharing my experience working on this small project, someone else can maybe gain some inspiration or value from it as well!&lt;/p&gt;

&lt;p&gt;Happy deploying,&lt;/p&gt;

&lt;p&gt;-Ivan&lt;/p&gt;

</description>
      <category>programming</category>
      <category>devops</category>
      <category>kubernetes</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Cloud Resume Challenge - Azure Edition</title>
      <dc:creator>Ivan Camacho</dc:creator>
      <pubDate>Sun, 10 Sep 2023 01:19:15 +0000</pubDate>
      <link>https://dev.to/swe-pea/cloud-resume-challenge-azure-edition-227o</link>
      <guid>https://dev.to/swe-pea/cloud-resume-challenge-azure-edition-227o</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--x-wLNGGy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjwo5k50xtntl93j309x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--x-wLNGGy--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/pjwo5k50xtntl93j309x.png" alt="" width="800" height="480"&gt;&lt;/a&gt;&lt;br&gt;
While looking through articles from the dev community, I recently stumbled across a member's blog post describing  their experience completing "The Cloud Resume Challenge." This caught my eye as the challenge looked fun and was similar to a simple personal blog project I had already wanted to start. After reviewing The Cloud Resume Challenge website, I knew this project was perfect for me!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Link To Challenge&lt;/em&gt;: &lt;a href="https://cloudresumechallenge.dev/docs/the-challenge/azure/#9-api"&gt;The Cloud Resume Challenge&lt;/a&gt;&lt;br&gt;
&lt;em&gt;Link To End Result&lt;/em&gt;: &lt;a href="https://www.cuauh.codes/"&gt;https://www.cuauh.codes/&lt;/a&gt;&lt;br&gt;
&lt;em&gt;GitHub&lt;/em&gt;: &lt;a href="https://github.com/swe-pea/AzureResumeChallenge"&gt;https://github.com/swe-pea/AzureResumeChallenge&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Considering Tools, Goals, &amp;amp; Objectives
&lt;/h2&gt;

&lt;p&gt;Before building things, I took a moment to assess the project requirements and weigh different technology solutions while considering my objectives. Off the bat, I knew I would be using Azure as the cloud provider (hence the title) since I've been heavily Azure-focused with most recent projects, and my only other cloud experience has been with AWS (Eliminating GCP - as learning a new provider doesn't align with my objectives for the project).&lt;br&gt;
 &lt;br&gt;
Consideration for version control &amp;amp; CI/CD fell between Gitlab, GitHub, and Azure DevOps. With web development taking priority for "area of desired learning/growth" with this project, I went with what I'm currently most comfortable &amp;amp; experienced working with: Azure DevOps. However, with the ease of authentication/compatibility, I used GitHub for the repo, with the "Azure Pipelines" GitHub App integration. I recommend  this solution when working with Azure. However, I'll probably be using more GitHub actions moving forward.&lt;/p&gt;

&lt;p&gt;Finally, rather than using Python to create the "Visitor Counter API" as recommended, I enjoy coding C# a lot and therefore opted to use that, although it's arguably overkill for this project, and I didn't do any fancy OOP stuff. &lt;/p&gt;

&lt;h2&gt;
  
  
  Setting Up The Site
&lt;/h2&gt;

&lt;p&gt;Some of the most time-consuming pieces of this project for me were in the beginning with simply building &amp;amp; setting up the static website and getting the visitor counter to work correctly. It has been a long time since I've touched HTML, CSS, and Javascript. My goal was to keep everything as simple as possible &amp;amp; keep things secure, which looked slightly different as I altered the challenge to host my blog site rather than a single-page resume.&lt;br&gt;
 &lt;br&gt;
I used GoDaddy to purchase my custom domain name &amp;amp; another site for the SSL certificate, where, in retrospect, I could've used Azure's internal services to buy a custom domain and configure it with a managed SSL certificate to minimize complexity. It wasn't a huge issue; I made a CNAME record mapping from the DNS provider I used to my Azure CND endpoint. Once that propagated, my Azure Front Door &amp;amp; CDN profile was ready to rock &amp;amp; roll!&lt;/p&gt;

&lt;h2&gt;
  
  
  Site Visitor Counter (DynamoDB &amp;amp; Azure Functions)
&lt;/h2&gt;

&lt;p&gt;After writing the javascript on my site for how I wanted the "Visitor Count" feature to work, I had a good idea of implementing the API using Azure Functions to communicate securely with a simple DB table entity. Visual Studio IDE helps create an Azure Function app, a speedy and  seamless process, so you can focus on writing code rather than overspending time on configuration/authentication. I highly recommend it if working with Azure!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ObM7hqIw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugrq1tofev1ljftq4wyk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ObM7hqIw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ugrq1tofev1ljftq4wyk.png" alt="Using VS to create C# Azure Function App" width="800" height="573"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Using VS to create C# Azure Function AppUsing the Cosmos DB .NET SDK, and after a period of trial &amp;amp; error, I had my visitorcounter.js method using the HTTP trigger to increment and display my site counter. What was most challenging for me was getting my visitorcounter.js logic to work with my site the way I wanted. Luckily, with the abundance of online resources developers have today (forums, AI tools, etc.), overcoming obstacles for integrating the front end with the back wasn't nearly as challenging as it would've been "back in the day." I have tons of gratitude for the easily accessible tech resources available in today's day &amp;amp; age!&lt;/p&gt;

&lt;h2&gt;
  
  
  Infrastructure As Code &amp;amp; Automation (CI/CD)
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a5uPijvo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qyk57hl1009ju48ng19j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a5uPijvo--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qyk57hl1009ju48ng19j.png" alt="Front End Deployment Stg in Azure DevOps" width="655" height="373"&gt;&lt;/a&gt;&lt;br&gt;
Front End Deployment Stg in Azure DevOpsIt could defeat the purpose of IaC for a project like this; however, I've always automated processes/tasks only after understanding the task "inside and out,"  and so I provisioned &amp;amp; configured my resources using Azure CLI and the UI portal first to get a POC(Proof of concept) working. I always learn a lot from building out and testing a little POC; in this case, it also helped me consider (in terms of automation) how robust, flexible, and well-designed a solution I wanted to create.&lt;/p&gt;

&lt;p&gt;For IaC, I was solely going to use Terraform. However, creating an Azure Document DB Table API (Supports enabling a "free-tier" feature) was difficult as there's no "Document DB" module in Terraform. So, I resorted to using Bicep to handle that. I had gotten confused with all the different APIs Cosmos DB supports and wanted to select the most cost-effective one.&lt;/p&gt;

&lt;h2&gt;
  
  
  TDLR ~ Review 
&lt;/h2&gt;

&lt;p&gt;My primary goals for this project were to gain experience with web development, write this blog, satisfy the challenge requirements, and get an MVP launched. Sticking more or less to these goals left tons of room for improvement, especially with the backend of the project, specifically the visitor counter feature (DB &amp;amp; Az Function) and the automation pipelines. &lt;/p&gt;

&lt;p&gt;That said, however, I thoroughly enjoyed working on this challenge (even if altered a little bit) and highly recommend it to just about anyone interested in technology, as it touches many different areas! I have already recommended it to several people. It's been a perfect and incredibly fun "breaking the ice" project to get kicked off developing experience &amp;amp; comfort writing "dev"/technical blog posts and sharing projects online despite their flaws! &lt;/p&gt;

&lt;p&gt;I am excited to continue writing blog posts on tech-related stuff geared toward helping others and providing value. While also sharing more public projects on Github and connecting with other like-minded techies! I am very grateful for the developer communities; thanks.&lt;br&gt;
-Ivan&lt;/p&gt;

</description>
      <category>devops</category>
      <category>azure</category>
      <category>cloud</category>
      <category>csharp</category>
    </item>
  </channel>
</rss>
