Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove the Terraform CLI from the provider package and deprecate the relevant provider command-line flags #434

Merged
merged 1 commit into from
Dec 13, 2023
Merged
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
6 changes: 2 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,12 @@ PROVIDER_NAME := gcp
PROJECT_NAME := provider-$(PROVIDER_NAME)
PROJECT_REPO := github.com/upbound/$(PROJECT_NAME)

export PROVIDER_NAME
export TERRAFORM_VERSION := 1.5.5
export TERRAFORM_PROVIDER_SOURCE := hashicorp/google
export TERRAFORM_PROVIDER_VERSION := 4.77.0
export TERRAFORM_PROVIDER_DOWNLOAD_NAME := terraform-provider-google
export TERRAFORM_PROVIDER_DOWNLOAD_URL_PREFIX := https://releases.hashicorp.com/terraform-provider-google/$(TERRAFORM_PROVIDER_VERSION)
export TERRAFORM_PROVIDER_SOURCE := hashicorp/google
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we still need this variable?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @sergenyalcin,
We now use TERRAFORM_PROVIDER_SOURCE and the like while extracting the Terraform provider metadata and for generating the schema.json. However, it's no longer used at runtime or for downloading the Terraform provider image while building the provider package.

export TERRAFORM_PROVIDER_REPO ?= https://github.com/hashicorp/terraform-provider-google
export TERRAFORM_DOCS_PATH ?= website/docs/r
export PROVIDER_NAME

PLATFORMS ?= linux_amd64 linux_arm64

Expand Down
48 changes: 3 additions & 45 deletions cluster/images/provider-gcp/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,57 +1,15 @@
FROM alpine:3.19.0 AS builder
RUN apk --no-cache add curl
FROM alpine:3.19.0
RUN apk --no-cache add ca-certificates bash

ARG TARGETOS
ARG TARGETARCH

# Setup Terraform environment

## Provider-dependent configuration
ARG TERRAFORM_VERSION
ARG TERRAFORM_PROVIDER_VERSION
ARG TERRAFORM_PROVIDER_DOWNLOAD_NAME
## End of - Provider-dependent configuration

RUN curl -L -o /tmp/terraform_${TERRAFORM_VERSION}_${TARGETOS}_${TARGETARCH}.zip https://github.com/upbound/terraform/releases/download/v${TERRAFORM_VERSION}/terraform_${TERRAFORM_VERSION}_${TARGETOS}_${TARGETARCH}.zip \
&& unzip /tmp/terraform_${TERRAFORM_VERSION}_${TARGETOS}_${TARGETARCH}.zip -d /tmp/ \
&& chmod +x /tmp/terraform \
&& rm /tmp/terraform_${TERRAFORM_VERSION}_${TARGETOS}_${TARGETARCH}.zip \
&& curl -L -o /tmp/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}_${TERRAFORM_PROVIDER_VERSION}_${TARGETOS}_${TARGETARCH}.zip https://releases.hashicorp.com/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}/${TERRAFORM_PROVIDER_VERSION}/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}_${TERRAFORM_PROVIDER_VERSION}_${TARGETOS}_${TARGETARCH}.zip \
&& unzip /tmp/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}_${TERRAFORM_PROVIDER_VERSION}_${TARGETOS}_${TARGETARCH}.zip -d /tmp/native/ \
&& chmod +x /tmp/native/* \
&& rm /tmp/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}_${TERRAFORM_PROVIDER_VERSION}_${TARGETOS}_${TARGETARCH}.zip
# End of - Setup Terraform environment

FROM alpine:3.19.0 as base

ARG CROSSPLANE_PROVIDER_VERSION
ARG TARGETOS
ARG TARGETARCH
ARG TERRAFORM_VERSION
ARG TERRAFORM_PROVIDER_SOURCE
ARG TERRAFORM_PROVIDER_VERSION
ARG TERRAFORM_PROVIDER_DOWNLOAD_NAME
ARG PLUGIN_DIR=/terraform/provider-mirror/registry.terraform.io/${TERRAFORM_PROVIDER_SOURCE}/${TERRAFORM_PROVIDER_VERSION}/${TARGETOS}_${TARGETARCH}

ENV USER_ID=65532
ENV TF_CLI_CONFIG_FILE /terraform/.terraformrc
ENV TF_FORK 0
# set user agent
ENV GOOGLE_TERRAFORM_USERAGENT_EXTENSION "upbound-provider-gcp/${CROSSPLANE_PROVIDER_VERSION}"

# Provider controller needs these environment variable at runtime
ENV TERRAFORM_VERSION ${TERRAFORM_VERSION}
ENV TERRAFORM_PROVIDER_SOURCE ${TERRAFORM_PROVIDER_SOURCE}
ENV TERRAFORM_PROVIDER_VERSION ${TERRAFORM_PROVIDER_VERSION}
ENV TERRAFORM_NATIVE_PROVIDER_PATH ${PLUGIN_DIR}/${TERRAFORM_PROVIDER_DOWNLOAD_NAME}_v${TERRAFORM_PROVIDER_VERSION}_x5

RUN apk --no-cache add ca-certificates bash

USER ${USER_ID}
EXPOSE 8080

ADD terraformrc.hcl ${TF_CLI_CONFIG_FILE}
COPY --from=builder /tmp/terraform /usr/local/bin/
COPY --from=builder /tmp/native/* ${PLUGIN_DIR}/

ENTRYPOINT ["provider"]
ENTRYPOINT ["provider"]
6 changes: 0 additions & 6 deletions cluster/images/provider-gcp/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,14 +36,8 @@ img.build:

img.build.shared:
@cp Dockerfile $(IMAGE_TEMP_DIR) || $(FAIL)
@cp terraformrc.hcl $(IMAGE_TEMP_DIR) || $(FAIL)
@docker buildx build $(BUILD_ARGS) \
--platform $(IMAGE_PLATFORMS) \
--build-arg TERRAFORM_VERSION=$(TERRAFORM_VERSION) \
--build-arg TERRAFORM_PROVIDER_SOURCE=$(TERRAFORM_PROVIDER_SOURCE) \
--build-arg TERRAFORM_PROVIDER_VERSION=$(TERRAFORM_PROVIDER_VERSION) \
--build-arg TERRAFORM_PROVIDER_DOWNLOAD_NAME=$(TERRAFORM_PROVIDER_DOWNLOAD_NAME) \
--build-arg TERRAFORM_PROVIDER_DOWNLOAD_URL_PREFIX=$(TERRAFORM_PROVIDER_DOWNLOAD_URL_PREFIX) \
--build-arg CROSSPLANE_PROVIDER_VERSION=$(VERSION) \
-t $(IMAGE) \
$(IMAGE_TEMP_DIR) || $(FAIL)
Expand Down
9 changes: 0 additions & 9 deletions cluster/images/provider-gcp/terraformrc.hcl

This file was deleted.

69 changes: 31 additions & 38 deletions cmd/provider/accesscontextmanager/zz_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,57 +18,64 @@ package main

import (
"context"
"fmt"
"os"
"path/filepath"
"time"

"gopkg.in/alecthomas/kingpin.v2"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/tools/leaderelection/resourcelock"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
"github.com/crossplane/crossplane-runtime/pkg/certificates"
xpcontroller "github.com/crossplane/crossplane-runtime/pkg/controller"
"github.com/crossplane/crossplane-runtime/pkg/feature"
"github.com/crossplane/crossplane-runtime/pkg/logging"
"github.com/crossplane/crossplane-runtime/pkg/ratelimiter"
"github.com/crossplane/crossplane-runtime/pkg/resource"

tjcontroller "github.com/crossplane/upjet/pkg/controller"
"github.com/crossplane/upjet/pkg/terraform"
"gopkg.in/alecthomas/kingpin.v2"
kerrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
"k8s.io/client-go/tools/leaderelection/resourcelock"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
"sigs.k8s.io/controller-runtime/pkg/log/zap"

"github.com/upbound/provider-gcp/apis"
"github.com/upbound/provider-gcp/apis/v1alpha1"
"github.com/upbound/provider-gcp/config"
"github.com/upbound/provider-gcp/internal/clients"
"github.com/upbound/provider-gcp/internal/controller"
"github.com/upbound/provider-gcp/internal/features"

_ "k8s.io/client-go/plugin/pkg/client/auth/gcp"
)

func deprecationAction(flagName string) kingpin.Action {
return func(c *kingpin.ParseContext) error {
_, err := fmt.Fprintf(os.Stderr, "warning: Command-line flag %q is deprecated and no longer used. It will be removed in a future release. Please remove it from all of your configurations (ControllerConfigs, etc.).\n", flagName)
kingpin.FatalIfError(err, "Failed to print the deprecation notice.")
return nil
}
}

func main() {
var (
app = kingpin.New(filepath.Base(os.Args[0]), "Terraform based Crossplane provider for GCP").DefaultEnvars()
debug = app.Flag("debug", "Run with debug logging.").Short('d').Bool()
syncInterval = app.Flag("sync", "Sync interval controls how often all resources will be double checked for drift.").Short('s').Default("1h").Duration()
pollInterval = app.Flag("poll", "Poll interval controls how often an individual resource should be checked for drift.").Default("10m").Duration()
leaderElection = app.Flag("leader-election", "Use leader election for the controller manager.").Short('l').Default("false").OverrideDefaultFromEnvar("LEADER_ELECTION").Bool()
maxReconcileRate = app.Flag("max-reconcile-rate", "The global maximum rate per second at which resources may checked for drift from the desired state.").Default("10").Int()
pluginProcessTTL = app.Flag("provider-ttl", "TTL for the native plugin processes before they are replaced. Changing the default may increase memory consumption.").Default("100").Int()
terraformVersion = app.Flag("terraform-version", "Terraform version.").Required().Envar("TERRAFORM_VERSION").String()
nativeProviderSource = app.Flag("terraform-provider-source", "Terraform provider source.").Required().Envar("TERRAFORM_PROVIDER_SOURCE").String()
providerVersion = app.Flag("terraform-provider-version", "Terraform provider version.").Required().Envar("TERRAFORM_PROVIDER_VERSION").String()
nativeProviderPath = app.Flag("terraform-native-provider-path", "Terraform native provider path for shared execution.").Default("").Envar("TERRAFORM_NATIVE_PROVIDER_PATH").String()
app = kingpin.New(filepath.Base(os.Args[0]), "Terraform based Crossplane provider for GCP").DefaultEnvars()
debug = app.Flag("debug", "Run with debug logging.").Short('d').Bool()
syncInterval = app.Flag("sync", "Sync interval controls how often all resources will be double checked for drift.").Short('s').Default("1h").Duration()
pollInterval = app.Flag("poll", "Poll interval controls how often an individual resource should be checked for drift.").Default("10m").Duration()
leaderElection = app.Flag("leader-election", "Use leader election for the controller manager.").Short('l').Default("false").OverrideDefaultFromEnvar("LEADER_ELECTION").Bool()
maxReconcileRate = app.Flag("max-reconcile-rate", "The global maximum rate per second at which resources may checked for drift from the desired state.").Default("100").Int()

namespace = app.Flag("namespace", "Namespace used to set as default scope in default secret store config.").Default("crossplane-system").Envar("POD_NAMESPACE").String()
essTLSCertsPath = app.Flag("ess-tls-cert-dir", "Path of ESS TLS certificates.").Envar("ESS_TLS_CERTS_DIR").String()
enableExternalSecretStores = app.Flag("enable-external-secret-stores", "Enable support for ExternalSecretStores.").Default("false").Envar("ENABLE_EXTERNAL_SECRET_STORES").Bool()
enableManagementPolicies = app.Flag("enable-management-policies", "Enable support for Management Policies.").Default("true").Envar("ENABLE_MANAGEMENT_POLICIES").Bool()

// now deprecated command-line arguments with the Terraform SDK-based upjet architecture
_ = app.Flag("provider-ttl", "[DEPRECATED: This option is no longer used and it will be removed in a future release.] TTL for the native plugin processes before they are replaced. Changing the default may increase memory consumption.").Hidden().Action(deprecationAction("provider-ttl")).Int()
_ = app.Flag("terraform-version", "[DEPRECATED: This option is no longer used and it will be removed in a future release.] Terraform version.").Envar("TERRAFORM_VERSION").Hidden().Action(deprecationAction("terraform-version")).String()
_ = app.Flag("terraform-provider-version", "[DEPRECATED: This option is no longer used and it will be removed in a future release.] Terraform provider version.").Envar("TERRAFORM_PROVIDER_VERSION").Hidden().Action(deprecationAction("terraform-provider-version")).String()
_ = app.Flag("terraform-native-provider-path", "[DEPRECATED: This option is no longer used and it will be removed in a future release.] Terraform native provider path for shared execution.").Envar("TERRAFORM_NATIVE_PROVIDER_PATH").Hidden().Action(deprecationAction("terraform-native-provider-path")).String()
_ = app.Flag("terraform-provider-source", "[DEPRECATED: This option is no longer used and it will be removed in a future release.] Terraform provider source.").Envar("TERRAFORM_PROVIDER_SOURCE").Hidden().Action(deprecationAction("terraform-provider-source")).String()
)

kingpin.MustParse(app.Parse(os.Args[1:]))
Expand Down Expand Up @@ -103,18 +110,6 @@ func main() {
kingpin.FatalIfError(err, "Cannot create controller manager")
kingpin.FatalIfError(apis.AddToScheme(mgr.GetScheme()), "Cannot add GCP APIs to scheme")

// if the native Terraform provider plugin's path is not configured via
// the env. variable TERRAFORM_NATIVE_PROVIDER_PATH or
// the `--terraform-native-provider-path` command-line option,
// we do not use the shared gRPC server and default to the regular
// Terraform CLI behaviour (of forking a plugin process per invocation).
// This removes some complexity for setting up development environments.
var scheduler terraform.ProviderScheduler = terraform.NewNoOpProviderScheduler()
if len(*nativeProviderPath) != 0 {
scheduler = terraform.NewSharedProviderScheduler(log, *pluginProcessTTL,
terraform.WithSharedProviderOptions(terraform.WithNativeProviderPath(*nativeProviderPath), terraform.WithNativeProviderName("registry.terraform.io/"+*nativeProviderSource)))
}

ctx := context.Background()
provider, err := config.GetProvider(ctx, false)
kingpin.FatalIfError(err, "Cannot initialize the provider configuration")
Expand All @@ -127,7 +122,7 @@ func main() {
Features: &feature.Flags{},
},
Provider: provider,
SetupFn: clients.TerraformSetupBuilder(*terraformVersion, *nativeProviderSource, *providerVersion, provider.TerraformProvider, scheduler),
SetupFn: clients.TerraformSetupBuilder(provider.TerraformProvider),
PollJitter: pollJitter,
OperationTrackerStore: tjcontroller.NewOperationStore(log),
}
Expand All @@ -137,8 +132,6 @@ func main() {
log.Info("Beta feature enabled", "flag", features.EnableBetaManagementPolicies)
}

o.WorkspaceStore = terraform.NewWorkspaceStore(log, terraform.WithDisableInit(len(*nativeProviderPath) != 0), terraform.WithProcessReportInterval(*pollInterval), terraform.WithFeatures(o.Features))

if *enableExternalSecretStores {
o.SecretStoreConfigGVK = &v1alpha1.StoreConfigGroupVersionKind
log.Info("Alpha feature enabled", "flag", features.EnableAlphaExternalSecretStores)
Expand Down
Loading
Loading