Skip to content

chore: flesh out envbuilder_cached_image example #22

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 8, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,79 +1,93 @@
// The below example illustrates the behavior of the envbuilder_cached_image
// resource.
// 1) Run a local registry:
//
// ```shell
// docker run -d -p 5000:5000 --name test-registry registry:2
// ```
//
// 2) Running a `terraform plan` should result in the following outputs:
//
// ```
// + builder_image = "ghcr.io/coder/envbuilder-preview:latest"
// + exists = (known after apply)
// + id = (known after apply)
// + image = (known after apply)
// ```
//
// 3) Running `terraform apply` should result in outputs similar to the below:
//
// ```
// builder_image = "ghcr.io/coder/envbuilder-preview:latest"
// exists = false
// id = "00000000-0000-0000-0000-000000000000"
// image = "ghcr.io/coder/envbuilder-preview:latest"
// ```
//
// 4) Populate the cache by running Envbuilder and pushing the built image to
// the local registry:
//
// ```shell
// docker run -it --rm \
// -e ENVBUILDER_CACHE_REPO=localhost:5000/test \
// -e ENVBUILDER_GIT_URL=https://github.com/coder/envbuilder-starter-devcontainer \
// -e ENVBUILDER_PUSH_IMAGE=true \
// -e ENVBUILDER_INIT_SCRIPT=exit \
// --net=host \
// ghcr.io/coder/envbuilder-preview:latest
// ```
//
// 5) Run `terraform plan` once more. Now, the cached image will be detected:
//
// ```
// Note: Objects have changed outside of Terraform
//
// Terraform detected the following changes made outside of Terraform since the last "terraform apply" which may have affected this plan:
// envbuilder_cached_image.example has been deleted
// - resource "envbuilder_cached_image" "example" {
// - exists = false -> null
// - id = "00000000-0000-0000-0000-000000000000" -> null
// - image = "ghcr.io/coder/envbuilder-preview:latest" -> null
// # (5 unchanged attributes hidden)
// ```
//
// 6) Run `terraform apply` and the newly pushed image will be saved in the Terraform state:
// ```shell
// builder_image = "ghcr.io/coder/envbuilder-preview:latest"
// exists = true
// id = "sha256:xxx..."
// image = "localhost:5000/test@sha256:xxx..."
// ```

terraform {
required_providers {
envbuilder = {
source = "coder/envbuilder"
}
docker = {
source = "kreuzwerker/docker"
}
}
}

// This variable designates the devcontainer repo to build.
// The default is recommended for testing, as it builds relatively quickly!
variable "repo_url" {
type = string
default = "https://github.com/coder/envbuilder-starter-devcontainer"
}

// This variable designates the builder image to use to build the devcontainer.
variable "builder_image" {
type = string
default = "ghcr.io/coder/envbuilder:latest"
}

// If you have an existing repository you want to use as a cache, you can set this here.
// Otherwise, we will stand up a temporary local registry.
variable "cache_repo" {
type = string
default = ""
}

locals {
// If no registry is specified, use a default.
cache_repo = var.cache_repo == "" ? "localhost:5000/test" : var.cache_repo
}

// Start a local registry if no cache repo is specified.
resource "docker_container" "registry" {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is dope!

count = var.cache_repo == "" ? 1 : 0
name = "envbuilder-cached-image-registry"
image = "registry:2"
ports {
internal = 5000
external = 5000
}
network_mode = "host"
lifecycle {
// We want to persist this across invocations
ignore_changes = all
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need a volume to persist the cache?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nah I'm not keeping a volume here, it's just in-memory. It goes away with the registry, which makes this example easy to tidy up.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's fine as an example of how it works I suppose, but it'll never hit the cache due to destruction 😅

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oooh, my bad, I thought the count was tied to workspace. NVM!

Copy link
Member

@matifali matifali Aug 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it conflict with another workspace from the same template due to name of the container being same?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't meant to be copy-pasted into a template! It's just an example to illustrate how the provider works.

}
}

// This resource performs the heavy lifting of determining
// if we need to build the devcontainer from scratch, or if
// there is a previously built image we can re-use.
// It fetches the Git repo located at var.git_repo, and
// performs a 'dry-run' build of the Devcontainer/Dockerfile.
// If all of the layers produced by the dry run are present
// in the remote cache repo, that image can then be used
// instead. Otherwise, the cache is stale and the image needs
// to be rebuilt.
resource "envbuilder_cached_image" "example" {
builder_image = "ghcr.io/coder/envbuilder-preview:latest"
git_url = "https://github.com/coder/envbuilder-starter-devcontainer"
cache_repo = "localhost:5000/test"
builder_image = var.builder_image
git_url = var.repo_url
cache_repo = local.cache_repo
extra_env = {
"ENVBUILDER_VERBOSE" : "true"
"ENVBUILDER_INSECURE" : "true" # due to local registry
"ENVBUILDER_INIT_SCRIPT" : "sleep infinity"
"ENVBUILDER_PUSH_IMAGE" : "true"
}
depends_on = [docker_container.registry]
}

// Run the cached image. Depending on the contents of
// the cache repo, this will either be var.builder_image
// or a previously built image pusehd to var.cache_repo.
// Running `terraform apply` once (assuming empty cache)
// will result in the builder image running, and the built
// image being pushed to the cache repo.
// Running `terraform apply` again will result in the
// previously built image running.
resource "docker_container" "example" {
name = "envbuilder-cached-image-example"
image = envbuilder_cached_image.example.image
env = envbuilder_cached_image.example.env
network_mode = "host" # required to hit local registry
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤩

}

output "builder_image" {
Expand All @@ -91,3 +105,4 @@ output "id" {
output "image" {
value = envbuilder_cached_image.example.image
}