Git Product home page Git Product logo

boring-registry's Introduction

boring-registry

Boring-registry is an open source module and provider registry compatible with Terraform and OpenTofu.

Table of Contents

Overview

With boring-registry, you can upload and distribute your own modules and providers, as an alternative to publishing them on HashiCorp's public Terraform Registry.

Support for the Module Registry Protocol, Provider Registry Protocol, and Provider Network Mirror Protocol allows it to work natively with Terraform and OpenTofu.

Features

  • Module Registry
  • Provider Registry
  • Network mirror for providers
  • Pull-through mirror for providers
  • Support for S3, GCS, Azure Blob Storage, and MinIO object storage

Installation

Helm

helm upgrade --install --wait --namespace default boring-registry oci://ghcr.io/boring-registry/charts/boring-registry

Docker Image

Images are published to ghcr.io/boring-registry/boring-registry for every tagged release of the project.

Local

Run make to build the project and install the boring-registry executable into $GOPATH/bin. Then start the server with $GOPATH/bin/boring-registry, or if $GOPATH/bin is already on your $PATH, you can simply run boring-registry.

Configuration

The boring-registry does not rely on a configuration file. Instead, everything can be configured using flags or environment variables.

Important Note:

  • Flags have higher priority than environment variables
  • All environment variables are prefixed with BORING_REGISTRY_

Example: To enable debug logging you can either pass the flag: --debug or set the environment variable: BORING_REGISTRY_DEBUG=true.

Storage backend

To run the server you need to specify which storage backend to use:

Minimal configuration using the S3 storage backend:

$ boring-registry server \
  --storage-s3-bucket=terraform-registry-test

Make sure the server has AWS credentials set (e.g. AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY).

Minimal example using the GCS storage backend:

$ boring-registry server \
  --storage-gcs-bucket=terraform-registry-test

Make sure the server has GCP credentials set (e.g. GOOGLE_CLOUD_PROJECT).

Minimal example using the S3 storage backend with MinIO:

$ boring-registry server \
  --storage-s3-bucket=terraform-registry-test \
  --storage-s3-region=eu-east-1 \
  --storage-s3-pathstyle=true \
  --storage-s3-endpoint=https://minio.example.com

Minimal example using the Azure storage backend:

$ boring-registry server \
  --storage-azure-account=registry \
  --storage-azure-container=terraform-registry-test

Make sure the server has Azure credentials set. The Azure backend supports the following authentication methods:

  • Environment Variables
    • Service principal with client secret (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_SECRET)
    • Service principal with certificate (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_CLIENT_CERTIFICATE_PATH, AZURE_CLIENT_CERTIFICATE_PASSWORD)
    • User with username and password (AZURE_TENANT_ID, AZURE_CLIENT_ID, AZURE_USERNAME, AZURE_PASSWORD)
  • Managed Identity
  • Azure CLI

Make sure the used identity has the role Storage Blob Data Contributor on the Storage Account.

The storage backend has to be specified for the upload command as well. Check the module upload section below.

Authentication

The boring-registry can be configured with a set of API keys to match for by using the --auth-static-token="very-secure-token" flag or by providing it as an environment variable BORING_REGISTRY_AUTH_STATIC_TOKEN="very-secure-token".

Multiple API keys can be configured by passing comma-separated tokens to the --auth-static-token="first-token,second-token" flag or environment variable BORING_REGISTRY_AUTH_STATIC_TOKEN="first-token,second-token".

The token can be passed to Terraform inside the ~/.terraformrc configuration file:

credentials "boring-registry.example.com" {
  token = "very-secure-token"
}

Internal Storage Layout

The boring-registry is using the following storage layout inside the storage backend:

<bucket_prefix>
├── modules
│   └── <namespace>
│       └── <name>
│           └── <provider>
│               ├── <namespace>-<name>-<provider>-<version>.tar.gz
│               └── <namespace>-<name>-<provider>-<version>.tar.gz
├── providers
│   └── <namespace>
│       ├── signing-keys.json
│       └── <name>
│           ├── terraform-provider-<name>_<version>_SHA256SUMS
│           ├── terraform-provider-<name>_<version>_SHA256SUMS.sig
│           └── terraform-provider-<name>_<version>_<os>_<arch>.zip
└── mirror
    └── providers
        └── <hostname>
            └── <namespace>
                ├── signing-keys.json
                └── <name>
                    ├── terraform-provider-<name>_<version>_SHA256SUMS
                    ├── terraform-provider-<name>_<version>_SHA256SUMS.sig
                    └── terraform-provider-<name>_<version>_<os>_<arch>.zip

The <bucket_prefix> is an optional prefix under which the boring-registry storage is organized and can be set with the --storage-s3-prefix or --storage-gcs-prefix flags.

An example without any placeholders could be the following:

<bucket_prefix>
├── modules
│   └── acme
│       └── tls-private-key
│           └── aws
│               ├── acme-tls-private-key-aws-0.1.0.tar.gz
│               └── acme-tls-private-key-aws-0.2.0.tar.gz
├── providers
│   └── acme
│       ├── signing-keys.json
│       └── dummy
│           ├── terraform-provider-dummy_0.1.0_SHA256SUMS
│           ├── terraform-provider-dummy_0.1.0_SHA256SUMS.sig
│           ├── terraform-provider-dummy_0.1.0_linux_amd64.zip
│           └── terraform-provider-dummy_0.1.0_linux_arm64.zip
└── mirror
    └── providers
        └── terraform.example.com
            └── acme
                ├── signing-keys.json
                └── random
                    ├── terraform-provider-random_0.1.0_SHA256SUMS
                    ├── terraform-provider-random_0.1.0_SHA256SUMS.sig
                    └── terraform-provider-random_0.1.0_linux_amd64.zip

Publishing Modules

Example Terraform configuration using a module referenced from the registry:

module "tls-private-key" {
  source = "boring-registry.example.com/acme/tls-private-key/aws"
  version = "~> 0.1"
}

Uploading modules using the CLI

Modules can be published to the registry with the upload command. The command expects a directory as argument, which is then walked recursively in search of boring-registry.hcl files.

The boring-registry.hcl file should be placed in the root directory of the module and should contain a metadata block like the following:

metadata {
  namespace = "acme"
  name      = "tls-private-key"
  provider  = "aws"
  version   = "0.1.0"
}

When running the upload command, the module is then packaged up and published to the registry.

Recursive vs. non-recursive upload

Walking the directory recursively is the default behavior of the upload command. This way all modules underneath the current directory will be checked for boring-registry.hcl files and modules will be packaged and uploaded if they not already exist However, this can be unwanted in certain situations e.g. if a .terraform directory is present containing other modules that have a configuration file. The --recursive=false flag will omit this behavior.

Fail early if module version already exists

By default the upload command will silently ignore already uploaded versions of a module and return exit code 0. For tagging mono-repositories this can become a problem as it is not clear if the module version is new or already uploaded. The --ignore-existing=false parameter will force the upload command to return exit code 1 in such a case. In combination with --recursive=false the exit code can be used to tag the Git repository only if a new version was uploaded.

for i in $(ls -d */); do
  printf "Operating on module \"${i%%/}\"\n"
  # upload the given directory
  ./boring-registry upload --type gcs -gcs-bucket=my-boring-registry-upload-bucket --recursive=false --ignore-existing=false ${i%%/}
  # tag the repo with a tag composed out of the boring-registry.hcl if not already exist
  if [ $? -eq 0 ]; then
    # git tag the repository with the version from boring-registry.hcl
    # hint: use mattolenik/hclq to parse the hcl file
  fi
done

Module version constraints

The --version-constraints-semver flag lets you specify a range of acceptable semver versions for modules. It expects a specially formatted string containing one or more conditions, which are separated by commas. The syntax is similar to the Terraform Version Constraint Syntax.

In order to exclude all SemVer pre-releases, you can e.g. use --version-constraints-semver=">=v0", which will instruct the boring-registry cli to only upload non-pre-releases to the registry. This would for example be useful to restrict CI to only publish releases from the main branch.

The --version-constraints-regex flag lets you specify a regex that module versions have to match. In order to only match pre-releases, you can e.g. use --version-constraints-regex="^[0-9]+\.[0-9]+\.[0-9]+-|\d*[a-zA-Z-][0-9a-zA-Z-]*$". This would for example be useful to prevent publishing releases from non-main branches, while allowing pre-releases to test out pull requests for example.

Publishing Providers

For general information on how to build and publish providers for Terraform see the official documentation.

GPG Public Keys

The boring-registry expects a file named signing-keys.json to be placed under the <namespace> level in the storage backend. More information about the purpose of this file can be found in the Provider Registry Protocol.

The file should have the following format:

{
  "gpg_public_keys": [
    {
      "key_id": "51852D87348FFC4C",
      "ascii_armor": "-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: GnuPG v1\n..."
    }
  ]
}

Multiple public keys are supported by extending the gpg_public_keys array.

The v0.10.0 and previous releases of the boring-registry only supported a single signing key in the following format:

{
  "key_id": "51852D87348FFC4C",
  "ascii_armor": "-----BEGIN PGP PUBLIC KEY BLOCK-----\nVersion: GnuPG v1\n..."
}

Publishing providers with the CLI

  1. Manually prepare the provider release artifacts according to the documentation from hashicorp
  2. Publish the artifacts with the following (minimal) command:
    boring-registry upload provider \
    --storage-s3-bucket <bucket_name> \
    --namespace <namespace> \
    --filename-sha256sums /absolute/path/to/terraform-provider-<name>_<version>_SHA256SUMS

Referencing providers in Terraform

Example Terraform configuration using a provider referenced from the registry:

terraform {
  required_providers {
    dummy = {
      source  = "boring-registry.example.com/acme/dummy"
      version = "0.1.0"
    }
  }
}

Provider Network Mirror

Note

The Provider Network Mirror feature is available starting from v0.12.0. The Network Mirror is enabled by default, but can be disabled with --network-mirror=false.

The boring-registry implements the Provider Network Mirror Protocol to provide an alternative installation source for providers.

Check the Terraform CLI documentation to learn how to configure Terraform to use the provider network mirror. In the following is an example for a .terraformrc:

provider_installation {
  network_mirror {
    url = "https://boring-registry.example.com:5601/v1/mirror/"
  }
}

To populate the mirror, the provider release artifacts need to be uploaded to the storage backend. Refer to the Internal Storage Layout section for an overview of the required structure. The terraform providers mirror command is a good starting point for collecting the necessary files.

Pull-through mirror

As part of the Provider Network Mirror, a pull-through mirror can optionally be activated with --network-mirror-pull-through=true.

The pull-through functionality makes it possible that the providers do not have to be uploaded upfront to the storage backend. Instead, boring-registry serves the providers of the origin registry and mirrors them automatically to the storage backend on the first download. On the subsequent download request, boring-registry serves the providers directly from the storage backend. This can significantly speed up the terraform init phase and in some cases save additional traffic costs.

boring-registry's People

Contributors

bg451 avatar c0urante avatar daniel-ciaglia avatar harpazo64 avatar heimweh avatar mathieux51 avatar maximilianofelice avatar odise avatar oliviermichaelis avatar ptu avatar renovate[bot] avatar tferraro avatar xrevo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

boring-registry's Issues

[Bug] Modules publishing to Cloud Storage are not appending extension

Alo!

Each time a module is published to cloud storage, it returns the following error message:

storage: object doesn't exist: failed to locate module

To reproduce:

  • Generate a minimum example of a module. Using a null_resource local-exec "ls" may suffice
  • Run ./boring-registry upload <module-name> --storage-gcs-bucket=<bucket name>

If checked into the bucket, the file is correctly uploaded. However, it is not recognized by ./boring-registry server command.

Origin

I've tracked the origin of the issue to this variable:
https://github.com/TierMobility/boring-registry/blob/main/pkg/storage/gcs.go#L31

This variable is used to create the path on the GetModule method https://github.com/TierMobility/boring-registry/blob/main/pkg/storage/gcs.go#L34 used by both server command (to identify versions or download) and the upload command, to return the information of the module & identify it's existence.

On the upload section, this works because the extension is hard-coded to the default variables:
https://github.com/TierMobility/boring-registry/blob/main/pkg/storage/gcs.go#L100

Results

This causes the whole module functionality to directly not work on GS, as the only way for the boring-registry to recognize the zip is to remove the extension (but leaving the dot, due to the string interpolation of an empty variable).
However, this doesn't work properly with Terraform as not having the extension makes the downloading of the module have undefined behavior.

Proposed Solution

I'll try to code this solution and generate a PR, but I wanted to ask how willing we are to accept it 😆

The issue comes from here:
https://github.com/TierMobility/boring-registry/blob/main/cmd/server.go#L203

This method is setting the storage for both server and upload variations; but on Cloud Storage, it forgets to set the following line: https://github.com/TierMobility/boring-registry/blob/main/cmd/server.go#L212. Therefore, leaving it null.

Also, it would be cool to avoid setting the default value in the upload storage method and directly use this configuration, to keep consistency.

Thanks!

S3 download URLs are not URL encoded

Semantic versioning allows for metadata to be included in versions with a prefix of +. This character has to be URL encoded when used in download URLs for S3, or requests to those URLs will result in a 4xx response from AWS.

Example of current behavior:

> curl -sSi https://boring-registry.com/v1/modules/ns/n/p/0.3.9-1.beta+gb051be9/download | grep '^x-terraform-get: ' | sed 's@.*provider=[^/]*/@@'
version=0.3.9-1.beta+gb051be9/ns-n-p-0.3.9-1.beta+gb051be9.zip

Example of desired behavior:

> curl -sSi https://boring-registry.com/v1/modules/ns/n/p/0.3.9-1.beta+gb051be9/download | grep '^x-terraform-get: ' | sed 's@.*provider=[^/]*/@@'
version=0.3.9-1.beta%2Bgb051be9/ns-n-p-0.3.9-1.beta%2Bgb051be9.zip

Worth noting that according to RFC 3986 section 2.2, the equals (=) character is also supposed to be URL encoded, but that doesn't appear to be strictly necessary in this case since the URLs served by boring registry frequently include that character and requests to S3 do not fail if it isn't encoded. Probably wouldn't hurt, though.

How does authorization with S3 work?

Hi guys,

I feel like I'm looking over something obvious here, but I don't understand how access to the S3 bucket is authorized?
I have never worked with AWS products, so perhaps I'm lacking knowledge in that area. FYI, I'm working on a PR that allows a different S3 endpoint to be used; I'd like to try boring registry with a MinIO backend.

OIDC auth

Hello,

In addition to static auth, it would be useful to add OIDC authentification like Keycloak, Authentic, ...

support `network_mirror` configuration of `.terraformrc`

I implemented a rather rudimentary mirror script to get versions of used providers and their signatures and store them in /providers directory of the boring registry. Sadly this doesn't match the expectations of terraform. (the needed files are present)

The key difference is the <namespace>/<provider>, which gets extended by terraform by registry.terraform.io

.terraformrc is

provider_installation {
  network_mirror {
    url = "https://terraform-registry.<client>/"
    include = ["*/*"]
  }
}
Error: Failed to query available provider packages

│ Could not retrieve the list of available versions for provider hashicorp/random: provider registry.terraform.io/hashicorp/random was not found in any of the search locations
│
│   - provider mirror at https://terraform-registry.<client>/
❯ curl -H "Authorization: Bearer xxx" https://terraform-registry.<client>/v1/providers/registry.terraform.io/hashicorp/aws/versions
404 page not found
❯ curl -H "Authorization: Bearer xxx" https://terraform-registry.<client>/v1/providers/hashicorp/aws/versions
{"versions":[{"version":"5.15.0","platforms":[{"os":"darwin","arch":"arm64"},{"os":"linux","arch":"amd64"}]}]}

see: #21

filesystem layout /providers

.
├── hashicorp
│   ├── archive
│   ├── aws
│   ├── cloudinit
│   ├── helm
│   ├── kubernetes
│   ├── null
│   ├── random
│   ├── time
│   └── tls
└── registry.terraform.io
    └── hashicorp
        ├── archive
        ├── aws
        ├── cloudinit
        ├── helm
        ├── kubernetes
        ├── null
        ├── random
        ├── time
        └── tls

Alternative module archive formats

Terraform can handle archives in several different formats, including zip, tar.bz2 (tbz2), tar.gz (tgz), and tar.xz (txz). It'd be nice to have support for these different formats in the registry.

This could potentially be done by checking the backing store for which formats are available for a requested module and then automatically serving a download link corresponding to one of those formats, but the implementation complexity would be high and the value would be dubious since it's unclear how many people would have mixed archive formats in the backing store for their registry.

An alternative could be to add a --storage-module-archive-format flag that defaults to tar.gz (the current expected format) but can be used to switch over to zip, tbz2, etc.

clarification on uploading a provider

  1. can we make an upload of a module/provider on a distant registry not local one ?
  2. I see that uploading a provider is not supported yet using CLI , what dev work should be done on that ? is there any blockers ?

Only release modules matching a version constraint

We would like to have the option to pass a flag to the boring-registry cli upload subcommand in order to constrain uploading modules.
In our use-case, we run the boring-registry cli in CI and would like to limit uploading new releases to the main branch, while allowing pre-releases (e.g. v1.2.3-alpha1) to be uploaded from non-main branches.

I'll see if I can manage to create a PR :)

HTTP 500 rather than 404

When making requests to a module / version not in the registry (file does not exist in the S3 bucket) we receive a http 500 response rather than a http 404

If a version does not exist in the backend please generate a 404 rather than 500

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

dockerfile
Dockerfile
  • golang 1.21
github-actions
.github/workflows/container.yml
  • docker/login-action v3
  • docker/build-push-action v5
.github/workflows/goreleaser.yml
  • actions/setup-go v5
  • actions/checkout v4
  • goreleaser/goreleaser-action v5
.github/workflows/release.yml
  • actions/setup-go v5
  • actions/checkout v4
  • actions/checkout v4
  • azure/setup-helm v3
  • actions/setup-python v5
  • helm/chart-testing-action v2.6.1
  • helm/kind-action v1
  • actions/checkout v4
  • actions/checkout v4
  • azure/setup-helm v3
gomod
go.mod
  • go 1.21
  • cloud.google.com/go/iam v1.1.5
  • cloud.google.com/go/storage v1.35.1
  • github.com/ProtonMail/go-crypto v0.0.0-20230923063757-afb1ddc0824c@afb1ddc0824c
  • github.com/aws/aws-sdk-go-v2 v1.24.0
  • github.com/aws/aws-sdk-go-v2/config v1.26.1
  • github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.15.7
  • github.com/aws/aws-sdk-go-v2/service/s3 v1.47.5
  • github.com/aws/smithy-go v1.19.0
  • github.com/go-kit/kit v0.13.0
  • github.com/go-kit/log v0.2.1
  • github.com/gorilla/mux v1.8.1
  • github.com/hashicorp/go-multierror v1.1.1
  • github.com/hashicorp/go-version v1.6.0
  • github.com/hashicorp/hcl v1.0.0
  • github.com/okta/okta-jwt-verifier-golang/v2 v2.0.3
  • github.com/prometheus/client_golang v1.17.0
  • github.com/spf13/cobra v1.8.0
  • github.com/spf13/pflag v1.0.5
  • github.com/spf13/viper v1.18.1
  • github.com/stretchr/testify v1.8.4
  • golang.org/x/oauth2 v0.15.0
  • golang.org/x/sync v0.5.0
  • google.golang.org/api v0.153.0
helm-values
helm/boring-registry/values.yaml
  • ghcr.io/tiermobility/boring-registry v0.11.4

  • Check this box to trigger a request for Renovate to run again on this repository

Only support presigned URLs

The logic to generate download URLs has gotten a little bit convoluted:
https://github.com/TierMobility/boring-registry/blob/a5bde2ed99e33f55447b4187b258ae43b965c956/pkg/storage/s3.go#L320-L358
We could think about only passing back presigned URLs to the client, which would slightly simplify the code and the configuration.

I can currently only imagine a single downside: by setting --storage-s3-signedurl=false, it's currently possible to limit the clients access to modules with ACLs, only giving certain clients access to a module for example. Although I don't really think that this is a common use-case

cc: @heimweh

Support provider network mirror with pull-through cache

I thought about adding support for the Provider Network Mirror Protocol to the project. In addition, there would be an opportunity to implement a pull-through cache for requested providers into the boring-registry.
Thus not only proxying the network traffic, but also maintaining a (local) mirror of providers from upstream registries. The goal would be to increase the level of autonomy e.g. in case an upstream registry is unavailable. Another benefit could be a speedup in terraform runs in certain circumstances because of network locality.

The Terraform CLI would need to be configured accordingly to use the Provider Network Mirror Protocol:

provider_installation {
  network_mirror {
    url = "https://example.com:5601/v1/mirror/"
  }
}

I started working on the feature and built a PoC to see if it's feasible (and sensible at all) to implement. So far, feature-wise, everything seems to be working.
The code is not in an ideal shape right now, but nevertheless I'd like to post a PR to get the discussion started as early as possible to see if the whole idea and approach make sense at all :)

ghcr.io/boring-registry/boring-registry:v0.12.0 not available for anonymous pull

❯ docker pull ghcr.io/boring-registry/boring-registry:0.12.0
ghcr.io/boring-registry/boring-registry:0.12.0: resolving      |--------------------------------------|
elapsed: 1.1 s                                  total:   0.0 B (0.0 B/s)
INFO[0001] trying next host                              error="failed to authorize: failed to fetch anonymous token: unexpected status from GET request to https://ghcr.io/token?scope=repository%3Aboring-registry%2Fboring-registry%3Apull&service=ghcr.io: 401 Unauthorized" host=ghcr.io
FATA[0001] failed to resolve reference "ghcr.io/boring-registry/boring-registry:0.12.0": failed to authorize: failed to fetch anonymous token: unexpected status from GET request to https://ghcr.io/token?scope=repository%3Aboring-registry%2Fboring-registry%3Apull&service=ghcr.io: 401 Unauthorized
FATA[0001] exit status 1

Older versions can be pulled from previous org (tiermobility; except 0.11.3)

❯ docker pull ghcr.io/tiermobility/boring-registry:latest
ghcr.io/tiermobility/boring-registry:latest:                                      resolved       |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:b9522172b229b4c17b4d3932955036bb24a03f8e2be869c3da898a8eb44f43b6: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:6421292c227abe2f641613ebb01841483b56510807710e4e0157d70502aeee18:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:b4ca4c215f483111b64ec6919f1659ff475d7080a649d6acd78a6ade562a4a63:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:1406fd42514e57f8c6f9bcf3ecfec41fa2fc198cdbb33bcafdd2c8803632c1e2:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:dd5ad9c9c29f04b41a0155c720cf5ccab28ef6d353f1fe17a06c579c70054f0a:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:eebb06941f3e57b2e40a0e9cbd798dacef9b04d89ebaa8896be5f17c976f8666:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:960043b8858c3c30f1d79dcc49adb2804fd35c2510729e67685b298b2ca746b7:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:02cd68c0cbf64abe9738767877756b33f50fff5d88583fdc74b66beffa77694b:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:d3c894b5b2b0fa857549aeb6cbc38b038b5b2828736be37b6d9fff0b886f12fd:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:b40161cd83fc5d470d6abe50e87aa288481b6b89137012881d74187cfbf9f502:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:46ba3f23f1d3fb1440deeb279716e4377e79e61736ec2227270349b9618a0fdd:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:4fa131a1b726b2d6468d461e7d8867a2157d5671f712461d8abd126155fdf9ce:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:01f38fc88b34d9f2e43240819dd06c8b126eae8a90621c1f2bc5042fed2b010a:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:6e24d515f042b5dd6855edf8f947ba7c611d0a8c0f9c04aaedba6ece85031051:    done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:0460cb7a0f85b7338c4d1efb1a206f2075ebd99389541849d29ad7127959daad:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 5.0 s

❯ docker pull ghcr.io/tiermobility/boring-registry:v0.11.4
ghcr.io/tiermobility/boring-registry:v0.11.4:                                     resolved       |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:b9522172b229b4c17b4d3932955036bb24a03f8e2be869c3da898a8eb44f43b6: exists         |++++++++++++++++++++++++++++++++++++++|
config-sha256:6421292c227abe2f641613ebb01841483b56510807710e4e0157d70502aeee18:   exists         |++++++++++++++++++++++++++++++++++++++|
elapsed: 0.7 s                                                                    total:   0.0 B (0.0 B/s)

❯ docker pull ghcr.io/tiermobility/boring-registry:v0.11.3
ghcr.io/tiermobility/boring-registry:v0.11.3: resolving      |--------------------------------------|
elapsed: 0.3 s                                total:   0.0 B (0.0 B/s)
INFO[0000] trying next host - response was http.StatusNotFound  host=ghcr.io
FATA[0000] failed to resolve reference "ghcr.io/tiermobility/boring-registry:v0.11.3": ghcr.io/tiermobility/boring-registry:v0.11.3: not found
FATA[0000] exit status 1

❯ docker pull ghcr.io/tiermobility/boring-registry:v0.11.2
ghcr.io/tiermobility/boring-registry:v0.11.2:                                     resolved       |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:40ebb4ec6a284490e6a258cd5c1ceb1f77f71fb1a521f637bbefa56a061ae055: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:70f3ff20380ae05c3182a07dfdade9bd54570d545821c0d6c2cad482a376e8d1:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:ad5edb819b719fae336d24c7856b05ed2eb3b704efb0b57896acc8e22db3cb01:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 4.5 s                                                                    total:  16.7 M (3.7 MiB/s)

❯ docker pull ghcr.io/tiermobility/boring-registry:v0.11.1
ghcr.io/tiermobility/boring-registry:v0.11.1:                                     resolved       |++++++++++++++++++++++++++++++++++++++|
manifest-sha256:ae8b7271308cd3f58e8da077f7db046b123f4fb7817590bfb52bd43d687e1027: done           |++++++++++++++++++++++++++++++++++++++|
config-sha256:ed772be70737b700e05f569bdfe631ac81d6377c5f8fad582ebc8b69561c3f63:   done           |++++++++++++++++++++++++++++++++++++++|
layer-sha256:504b4a5903e8fc4de59f1ca1ba61916fe04e9184bc16738d64b01d0d8ce28718:    done           |++++++++++++++++++++++++++++++++++++++|
elapsed: 9.2 s

helm Chart // allow to add a true/false `extraEnv`

at the moment I can not add an add. environment variable

extraEnvs:
  - name: BORING_REGISTRY_NETWORK_MIRROR_PULL_THROUGH
    value: "true"

As this is simply translated into a Yaml boolean 😭
json: cannot unmarshal bool into Go struct field EnvVar.spec.template.spec.containers.env.value of type string

Allow cloud objects to be referenced via HTTP protocol

The Terraform CLI fails to download modules from S3 even if they're publicly-readable if it can't find any AWS credentials. An easy workaround to this is to serve module sources that use the https:// scheme, which causes the CLI to use HTTP instead of the S3 protocol to download the module. It'd be nice if there were a flag like --storage-s3-force-http that could enable that behavior.

I've taken a brief look at the GCS logic and it seems like https:// URLs are already being served for GCS objects, but if that's not the case, it's probably worth it to add support for this type of behavior to GCS mode as well.

Does this sound reasonable?

Unable to reference module from minIO backed registry

I have minio server running and I successfully uploaded my module, but so far I am not able to reference the module in my TF code.
I'm not sure about the proper content for source field in my TF module definition and proper TF configuration. In readme of boring-registry the registry module is referenced just by source="boring-registry/.....". But how is it resolved to my local registry? Using my IP source="http://<IP>:9000/....".
I am getting 403 or by using source="s3::http://<IP>:9000/...." I am getting InvalidAccessKeyId: The AWS Access Key Id you provided does not exist in our records.

Please advice.

0.11.2 container crashlooping

Using Helm chart version: 0.7.0

Error as shown below

/boring-registry: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.32' not found (required by /boring-registry)
/boring-registry: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.34' not found (required by /boring-registry)
Stream closed EOF for boring-registry/boring-registry-596774b694-k9qkq (boring-registry)```

I didn't investigate much to be honest :(

[Feature Request]: Support using local file system as storage

Hi, guys 👋

When we revolve around Terraform to launch a project, a private Terraform Registry is necessary. boring-registry seems like a great open-source choice.

During the early stages of development, using the local filesystem as the registry storage can be simpler, cost-effective, and faster to make significant progress. Additionally, local filesystem storage is more friendly for frequent debugging in the initial phase of the project, especially for projects with fewer users that may not require remote storage in the beginning, whether due to cost or functional considerations. Furthermore, projects similar to boring-registry, like Citizen, also offer similar support.

Therefore, I propose here that boring-registry could support local filesystem storage. I hope to receive your response and hear your thoughts on this. If the proposal allows, I can also help with some related code development in my free time.

Thank you.

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: Cannot find preset's package (github>TierMobility/renovate-config)

Flags or environment variables are not being enforced

Hi,

I have set up a minio instance locally and trying to upload modules to it via boring-registry.

I have the following .hcl file in the module folder:

metadata {
  namespace = "tier"
  name      = "tls-private-key"
  provider = "aws"
  version   = "0.1.0"
}

But whenever I run the following command:

boring-registry upload module   --storage-s3-bucket=terraform-registry-test \
  --storage-s3-region=eu-east-1 \
  --storage-s3-pathstyle=true \
  --storage-s3-endpoint=http://localhost:9000 .

It comes with the following error:
operation error S3: CreateMultipartUpload, exceeded maximum number of attempts, 3, failed to sign request: failed to retrieve credentials: failed to refresh cached credentials, no EC2 IMDS role found, operation error ec2imds: GetMetadata, exceeded maximum number of attempts, 3, request send failed, Get "http://169.254.169.254/latest/meta-data/iam/security-credentials/": dial tcp 169.254.169.254:80: i/o timeout: failed to upload module

Unable to query published provider info and local terraform init got error

Hi Team,

I am using this open source project to experiment the publish of both public and private providers.

I started a local minio storage and uploaded azurerm provider files manually under the path terraform-registry-test/providers/hashicorp/azurerm (terraform-registry-test is the bucket name)

image

It is running at localhost:9000.

Afterward, I start the server with

`66859644@C02D94YHML85 boring-registry % boring-registry server \

--storage-s3-bucket=terraform-registry-test \

--storage-s3-pathstyle=true \

--storage-s3-endpoint=http://localhost:9000 \

--debug

caller=root.go:62 timestamp=2022-10-17T15:29:18.986407Z level=debug hostname=C02D94YHML85 msg="debug mode enabled"

caller=server.go:162 timestamp=2022-10-17T15:29:18.997946Z level=info hostname=C02D94YHML85 listen=:7801 msg="starting telemetry server"

caller=server.go:140 timestamp=2022-10-17T15:29:18.997985Z level=info hostname=C02D94YHML85 listen=:5601 msg="starting server"`

Does it mean the server has already started? and how I can query the provider info using the server API?

I created a main.tf with provider info:

`terraform {

required_providers {

azurerm = {

  source = "localhost:5601/hashicorp/azurerm"

  version = "3.24.0"

}

}

}`

but the terraform init gave error:

`266859644@C02D94YHML85 test % terraform init

Initializing the backend...

Initializing provider plugins...

  • Finding localhost:5601/hashicorp/azurerm versions matching "3.24.0"...

│ Error: Failed to query available provider packages

│ Could not retrieve the list of available versions for provider localhost:5601/hashicorp/azurerm: could not connect to localhost:5601: Failed to request discovery document: Get

│ "https://localhost:5601/.well-known/terraform.json": http: server gave HTTP response to HTTPS client`

Could you kindly guide what I may miss?

Thanks

Support Azure Blob Storage

Are there (or any plans to add) any other storage options other then S3 bucket? I only have access to Azure. Is there any way to use this with an Azure file share? Or Azure blob? Thanks!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.