Skip to content
Open
Show file tree
Hide file tree
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
115 changes: 115 additions & 0 deletions .github/workflows/release-terraform-provider.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
name: Release terraform-provider

on:
push:
branches: [master]

permissions: {}

concurrency:
group: release-terraform-provider
cancel-in-progress: false

env:
# The version OpenTofu/Terraform select on. It is part of the package
# filename, so it must be a plain semver; the rolling build id goes into the
# binary instead. Keep in sync with the plugin dir in terraform-provider/mod.just.
PROVIDER_VERSION: "0.1.0"
Comment thread
ThomBogers marked this conversation as resolved.

jobs:
release:
runs-on: ubuntu-24.04
permissions:
contents: write
steps:
- uses: actions/checkout@v5

- name: Setup Go
uses: actions/setup-go@v5
with:
go-version-file: go.mod

- name: Build provider packages
run: |
VERSION="${GITHUB_SHA::7}-master-${{ github.run_number }}"
echo "VERSION=${VERSION}" >> "$GITHUB_ENV"

# Packages follow the provider registry layout so that a zip dropped
# unchanged into a local plugin mirror is picked up by `tofu init`:
# terraform-provider-fundament_<semver>_<os>_<arch>.zip
# containing a single terraform-provider-fundament_v<semver>[.exe].
mkdir -p dist
for target in linux/amd64 linux/arm64 darwin/arm64 windows/amd64; do
GOOS="${target%/*}"
GOARCH="${target#*/}"
OUT_DIR="dist/terraform-provider-fundament_${GOOS}_${GOARCH}"
BIN="terraform-provider-fundament_v${PROVIDER_VERSION}"
if [ "$GOOS" = "windows" ]; then
BIN="${BIN}.exe"
fi
mkdir -p "$OUT_DIR"
CGO_ENABLED=0 GOOS="$GOOS" GOARCH="$GOARCH" \
go build -trimpath \
-ldflags "-s -w -X main.version=${VERSION}" \
-o "$OUT_DIR/$BIN" ./terraform-provider
(cd "$OUT_DIR" && zip -q "../terraform-provider-fundament_${PROVIDER_VERSION}_${GOOS}_${GOARCH}.zip" "$BIN")
done
(cd dist && sha256sum *.zip > "terraform-provider-fundament_${PROVIDER_VERSION}_SHA256SUMS")

- name: Update rolling release
env:
GH_TOKEN: ${{ github.token }}
run: |
# The package names are fixed, so replacing assets on the live release
# (gh release upload --clobber) would expose a mix of old and new
# packages while uploading, and a failed upload would leave it that
# way. Instead, upload everything to a draft release while the current
# one stays live, then swap: move the tag, delete the old release and
# publish the draft. The swap itself is two API calls, in which the
# download URLs 404; a downloader never sees a mix. Any failure before
# the swap leaves the current release untouched.
#
# While the draft and the published release share the tag, gh's
# tag-addressed release commands may resolve to either of them, so the
# draft is only ever addressed by id.
TAG=terraform-provider-latest
NOTES="Rolling build of the Fundament OpenTofu/Terraform provider from the latest push to master.

- Provider version: \`${PROVIDER_VERSION}\`
- Build: \`${VERSION}\`
- Commit: ${GITHUB_SHA}

See terraform-provider/README.md for install instructions."

OLD_ID=$(gh api "repos/${GITHUB_REPOSITORY}/releases/tags/${TAG}" --jq .id 2>/dev/null || true)

NEW_ID=$(gh api -X POST "repos/${GITHUB_REPOSITORY}/releases" \
-f tag_name="$TAG" \
-f target_commitish="$GITHUB_SHA" \
-f name="terraform-provider (rolling)" \
-f body="$NOTES" \
-F draft=true \
-F prerelease=true \
--jq .id)
trap 'gh api -X DELETE "repos/${GITHUB_REPOSITORY}/releases/${NEW_ID}" || true' ERR

for f in dist/*.zip "dist/terraform-provider-fundament_${PROVIDER_VERSION}_SHA256SUMS"; do
gh api -X POST \
-H "Content-Type: application/octet-stream" \
"https://uploads.github.com/repos/${GITHUB_REPOSITORY}/releases/${NEW_ID}/assets?name=$(basename "$f")" \
--input "$f" > /dev/null
done
echo "Draft release ${NEW_ID} assets:"
gh api "repos/${GITHUB_REPOSITORY}/releases/${NEW_ID}/assets" --jq '.[] | " \(.name) \(.size)"'

# Swap. Publishing does not move an existing tag, so move it here.
git tag -f "$TAG"
git push -f origin "$TAG"
if [ -n "$OLD_ID" ]; then
gh api -X DELETE "repos/${GITHUB_REPOSITORY}/releases/${OLD_ID}"
fi
trap - ERR
gh api -X PATCH "repos/${GITHUB_REPOSITORY}/releases/${NEW_ID}" \
-F draft=false \
-F prerelease=true \
-f make_latest=false > /dev/null
21 changes: 21 additions & 0 deletions docs/user/opentofu-provider.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,27 @@ orientation.
- OpenTofu >= 1.11
- A running Fundament instance and an [API key](./api-keys.md)

## Install

The provider is not published to a registry. Prebuilt packages for Linux
(amd64, arm64), macOS (Apple Silicon) and Windows (amd64) are published to the
rolling `terraform-provider-latest` release, named so that OpenTofu finds them
in its local plugin directory without any CLI configuration:

```bash
# Pick your platform: linux_amd64, linux_arm64 or darwin_arm64
PLATFORM=linux_amd64
MIRROR=~/.terraform.d/plugins/registry.opentofu.org/fundament/fundament
mkdir -p "$MIRROR"
curl -fsSL -o "$MIRROR/terraform-provider-fundament_0.1.0_${PLATFORM}.zip" \
"https://github.com/fundament-oss/fundament/releases/download/terraform-provider-latest/terraform-provider-fundament_0.1.0_${PLATFORM}.zip"
```

Keep the zip as downloaded: its name is how OpenTofu discovers the version
and platform. Windows, Terraform instead of OpenTofu, checksums and updating to
a newer build are covered in the
[provider README](https://github.com/fundament-oss/fundament/blob/master/terraform-provider/README.md#installation).

## Configuration

```hcl
Expand Down
43 changes: 39 additions & 4 deletions terraform-provider/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,51 @@ This OpenTofu provider allows you to interact with the Fundament organization AP
## Requirements

- [OpenTofu](https://opentofu.org/docs/intro/install/) >= 1.11
- [Go](https://golang.org/doc/install) >= 1.25 (for building from source)
- [Go](https://golang.org/doc/install) >= 1.26 (for building from source)
- A running Fundament instance

## Building the Provider
## Installation

### Download a prebuilt package

The provider is not (yet) published to a provider registry. Every push to master publishes packages for Linux (amd64, arm64), macOS (Apple Silicon) and Windows (amd64) to the rolling [`terraform-provider-latest`](https://github.com/fundament-oss/fundament/releases/tag/terraform-provider-latest) release, named in the registry layout that OpenTofu and Terraform understand for local plugin mirrors. Drop the zip, unchanged, into the implied plugin directory and `tofu init` picks it up without any CLI configuration:
Comment thread
ThomBogers marked this conversation as resolved.

```bash
# Pick your platform: linux_amd64, linux_arm64 or darwin_arm64
PLATFORM=linux_amd64
MIRROR=~/.terraform.d/plugins/registry.opentofu.org/fundament/fundament
mkdir -p "$MIRROR"
curl -fsSL -o "$MIRROR/terraform-provider-fundament_0.1.0_${PLATFORM}.zip" \
"https://github.com/fundament-oss/fundament/releases/download/terraform-provider-latest/terraform-provider-fundament_0.1.0_${PLATFORM}.zip"
```

On Windows (PowerShell):

```powershell
$mirror = "$env:APPDATA\terraform.d\plugins\registry.opentofu.org\fundament\fundament"
New-Item -ItemType Directory -Force $mirror | Out-Null
Invoke-WebRequest -Uri https://github.com/fundament-oss/fundament/releases/download/terraform-provider-latest/terraform-provider-fundament_0.1.0_windows_amd64.zip -OutFile "$mirror\terraform-provider-fundament_0.1.0_windows_amd64.zip"
```

Do not rename or unpack the zip: the filename is how OpenTofu discovers the provider version and platform. For Terraform instead of OpenTofu, use the same layout under `registry.terraform.io/fundament/fundament/`.

Checksums are published alongside the packages as `terraform-provider-fundament_0.1.0_SHA256SUMS`. `tofu init` reports the provider as `(unauthenticated)` because the packages are not GPG-signed.

The rolling release always carries provider version `0.1.0`, so `tofu init` alone will keep using the copy it already unpacked. To pick up a newer build after re-downloading the zip:

```bash
rm .terraform.lock.hcl
tofu init -upgrade
```

### Build from source
Comment thread
ThomBogers marked this conversation as resolved.

```bash
# From the terraform-provider directory
just terraform-provider::build
just terraform-provider::install
```

This builds the provider and installs it as version `0.1.0` for your platform in the local plugin directory, replacing any downloaded package for that platform.

## Using the Provider

### Provider Configuration
Expand Down
6 changes: 5 additions & 1 deletion terraform-provider/mod.just
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@ install: build
set -euo pipefail
OS=$(go env GOOS)
ARCH=$(go env GOARCH)
PLUGIN_DIR=~/.terraform.d/plugins/registry.opentofu.org/fundament/fundament/0.1.0/${OS}_${ARCH}
MIRROR=~/.terraform.d/plugins/registry.opentofu.org/fundament/fundament
PLUGIN_DIR=${MIRROR}/0.1.0/${OS}_${ARCH}
# Remove a downloaded release package for this platform so the dev build
# is the only 0.1.0 in the mirror.
rm -fv "$MIRROR"/terraform-provider-fundament_*_${OS}_${ARCH}.zip
mkdir -p "$PLUGIN_DIR"
cp terraform-provider-fundament "$PLUGIN_DIR/"

Expand Down
Loading