Skip to content

Commit

Permalink
Merge pull request #28 from 18F/add-semver-module
Browse files Browse the repository at this point in the history
Enable using these modules with version constraints
  • Loading branch information
mogul authored Sep 19, 2023
2 parents 7db01d5 + aa1262f commit 0b02d60
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 7 deletions.
37 changes: 30 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,29 @@
# 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

## Usage

Specify acceptable versions of these modules using an [NPM-style version constraint](https://github.com/npm/node-semver#versions), using our [semver module](./semver). ([Terraform doesn't support version constraints for github-hosted modules](https://developer.hashicorp.com/terraform/language/modules/sources#github).)

```terraform
# Specify a (NPM-style) version constraint for the modules you use
locals {
module_versions = {
database = "^0.x", # major version 0
s3 = "^0.x" # major version 0
}
}
# Find 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, as demonstrated below
```

## Module Examples

Expand All @@ -10,7 +33,7 @@ Creates an RDS database based on the `rds_plan_name` variable and outputs the `i

```
module "database" {
source = "github.com/18f/terraform-cloudgov//database?ref=v0.6.0"
source = "github.com/18f/terraform-cloudgov//database?ref=v${module.version["database"].target_version}"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
Expand All @@ -25,7 +48,7 @@ Creates a Elasticache redis instance and outputs the `instance_id` for use elsew

```
module "redis" {
source = "github.com/18f/terraform-cloudgov//redis?ref=v0.6.0"
source = "github.com/18f/terraform-cloudgov//redis?ref=v${module.version["redis"].target_version}"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
Expand All @@ -40,7 +63,7 @@ Creates an s3 bucket and outputs the `bucket_id` for use elsewhere.

```
module "s3" {
source = "github.com/18f/terraform-cloudgov//s3?ref=v0.6.0"
source = "github.com/18f/terraform-cloudgov//s3?ref=v${module.version["s3"].target_version}"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
Expand All @@ -58,7 +81,7 @@ Note that the domain must be created in cloud.gov by an OrgManager before this m

```
module "domain" {
source = "github.com/18f/terraform-cloudgov//domain?ref=v0.7.0"
source = "github.com/18f/terraform-cloudgov//domain?ref=v${module.version["domain"].target_version}"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
Expand All @@ -79,7 +102,7 @@ Notes:

```
module "clamav" {
source = "github.com/18f/terraform-cloudgov//clamav?ref=v0.6.0"
source = "github.com/18f/terraform-cloudgov//clamav?ref=v${module.version["clamav"].target_version}"
cf_org_name = local.cf_org_name
cf_space_name = local.cf_space_name
Expand All @@ -102,7 +125,7 @@ Creates a new cloud.gov space, such as when creating an egress space, and output

```
module "egress_space" {
source = "github.com/18f/terraform-cloudgov//cg_space?ref=v0.6.0"
source = "github.com/18f/terraform-cloudgov//cg_space?ref=v${module.version["cg_space"].target_version}"
cf_org_name = local.cf_org_name
cf_space_name = "${local.cf_space_name}-egress"
Expand Down
34 changes: 34 additions & 0 deletions semver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# 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.x", # major version 0
s3 = "^0.x" # major version 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
}
48 changes: 48 additions & 0 deletions semver/tests/default/default.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
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 = {
# This test will break after we tag something higher than 1.0.0; fix and
# expand these tests then!
# https://github.com/npm/node-semver#tilde-ranges-123-12-1
greaterthan = "~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 = local.latest_tag
}
}

0 comments on commit 0b02d60

Please sign in to comment.