DEV Community

Hima
Hima

Posted on

CD pipeline in GO

The IDEA

I often pondered the necessity of acquiring proficiency in a new DSL (Domain-Specific Language) for orchestrating releases and executing CD (Continuous Delivery) steps such as simply building a container image and running shell commands etc.. It seemed counterintuitive to me, as I questioned why I couldn't achieve my objectives using the language(s) I'm already proficient in (Python/Go).

Analysis

Analyzing the above idea a bit two key benefits stood out:

Time Efficiency: The potential to save time and redirect it towards enhancing my proficiency in the core language, exploring concepts like Go routines, packaging, and more.

Singular Focus: The ability to concentrate solely on my primary project, minimizing the need to delve into and comprehend additional DSLs.

The solution

While looking at this ideal scenario, I recently came across dagger.io, a brilliant tool crafted by the minds behind Docker. Intrigued, I decided to put it to the test by implementing CICD as code in a small project, specifically focusing on "Building a container image from a Dockerfile."

Project

To kickstart the process, I began by installing the dagger.io/dagger Go package and most importantly dagger CLI.

For testing this you need to have the Container Runtime Environment (CRE) which is Docker in my case(you can try with containerd which is the current CRE for K8s)

Just a recap, I have one basic test in my mind, build my image and ship it in my choice of code and I have no interest in learning a new configuration other than what I already knew.

Breaking that goal into steps, the following are the tasks we need to code.

  1. Creation of a Dockerfile.
  2. Building Image.
  3. Ship it.

This experience with dagger.io marked a noteworthy exploration into simplifying CICD workflows, aligning seamlessly with my aspiration to articulate deployment tasks using the language integral to my primary project.

Action

Dagger Definition:

package main

import (
    "context"

    "dagger.io/dagger"
)

var DockerTag string = "123123123213.dkr.ecr.us-east-1.amazonaws.com"

func main() {
    ctx := context.Background()
    client, err := dagger.Connect(ctx)
    if err != nil {
        panic(err)
    }

    defer client.Close()

    thisImage := client.Container().Build(
        client.Host().Directory("./"),
        dagger.ContainerBuildOpts{
            Dockerfile: "../Dockerfile",
        })

    thisImage.Publish(ctx, DockerTag)
}
Enter fullscreen mode Exit fullscreen mode

What just happened?

In the above snippet, you are importing the dagger package and defining the steps that the pipeline should do, basically converting our tasks from the goal to instructions.

When you submit this to the dagger command line,

Image description

  1. It opens a new session to the dagger engine and submits the above API requests.
  2. The dagger engine calculates the DAG(Directed Acyclic Graph) on how to achieve those tasks, simply computing the steps to produce the result.
  3. when the steps are executed the responses are sent back to our program.
  4. This is where we can trigger other APIs or may even trigger a different pipeline.

Conclusion

This is just a basic project, I just wanted to see how easy it is to create a pipeline in Go and additionally test the pipeline locally without needing a CICD instance.

what I like is that you can test your pipeline locally without needing to spin a local Jenkins or any other tool as a container and configure it and add build agents or install plugins etc.. with dagger I can eliminate all that extra stuff.

Dagger

Top comments (0)