-
Notifications
You must be signed in to change notification settings - Fork 4
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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" { | ||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we need a volume to persist the cache? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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. There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 😅 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oooh, my bad, I thought the count was tied to workspace. NVM! There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🤩 |
||
} | ||
|
||
output "builder_image" { | ||
|
@@ -91,3 +105,4 @@ output "id" { | |
output "image" { | ||
value = envbuilder_cached_image.example.image | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is dope!