Overview | Dagger CI・CD界隈期待の星!!Daggerに入門してローカルとGithubActionsでCIを動かしてみた | DevelopersIO
ポータブルなCI/CDパイプライン devkit Dockerコンテナ上で実行されて、どこでも動かすことができる
- CI/CDサービス固有の記法を学習する必要があり、移行の際には書き換えが必要
- ローカルで試しにくく、commit & pushしては動くか確認する作業が発生
- YAMLが辛い
Dagger はプラットフォーム非依存でCUE言語を使って書けるのが良さそう。 ローカルで実行できるっていうのも大きい
- CUE言語がそんなにまだメジャーでない
- IaCでたまに見るかな?Go には公式のparserがある
- まだメジャーバージョン0系で開発途上
インストール
macはHomebrewでもインストールできる
install.sh を使ってインストールすることもできる
curl -L https://dl.dagger.io/dagger/install.sh | DAGGER_VERSION=0.2.19 sh
./bin/dagger version
dagger 0.2.19 (GIT_SHA) darwin/arm64
サンプル
git clone https://github.com/dagger/todoapp
cd todoapp
dagger project update
dagger do build
使ってみる
hello.cue
package main
import (
"dagger.io/dagger"
"dagger.io/dagger/core"
)
// Write a greeting to a file, and add it to a directory
#AddHello: {
// The input directory
dir: dagger.#FS
// The name of the person to greet
name: string | *"world"
write: core.#WriteFile & {
input: dir
path: "hello-\(name).txt"
contents: "hello, \(name)!"
}
// The directory with greeting message added
result: write.output
}
dagger.#Plan & {
// Say hello by writing to a file
actions: hello: #AddHello & {
dir: client.filesystem.".".read.contents
name: "hey"
}
client: filesystem: ".": {
read: contents: dagger.#FS
write: contents: actions.hello.result
}
}
dagger project init
dagger project update
dagger do hello
dagger project update
を実行すると、 ./cue.mod
が更新される
go get したときに $GOPATH/pkg/mod
にソースがダウンロードされるが、それと同じように ./cue.mod
に置かれる
Actions
Actions が基本的な要素となる 4つのライフサイクルがある
- Definition
- Integration
- Discovery
- Execution
pipelines と steps のような区別がなく、全てをActionで定義できる 定義済みのActionを他のActionからサブアクションとして呼び出せる
公式の説明で使われているDefinition
// Write a greeting to a file, and add it to a directory
#AddHello: {
// The input directory
dir: dagger.#FS
// The name of the person to greet
name: string | *"world"
write: core.#WriteFile & {
input: dir
path: "hello-\(name).txt"
contents: "hello, \(name)!"
}
// The directory with greeting message added
result: write.output
}
ここでは core.#WriteFile
という core で定義済みの Action を #AddHello
の中で呼び出している
Integration
全てのパイプラインは dagger.#Plan
definition で定義される
dagger do --help
を実行すると、定義済みの Action 一覧が出力される
$ ./dagger do --help
Usage:
dagger do <action> [subaction...] [flags]
Options
Available Actions:
hello Say hello by writing to a file
AWS SAMのデプロイのサンプル
https://docs.dagger.io/1248/aws-sam sam用のActionがimportして使用できる
zipをデプロイするパターン
package samZip
import (
"dagger.io/dagger"
"universe.dagger.io/alpha/aws/sam"
)
dagger.#Plan & {
_common: config: sam.#Config & {
accessKey: client.env.AWS_ACCESS_KEY_ID
region: client.env.AWS_REGION
bucket: client.env.AWS_S3_BUCKET
secretKey: client.env.AWS_SECRET_ACCESS_KEY
stackName: client.env.AWS_STACK_NAME
}
client: {
filesystem: "./": read: contents: dagger.#FS
env: {
AWS_ACCESS_KEY_ID: string
AWS_REGION: string
AWS_S3_BUCKET: string
AWS_SECRET_ACCESS_KEY: dagger.#Secret
AWS_STACK_NAME: string
}
}
actions: {
build: sam.#Package & _common & {
fileTree: client.filesystem."./".read.contents
}
deploy: sam.#DeployZip & _common & {
input: build.output
}
}
}
Dockerイメージをデプロイするパターン
package samImage
import (
"dagger.io/dagger"
"universe.dagger.io/alpha/aws/sam"
)
dagger.#Plan & {
_common: config: sam.#Config & {
accessKey: client.env.AWS_ACCESS_KEY_ID
region: client.env.AWS_REGION
secretKey: client.env.AWS_SECRET_ACCESS_KEY
stackName: client.env.AWS_STACK_NAME
clientSocket: client.network."unix:///var/run/docker.sock".connect
}
client: {
filesystem: "./": read: contents: dagger.#FS
network: "unix:///var/run/docker.sock": connect: dagger.#Socket
env: {
AWS_ACCESS_KEY_ID: string
AWS_REGION: string
AWS_SECRET_ACCESS_KEY: dagger.#Secret
AWS_STACK_NAME: string
}
}
actions: {
build: sam.#Build & _common & {
fileTree: client.filesystem."./".read.contents
}
deploy: sam.#Deployment & _common & {
input: build.output
}
}
}
Jenkins上で利用する
Jenkinsにdocker、daggerをインストールしておく
pipeline {
agent any
environment {
NAME='John'
}
stages {
stage("setup") {
steps {
sh '''
# インストールずみなら不要
curl -L https://dl.dagger.io/dagger/install.sh | sh
./bin/dagger project init
./bin/dagger project update
'''
}
}
stage("do") {
steps {
sh '''
cat << EOF > dagger.cue
package main
import (
"dagger.io/dagger"
"dagger.io/dagger/core"
)
// Write a greeting to a file, and add it to a directory
#AddHello: {
// The input directory
dir: dagger.#FS
name: string | *"world"
write: core.#WriteFile & {
input: dir
path: "hello-\\(name).txt"
contents: "hello, \\(name)!"
}
// The directory with greeting message added
result: write.output
}
dagger.#Plan & {
// Say hello by writing to a file
actions: hello: #AddHello & {
dir: client.filesystem.".".read.contents
name: client.env.NAME
}
client: {
filesystem: ".": {
read: contents: dagger.#FS
write: contents: actions.hello.result
}
env : {
NAME: string
}
}
}
EOF
./bin/dagger do hello
'''.stripIndent()
}
}
}
}