crossplane / terrajet

Generate Crossplane Providers from any Terraform Provider
https://crossplane.io
Apache License 2.0
289 stars 38 forks source link

Allow external-name annotation to be constructed from spec and spec fields to be initialized from external-name #119

Closed ulucinar closed 2 years ago

ulucinar commented 2 years ago

What problem are you facing?

Like manually coded in native providers, in certain cases, we need a mechanism in terrajet to allow the external-name to be constructed from information available from spec & provider configuration. This should also work in the opposite direction, i.e., when an external name is specified by the user, we should be able to late-initialize certain spec fields from the information made available in the external-name.

How could Terrajet help solve your problem?

An example from tf-provider-azure is the v1alpha1.ResourceGroup:

apiVersion: resource.azure.tf.crossplane.io/v1alpha1
kind: ResourceGroup
metadata:
  name: example
  annotations:
    crossplane.io/external-name: /subscriptions/<subscription id>/resourceGroups/example
spec:
  forProvider:
    name: example-resourcegroup
    location: "East US"
    tags:
      provisioner: crossplane
  providerConfigRef:
    name: example

In this example, ideally, the users should be able to:

muvaf commented 2 years ago

The external name annotation feature of XRM requires the removal of the name field and, if possible, use external name annotation instead. The ideal example YAML would look like the following:

apiVersion: resource.azure.tf.crossplane.io/v1alpha1
kind: ResourceGroup
metadata:
  name: example
  annotations:
    crossplane.io/external-name: example-resourcegroup # if not given, populated with metadata.name
spec:
  forProvider:
    # /subscriptions/<subscription id>/resourceGroups/example to use in TFState
    # is calculated by a custom function using information from spec and external-name annotation
    location: "East US"
    tags:
      provisioner: crossplane
  providerConfigRef:
    name: example

Right now, Terrajet allows us to parse the value of metadata.annotations[crossplane.io/external-name] to populate the main TF HCL in a custom manner but the problem is that there is no way to override the logic that takes the id from tfstate and assigns it to metadata.annotations[crossplane.io/external-name] if it's empty and the logic that calculates an id by using information from spec & annotation to be used in import cases. That makes us to use the whatever format it exists in tfstate, which is fully qualified form in some cases, and that prevents us to use the name initializer which defaults the value of annotation to metadata.name.

So I think what we need to in order to enable this XRM feature for Azure (and possibly some GCP resourcecs) is:

muvaf commented 2 years ago

Just to shed more light, this is currently blocking external name XRM feature to be implemented for provider-tf-azure since all IDs in Azure RM are fully qualifier that includes resource group, location etc.