<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged jenkins</title>
<link>https://coderlegion.com/tag/jenkins</link>
<description>Powered by Question2Answer</description>
<item>
<title>MongoDB DR Drill Automation with Terraform, Python &amp; Jenkins — How We Made Restores Boring</title>
<link>https://coderlegion.com/21768/mongodb-dr-drill-automation-with-terraform-python-jenkins-how-we-made-restores-boring</link>
<description>&lt;h3 id=&quot;backups-don-t-save-you-restores-do-&quot;&gt;Backups Don't Save You. Restores Do.&lt;/h3&gt;
&lt;p&gt;We ran a MongoDB restore drill last quarter. It failed — not the restore itself, but the confidence. Nobody in the room was sure the data was actually intact. The service came back up, and we all just stared at each other.&lt;/p&gt;
&lt;p&gt;That was the problem. So we fixed it by automating everything.&lt;/p&gt;
&lt;p&gt;One Jenkins job now provisions infra, builds the replica set, restores from dumps, validates data integrity, and stores a full audit trail. Here's exactly how it works.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-goal&quot;&gt;The Goal&lt;/h3&gt;
&lt;p&gt;Remove every manual, error-prone step from the DR process:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Identical restore flow across all environments&lt;/li&gt;
&lt;li&gt;Automated replica set setup — no manual &lt;code&gt;rs.initiate()&lt;/code&gt; typos&lt;/li&gt;
&lt;li&gt;Real validation that &lt;em&gt;proves&lt;/em&gt; data is intact, not just assumed&lt;/li&gt;
&lt;li&gt;Full audit trail for post-mortems and compliance reviews&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-pipeline-5-stages&quot;&gt;The Pipeline: 5 Stages&lt;/h3&gt;
&lt;h4 id=&quot;1-infrastructure-with-terraform&quot;&gt;1. Infrastructure with Terraform&lt;/h4&gt;
&lt;p&gt;Every drill starts with clean infra. Terraform provisions EC2s, networking, and persistent volumes from scratch — same starting point every time. No leftover state. No &quot;works on my machine&quot; surprises.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-hcl&quot;&gt;resource &quot;aws_instance&quot; &quot;mongo_node&quot; {
  count         = 3
  ami           = var.mongo_ami
  instance_type = &quot;t3.medium&quot;
  tags = {
    Name = &quot;mongo-dr-node-${count.index}&quot;
    Role = &quot;mongodb-replica&quot;
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;2-replica-set-creation-python-&quot;&gt;2. Replica Set Creation (Python)&lt;/h4&gt;
&lt;p&gt;Instead of manually running &lt;code&gt;rs.initiate()&lt;/code&gt; and &lt;code&gt;rs.add()&lt;/code&gt; and hoping the timing works, a Python script handles the entire setup — ordering, retries, and confirmation.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;from pymongo import MongoClient
import time

def init_replica_set(primary_host, secondary_hosts):
    client = MongoClient(f&quot;mongodb://{primary_host}:27017&quot;)
    config = {
        &quot;_id&quot;: &quot;rs0&quot;,
        &quot;members&quot;: [{&quot;_id&quot;: i, &quot;host&quot;: h}
                    for i, h in enumerate([primary_host] + secondary_hosts)]
    }
    client.admin.command(&quot;replSetInitiate&quot;, config)
    # Wait for PRIMARY election
    for _ in range(30):
        status = client.admin.command(&quot;replSetGetStatus&quot;)
        if any(m[&quot;stateStr&quot;] == &quot;PRIMARY&quot; for m in status[&quot;members&quot;]):
            return True
        time.sleep(2)
    raise Exception(&quot;Replica set did not elect a PRIMARY in time&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Automating this removes timing issues and misconfiguration. Every replica set comes up the same way.&lt;/p&gt;
&lt;h4 id=&quot;3-backup-amp-restore&quot;&gt;3. Backup &amp;amp; Restore&lt;/h4&gt;
&lt;p&gt;Backups are normalized into compressed archives. The restore unpacks a dump and applies it to the fresh nodes:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Create dump
mongodump --host $SOURCE_HOST --db $DB_NAME \
  --out /backup/dump --gzip

# Restore to DR environment
mongorestore --host $DR_HOST --db $DB_NAME \
  /backup/dump/$DB_NAME --gzip --drop
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;4-validation-amp-comparison-the-part-most-teams-skip&quot;&gt;4. Validation &amp;amp; Comparison — The Part Most Teams Skip&lt;/h4&gt;
&lt;p&gt;This is the step that actually builds confidence. The validation script:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Checks which collections exist (flags missing collections)&lt;/li&gt;
&lt;li&gt;Compares document counts collection by collection&lt;/li&gt;
&lt;li&gt;Compares indexes between source and restored DB&lt;/li&gt;
&lt;li&gt;Samples &lt;code&gt;_id&lt;/code&gt; values for obvious data mismatches&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def validate_restore(source_uri, dr_uri, db_name):
    src = MongoClient(source_uri)[db_name]
    dr  = MongoClient(dr_uri)[db_name]

    report = {&quot;status&quot;: &quot;pass&quot;, &quot;collections&quot;: {}}

    for col in src.list_collection_names():
        src_count = src[col].count_documents({})
        dr_count  = dr[col].count_documents({})
        src_idx   = sorted(src[col].index_information().keys())
        dr_idx    = sorted(dr[col].index_information().keys())

        match = (src_count == dr_count) and (src_idx == dr_idx)
        report[&quot;collections&quot;][col] = {
            &quot;count_match&quot;:  match,
            &quot;source_count&quot;: src_count,
            &quot;dr_count&quot;:     dr_count,
            &quot;index_match&quot;:  src_idx == dr_idx
        }
        if not match:
            report[&quot;status&quot;] = &quot;fail&quot;

    return report
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Exit code &lt;code&gt;0&lt;/code&gt; = counts and indexes match → Jenkins passes.&lt;br&gt;
Non-zero = mismatch → Jenkins fails the build immediately.&lt;/p&gt;
&lt;p&gt;No more guessing. No more staring at each other in the war room.&lt;/p&gt;
&lt;h4 id=&quot;5-jenkins-orchestration&quot;&gt;5. Jenkins Orchestration&lt;/h4&gt;
&lt;p&gt;Single Jenkins pipeline. Stages run sequentially, each one gated on the previous:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-groovy&quot;&gt;pipeline {
  agent any
  stages {
    stage('Provision Infra') {
      steps {
        sh 'terraform init &amp;amp;&amp;amp; terraform apply -auto-approve'
      }
    }
    stage('Setup Replica Set') {
      steps {
        sh 'python3 scripts/init_replica_set.py'
      }
    }
    stage('Restore MongoDB') {
      steps {
        sh 'bash scripts/restore.sh'
      }
    }
    stage('Validate Restore') {
      steps {
        sh 'python3 scripts/validate_restore.py'
      }
    }
    stage('Archive Logs') {
      steps {
        archiveArtifacts artifacts: 'reports/*.json, logs/*.log'
      }
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every run is logged, every report is archived. When auditors ask if restores work — you show them a report with timestamps, counts, and index diffs. Not a gut feeling.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;lessons-learned&quot;&gt;Lessons Learned&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Automate infra, not just the restore.&lt;/strong&gt; Terraform gives you a clean slate every drill. Manual infra setup introduces variability that hides real problems.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Validation is not optional.&lt;/strong&gt; A restore that &quot;seems fine&quot; is not the same as a restore that &lt;em&gt;is&lt;/em&gt; fine. Document count mismatches and missing indexes are easy to catch automatically and impossible to catch by eyeballing logs.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Logs equal trust.&lt;/strong&gt; The audit trail is what makes your DR process credible to others — engineers, management, auditors. Without it, you're asking people to take your word for it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Minimal input reduces errors.&lt;/strong&gt; We trimmed required inputs to just host + DB name and let scripts infer the rest. Less to type = fewer mistakes under pressure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Practice makes permanent.&lt;/strong&gt; Each drill found a small improvement. After ten drills, the process was genuinely fast and boring — which is exactly what you want.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-outcome&quot;&gt;The Outcome&lt;/h3&gt;
&lt;p&gt;We went from a 3-hour manual war room exercise to a single Jenkins job anyone can trigger. The drills are now predictable, repeatable, and quick.&lt;/p&gt;
&lt;p&gt;More importantly — everyone on the team &lt;em&gt;believes&lt;/em&gt; the restores work, because the validation script proves it every single time.&lt;/p&gt;
&lt;p&gt;Boring DR is good DR.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Running MongoDB in production? When did you last drill a full restore? Drop your setup in the comments — curious how teams handle validation.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21768/mongodb-dr-drill-automation-with-terraform-python-jenkins-how-we-made-restores-boring</guid>
<pubDate>Thu, 02 Jul 2026 15:09:45 +0000</pubDate>
</item>
<item>
<title>Implementing an End-to-End CI/CD Pipeline for a Java ATM Simulation Application</title>
<link>https://coderlegion.com/8101/implementing-an-end-to-end-ci-cd-pipeline-for-a-java-atm-simulation-application</link>
<description>&lt;p&gt;Abstract&lt;br&gt;
This case study outlines the design and implementation of a complete CI/CD pipeline for a Java ATM Simulation application. The project aimed to strengthen hands-on skills in DevOps automation, continuous integration, code quality analysis, artifact management, and deployment workflows using real-world tools on AWS.&lt;/p&gt;
&lt;p&gt;Project Goals&lt;/p&gt;
&lt;p&gt;Develop a fully automated CI/CD pipeline from code commit to deployment.&lt;/p&gt;
&lt;p&gt;Integrate Jenkins, Maven, SonarQube, Nexus, and Tomcat into a streamlined workflow.&lt;/p&gt;
&lt;p&gt;Deploy services on separate AWS EC2 instances to mimic production infrastructure.&lt;/p&gt;
&lt;p&gt;Implement artifact versioning and reliable storage.&lt;/p&gt;
&lt;p&gt;Enable automated deployment to an application server with minimal manual intervention.&lt;/p&gt;
&lt;p&gt;Tools &amp;amp; Technology Stack&lt;/p&gt;
&lt;p&gt;AWS EC2: Dedicated servers for Jenkins, SonarQube, Nexus, and Tomcat.&lt;/p&gt;
&lt;p&gt;Jenkins: CI server and pipeline orchestration.&lt;/p&gt;
&lt;p&gt;Maven: Build automation and dependency management.&lt;/p&gt;
&lt;p&gt;SonarQube: Static code analysis and code quality reporting.&lt;/p&gt;
&lt;p&gt;Nexus Repository Manager: Artifact storage and version control.&lt;/p&gt;
&lt;p&gt;Apache Tomcat: Application server deployment.&lt;/p&gt;
&lt;p&gt;GitHub: Source code management.&lt;/p&gt;
&lt;p&gt;Java 11+: Application and tooling requirement.&lt;/p&gt;
&lt;p&gt;Jenkins Plugins: Git, Maven, SSH Agent, SonarQube Scanner.&lt;/p&gt;
&lt;p&gt;Infrastructure Setup&lt;br&gt;
Four EC2 instances were provisioned, each hosting a separate tool to simulate production:&lt;/p&gt;
&lt;p&gt;Jenkins on port 8080&lt;/p&gt;
&lt;p&gt;SonarQube on port 9000&lt;/p&gt;
&lt;p&gt;Nexus on port 8081&lt;/p&gt;
&lt;p&gt;Tomcat on port 8080&lt;/p&gt;
&lt;p&gt;Java was installed on all instances, and security groups were configured for inter-tool communication. Each server was validated for accessibility via a browser to ensure proper connectivity.&lt;/p&gt;
&lt;p&gt;Pipeline Design &amp;amp; Implementation&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Source Control Integration&lt;br&gt;
The ATM Simulation project was pushed to GitHub. Jenkins was configured to clone the repository automatically on each build trigger using a declarative pipeline script.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
&lt;li&gt;Build &amp;amp; Test Automation&lt;br&gt;
mvn clean package was used to compile code, execute tests, and generate artifacts. Maven ensured dependency management and consistent builds across environments.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
&lt;li&gt;Code Quality Analysis&lt;br&gt;
SonarQube was integrated by updating pom.xml and Jenkins credentials. Running mvn sonar:sonar generated detailed code metrics, highlighting vulnerabilities and enforcing coding standards.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
&lt;li&gt;Artifact Management&lt;br&gt;
A Maven repository was created in Nexus. pom.xml and Jenkins settings.xml were configured to upload artifacts via mvn deploy, ensuring version-controlled storage and rollback capability.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
&lt;li&gt;Automated Deployment to Tomcat&lt;br&gt;
Tomcat manager roles and credentials were configured. Jenkins deployed the final WAR file, completing the continuous delivery process. Poll SCM triggers enabled automation for every commit.&lt;/li&gt;
&lt;/ol&gt;
&lt;ol&gt;
&lt;li&gt;Advanced Jenkins Configuration&lt;br&gt;
The SSH Agent plugin simulated a master-slave architecture, enabling distributed builds and enhancing pipeline scalability.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Challenges &amp;amp; Solutions&lt;/p&gt;
&lt;p&gt;Tool Version Conflicts: Resolved Java compatibility issues for SonarQube and Nexus.&lt;/p&gt;
&lt;p&gt;Nexus Deployment Failures: Fixed misconfigurations in pom.xml and settings.xml.&lt;/p&gt;
&lt;p&gt;Tomcat Deployment Errors: Corrected manager roles and permissions for successful deployment.&lt;/p&gt;
&lt;p&gt;Pipeline Failures: Updated Jenkins plugins and validated pipeline scripts to resolve build issues.&lt;/p&gt;
&lt;p&gt;Key Learnings&lt;/p&gt;
&lt;p&gt;Hands-on experience in end-to-end CI/CD workflows.&lt;/p&gt;
&lt;p&gt;Integration between source control, CI servers, artifact repositories, and application servers.&lt;/p&gt;
&lt;p&gt;Best practices in artifact versioning, storage, and automated deployment.&lt;/p&gt;
&lt;p&gt;Troubleshooting pipeline failures and ensuring tool compatibility.&lt;/p&gt;
&lt;p&gt;Leveraging Jenkins plugins for scalable master-slave architectures.&lt;/p&gt;
&lt;p&gt;Real-world automation of software delivery and cloud deployment.&lt;/p&gt;
&lt;p&gt;Conclusion&lt;br&gt;
This project provided practical exposure to enterprise-grade DevOps practices, including automation, CI/CD pipeline creation, artifact management, and deployment orchestration. It strengthened problem-solving, tool integration, and cloud deployment skills, demonstrating the ability to implement and manage robust DevOps workflows in real-world environments while reinforcing a commitment to continuous learning in automation and CI/CD.&lt;/p&gt;
</description>
<category>CI/CD Pipelines</category>
<guid isPermaLink="true">https://coderlegion.com/8101/implementing-an-end-to-end-ci-cd-pipeline-for-a-java-atm-simulation-application</guid>
<pubDate>Tue, 02 Dec 2025 23:48:32 +0000</pubDate>
</item>
<item>
<title>Mastering Jenkins CI/CD and Cloud Fundamentals: My June–July DevOps Journey ✅</title>
<link>https://coderlegion.com/4290/mastering-jenkins-ci-cd-and-cloud-fundamentals-my-june-july-devops-journey</link>
<description>&lt;h4 id=&quot;-introduction&quot;&gt;✨ Introduction&lt;/h4&gt;
&lt;p&gt;Over the past two months, I took a deep dive into the world of CI/CD pipelines, application security, and cloud fundamentals. My goal was to simulate a real-world enterprise environment using tools like Jenkins, Docker, Tomcat, and SonarQube—all while improving my grasp of DevOps principles. The cherry on top: I successfully cleared the AWS Cloud Practitioner certification.&lt;/p&gt;
&lt;p&gt;This blog documents my learnings, setups, and the hands-on challenges I tackled. Whether you're starting your DevOps journey or looking to refine your pipeline, I hope this helps.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;1-setting-up-jenkins-for-real-world-ci-cd&quot;&gt;1. Setting Up Jenkins for Real-World CI/CD&lt;/h4&gt;
&lt;p&gt;I started by setting up a Jenkins controller and then created custom Jenkins agents using Docker. This allowed me to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Isolate build environments&lt;/li&gt;
&lt;li&gt;Control security boundaries&lt;/li&gt;
&lt;li&gt;Reuse Docker images across pipelines&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I structured separate pipelines for &lt;strong&gt;DEV&lt;/strong&gt; and &lt;strong&gt;QA&lt;/strong&gt; profiles, ensuring each environment had unique configurations and behavior. Jenkins' flexibility made it easy to parameterize the builds and manage them per environment.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;2-security-amp-secrets-management&quot;&gt;2. Security &amp;amp; Secrets Management&lt;/h4&gt;
&lt;p&gt;One major focus was improving how environment variables and secrets are handled:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Used Jenkins &lt;strong&gt;Credentials Plugin&lt;/strong&gt; to store secrets like JWT keys and database credentials&lt;/li&gt;
&lt;li&gt;Passed these into Docker containers via &lt;code&gt;docker-compose&lt;/code&gt; and environment variables in &lt;code&gt;JAVA_OPTS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Ensured no secrets were hardcoded in the source or pipeline definitions&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This was crucial for simulating a real enterprise-grade deployment pipeline.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;3-code-quality-amp-test-coverage&quot;&gt;3. Code Quality &amp;amp; Test Coverage&lt;/h4&gt;
&lt;p&gt;I integrated &lt;strong&gt;SonarQube&lt;/strong&gt; with Jenkins to continuously analyze code quality. Here's what I did:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Installed the SonarQube plugin in Jenkins&lt;/li&gt;
&lt;li&gt;Set up a local SonarQube server running in a Docker container&lt;/li&gt;
&lt;li&gt;Used Maven goals (&lt;code&gt;sonar:sonar&lt;/code&gt;) to trigger analysis from Jenkins&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;To measure test coverage, I integrated &lt;strong&gt;JaCoCo&lt;/strong&gt; and ensured &lt;strong&gt;JUnit&lt;/strong&gt; tests were run and reported independently.&lt;/p&gt;
&lt;p&gt;These tools helped me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Identify code smells and bugs early&lt;/li&gt;
&lt;li&gt;Maintain a clean, modular codebase&lt;/li&gt;
&lt;li&gt;Track testing metrics over time&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;4-tomcat-amp-docker-compose-insights&quot;&gt;4. Tomcat &amp;amp; Docker Compose Insights&lt;/h4&gt;
&lt;p&gt;I deployed my Spring Boot application using Tomcat within a Dockerized setup. Key takeaways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Understood how Tomcat manages servlet deployment&lt;/li&gt;
&lt;li&gt;Learned how to pass environment-specific properties (&lt;code&gt;application-qa.properties&lt;/code&gt;, etc.) via &lt;code&gt;JAVA_OPTS&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Used &lt;code&gt;docker-compose.yml&lt;/code&gt; to streamline configuration and ensure consistent environments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This was especially helpful in managing profile-specific behavior.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;5-ssh-amp-github-automation&quot;&gt;5. SSH &amp;amp; GitHub Automation&lt;/h4&gt;
&lt;p&gt;I explored the use of &lt;code&gt;ssh-keygen&lt;/code&gt; and how SSH keys can be leveraged to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Authenticate GitHub repositories from Jenkins&lt;/li&gt;
&lt;li&gt;Enable secure, automated Git pulls&lt;/li&gt;
&lt;li&gt;Avoid manual authentication during builds&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This added a new layer of automation and security to the CI/CD flow.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;6-cloud-achievement-aws-cloud-practitioner&quot;&gt;6. Cloud Achievement: AWS Cloud Practitioner&lt;/h4&gt;
&lt;p&gt;Parallel to my DevOps practice, I prepared for and passed the &lt;strong&gt;AWS Cloud Practitioner certification&lt;/strong&gt;. Key concepts I explored:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AWS Core Services (EC2, S3, RDS, Lambda)&lt;/li&gt;
&lt;li&gt;Identity and Access Management (IAM)&lt;/li&gt;
&lt;li&gt;Shared Responsibility Model&lt;/li&gt;
&lt;li&gt;Cloud pricing and billing concepts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This knowledge gave me a stronger foundation in cloud architecture and how it supports DevOps.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;-key-takeaways&quot;&gt;✅ Key Takeaways&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Jenkins pipelines can be secured and structured to simulate enterprise-grade scenarios&lt;/li&gt;
&lt;li&gt;Docker agents are essential for isolating builds and improving reproducibility&lt;/li&gt;
&lt;li&gt;Tools like SonarQube and JaCoCo provide critical insights into code health and coverage&lt;/li&gt;
&lt;li&gt;Managing SSH and environment variables correctly enhances both automation and security&lt;/li&gt;
&lt;li&gt;Understanding cloud fundamentals bridges the gap between development and operations&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h4&gt;
&lt;p&gt;This journey was packed with hands-on learning, challenges, and rewarding moments. I now feel much more confident in designing CI/CD pipelines, securing deployments, and integrating quality gates into builds.&lt;/p&gt;
&lt;p&gt;I'd love to hear how others approach similar setups—feel free to connect, comment, or share your tips. You can also find some of my sample configs and scripts on &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/RajG98&quot;&gt;my GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Thanks for reading!&lt;/p&gt;
</description>
<category>CI/CD Pipelines</category>
<guid isPermaLink="true">https://coderlegion.com/4290/mastering-jenkins-ci-cd-and-cloud-fundamentals-my-june-july-devops-journey</guid>
<pubDate>Sun, 27 Jul 2025 19:14:31 +0000</pubDate>
</item>
</channel>
</rss>