Skip to content

Commit

Permalink
Add semver module
Browse files Browse the repository at this point in the history
This does not update the main README's examples to use semver; we should
probably discuss how best to do that.
  • Loading branch information
mogul committed Sep 14, 2023
1 parent 7db01d5 commit 517a067
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 1 deletion.
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# terraform-cloudgov

Terraform modules for cloud.gov managed services commonly used by [18f/rails-template](https://github.com/18f/rails-template) based apps
Terraform modules for working with cloud.gov commonly used by [18f/rails-template](https://github.com/18f/rails-template) based apps

## Module Examples

Expand Down Expand Up @@ -117,3 +117,7 @@ module "egress_space" {
]
}
```

## Staying up to date

Note that [Terraform doesn't support version constraints for github module sources](https://developer.hashicorp.com/terraform/language/modules/sources#github). To use the latest available versions of these modules using a version constraint, use our [semver module](./semver).
35 changes: 35 additions & 0 deletions semver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# terraform-cloudgov/semver

Find a tag for this repository matching NPM-style version constraints

## Example

```terraform
# Specify a version constraint for each module we plan to use
locals {
module_versions = {
database = ">0.5.0",
s3 = ">0.6.0"
}
}
# Divine the most recent versions matching those constraints...
module "version" {
for_each = local.module_versions
source = "github.com/18f/terraform-cloudgov//semver"
version_constraint = each.value
}
# ...then refer to the source for those modules using the calculated versions.
module "database" {
source = "github.com/18f/terraform-cloudgov//database?ref=v${module.version["database"].target_version}"
# [...]
}
module "s3" {
source = "github.com/18f/terraform-cloudgov//s3?ref=v${module.version["s3"].target_version}"
# [...]
}
```

28 changes: 28 additions & 0 deletions semver/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# This is just a thin wrapper around the following module, prefilling
# the 18f/terraform-cloudgov repository
# https://registry.terraform.io/modules/rhythmictech/find-release-by-semver

# Just accepts the one parameter
variable "version_constraint" {
type = string
description = "The NPM-style version constraint you want to use to find the right version"
}

module "find-cloudgov-module-version" {
source = "rhythmictech/find-release-by-semver/github"
version = "~> 1.1.2"

repo_name = "terraform-cloudgov"
repo_owner = "18f"
version_constraint = var.version_constraint
}

output "target_version" {
description = "Version matched to constraint"
value = module.find-cloudgov-module-version.target_version
}

output "version_info" {
description = "All available info about the target release"
value = module.find-cloudgov-module-version.version_info
}
46 changes: 46 additions & 0 deletions semver/tests/default/default.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
terraform {
required_providers {
test = {
# See https://developer.hashicorp.com/terraform/language/modules/testing-experiment#writing-tests-for-a-module
source = "terraform.io/builtin/test"
}
http = {
source = "hashicorp/http"
}
}
}

# Fixture constraints
locals {
module_versions = {
greaterthan = ">0.5.0",
}

latest_tag = trimprefix(jsondecode(data.http.latest_version.response_body).tag_name, "v")
}

# Divine the most recent versions matching fixture
module "version" {
for_each = local.module_versions
source = "../.."
version_constraint = each.value
}

data "http" "latest_version" {
url = "https://api.github.com/repos/18f/terraform-cloudgov/releases/latest"

request_headers = {
accept = "vnd.github+json"
}
}

resource "test_assertions" "greater-than-is-latest" {
component = "outputs"
equal "target_version" {
description = "greater than should always be the latest in the repo"
got = module.version["greaterthan"].target_version
# want = "0.7.0" # Need to programmatically derive this
want = local.latest_tag
}
}

0 comments on commit 517a067

Please sign in to comment.