hashicorp / terraform

Terraform enables you to safely and predictably create, change, and improve infrastructure. It is a source-available tool that codifies APIs into declarative configuration files that can be shared amongst team members, treated as code, edited, reviewed, and versioned.
https://www.terraform.io/
Other
42.31k stars 9.49k forks source link

Support OCI registries as module & provider source #31463

Open itspngu opened 2 years ago

itspngu commented 2 years ago

Current Terraform Version

Terraform v1.2.5
on linux_amd64

Use-cases

Using container registries as storage backend for provider and module distribution would empower users to leverage existing infrastructure in scenarios where otherwise a private registry would have to be hosted. There is a rich ecosystem around working with container images which could be used to enable a variety of creative use cases, e.g.:

Attempted Solutions

Originally I was contemplating building an application that implements the Registry API and serves artifacts from a container registry backend, but I've come to realize that directly supporting that sort of functionality inside Terraform itself would make a lot more sense, especially considering the fact that some of the core properties of OCI registries already make them more suitable as a provider/module source than zip files on S3.

Proposal

Facilitate using OCI registries for module and provider distribution/storage.

References

Other projects leveraging the same techniques:

apparentlymart commented 2 years ago

Hi @itspngu! Thanks for sharing this use-case.

Terraform only supports provider installation using its own provider registry protocol, and we don't have any intention of supporting any other protocols because Terraform's needs for provider installation are pretty specialized and so it doesn't really make sense to try to map them onto other implementations.

For module installation the situation is a bit more murky, however. Most of the non-registry sources Terraform currently supports predate Terraform having its own registry protocol, and implementing that protocol does allow additional features such as version constraints, and so I would typically suggest implementing the module registry protocol natively as a first preference -- note that the module registry protocol is a much smaller protocol than the "registry API" you linked to; the "registry API" is the full API implemented by Terraform Registry in particular, which has a wider scope of functionality than just Terraform CLI's module installer. I'm not sure how well that additional functionality maps to the features of the OCI registry protocol, though.

With that said, if upstream go-getter accepted a contribution to add a "getter" for the OCI registry protocol then I expect we would adopt it into Terraform as long as it works in a similar way to the other existing getters, such that it wouldn't require changes to Terraform other than registering the additional getter in our go-getter configuration. I expect the Terraform Core team won't be able to originate such an implementation though, since our focus is typically on Terraform's native functionality and protocols; integrations with external systems are more typically contributed by someone with an existing relationship or expertise with that external system.

bkalcho commented 1 year ago

I know you do not have intention of supporting additional registries, but it would be great if you start support OCI compliant registries which are easily becoming standard for registries, and thus giving your customers more options instead of vendor locking.

davidspek commented 1 year ago

Just mentioning https://github.com/hashicorp/go-getter/issues/271 here as it is the upstream issue for OCI support.

PR https://github.com/hashicorp/go-getter/pull/272 seems to implement OCI support but has become stale.

apparentlymart commented 1 year ago

It's not clear to me who ought to be responsible for reviewing that PR to go-getter, but looking at its source code I do see that it presents a challenge for Terraform in particular:

Terraform reserves addresses of the form hostname/anything/anything/anything as module registry addresses, which collides with the scheme implemented by the "detector" in the current implementation over in #272. I suspect that if that were merged in to go-getter as-is then Terraform would need to adopt only the getter portion and not the detector portion, which would mean that for Terraform it would be mandatory to use the oci:// prefix to be explicit that the address is intended to be an OCI registry address rather than a Terraform Module Registry address.

I don't think that's a big problem -- the URLs with the oci:// prefix seem ergonomic enough -- but I'm just noting it in case that PR does get merged in a form similar to what's currently there and someone else on the Terraform team comes back here to consider how to incorporate it into Terraform.

Blokje5 commented 1 year ago

On the open PR in https://github.com/hashicorp/go-getter/issues/271: I created it originally as support for the related issue (OCI support in go-getter). It was essentially a port of the code we used in conftest to handle downloading OPA policies from registries.

I am happy to update the go-getter PR. Or if anyone else wants to open a new PR feel free to. The code I wrote there is quite old by now. ORAS already seems to have a 1.0.0 version available.

The question remains who would handle reviews on go-getter?

davidspek commented 1 year ago

@Blokje5 I’d have a look at the last commits to the go-getter repo and ping them on the PR.

gclawes commented 1 year ago

Could the use of OCI registry be a possible mitigation to this?

https://github.com/bridgecrewio/checkov/issues/5286

https://medium.com/boostsecurity/erosion-of-trust-unmasking-supply-chain-vulnerabilities-in-the-terraform-registry-2af48a7eb2

itspngu commented 1 year ago

Could the use of OCI registry be a possible mitigation to this?

https://medium.com/boostsecurity/erosion-of-trust-unmasking-supply-chain-vulnerabilities-in-the-terraform-registry-2af48a7eb2

If the (pending) OCI implementation for go-getter allows for pinning digests in oci:// URLs and were to be incorporated into Terraform that way, yes. However, you could already achieve the same thing by using git as a module source and pinning your imports to a specific commit, the same idea of content addressability applies (to an extent).

My personal primary intent behind this feature request was a lot more mundane than leveraging it for SCC - the use of OCI registries as a sort-of "registry for everything, not just containers" has been steadily proliferating, and personally I'd much prefer leveraging that to tie in with existing infrastructure rather than managing S3 buckets or throwing around SSH keys for git repos when it comes to distributing Terraform modules. The array of other possible features and integrations that come with the vast container ecosystem are a welcome side effect ;)

sybereal commented 1 year ago

I want to note that, while here are tools like Flux' Terraform Controller, which allow fetching root modules from OCI registries already,^tfc-oci having the ability to do this for child modules as well would make for a more complete experience by enabling the use of OCI for everything, not just root modules.

gclawes commented 1 year ago

My personal primary intent behind this feature request was a lot more mundane than leveraging it for SCC - the use of OCI registries as a sort-of "registry for everything, not just containers" has been steadily proliferating, and personally I'd much prefer leveraging that to tie in with existing infrastructure rather than managing S3 buckets or throwing around SSH keys for git repos when it comes to distributing Terraform modules. The array of other possible features and integrations that come with the vast container ecosystem are a welcome side effect ;)

Agreed, especially around software-supply-chain tools that already support OCI registry artifacts, given that the concern in https://github.com/bridgecrewio/checkov/issues/5286 is about supply-chain attacks.