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.
- Creation of a Dockerfile.
- Building Image.
- 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)
}
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,
- It opens a new session to the dagger engine and submits the above API requests.
- The dagger engine calculates the DAG(Directed Acyclic Graph) on how to achieve those tasks, simply computing the steps to produce the result.
- when the steps are executed the responses are sent back to our program.
- 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.
Top comments (0)