Skip to content

Commit 2ae1e62

Browse files
committed
wip: configurable terraform aws version
1 parent 39d9e43 commit 2ae1e62

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

controllers/controlplane/kopscontrolplane_controller.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ type KopsControlPlaneReconciler struct {
9595
Recorder record.EventRecorder
9696
TfExecPath string
9797
DryRun bool
98+
AWSProviderVersion string
9899
GetKopsClientSetFactory func(configBase string) (simple.Clientset, error)
99100
BuildCloudFactory func(*kopsapi.Cluster) (fi.Cloud, error)
100101
PopulateClusterSpecFactory func(ctx context.Context, kopsCluster *kopsapi.Cluster, kopsClientset simple.Clientset, cloud fi.Cloud) (*kopsapi.Cluster, error)
@@ -748,7 +749,12 @@ func (r *KopsControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.Req
748749
}
749750

750751
// This is needed because this is normally created, but when deleting we don't create the kops resources files
751-
err = utils.CreateTerraformFilesFromTemplate("templates/provider.tf.tpl", "provider.tf", terraformOutputDir, nil)
752+
providerData := struct {
753+
Version string
754+
}{
755+
Version: r.AWSProviderVersion,
756+
}
757+
err = utils.CreateTerraformFilesFromTemplate("templates/provider.tf.tpl", "provider.tf", terraformOutputDir, providerData)
752758
if err != nil {
753759
return resultError, err
754760
}
@@ -939,6 +945,14 @@ func (r *KopsControlPlaneReconciler) Reconcile(ctx context.Context, req ctrl.Req
939945
return resultError, err
940946
}
941947

948+
// Modify existing Terraform files to add AWS provider version constraint if specified
949+
if r.AWSProviderVersion != "" {
950+
err = utils.ModifyTerraformProviderVersion(terraformOutputDir, r.AWSProviderVersion)
951+
if err != nil {
952+
return resultError, err
953+
}
954+
}
955+
942956
// Only Apply resources if DryRun isn't set from command line
943957
if r.DryRun {
944958
reconciler.log.Info(fmt.Sprintf("planning Terraform for %s", kopsControlPlane.ObjectMeta.GetName()))

main.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,13 +71,15 @@ func main() {
7171
var probeAddr string
7272
var controllerClass string
7373
var dryRun bool
74+
var awsProviderVersion string
7475
flag.StringVar(&metricsAddr, "metrics-bind-address", ":8080", "The address the metric endpoint binds to.")
7576
flag.StringVar(&probeAddr, "health-probe-bind-address", ":8081", "The address the probe endpoint binds to.")
7677
flag.BoolVar(&enableLeaderElection, "leader-elect", false,
7778
"Enable leader election for controller manager. "+
7879
"Enabling this will ensure there is only one active controller manager.")
7980
flag.StringVar(&controllerClass, "controller-class", "", "The name of the controller class to associate with the controller.")
8081
flag.BoolVar(&dryRun, "dry-run", false, "Enable dry-run mode to plan without making actual changes.")
82+
flag.StringVar(&awsProviderVersion, "aws-provider-version", "", "The version of the AWS provider to use in Terraform templates.")
8183

8284
opts := zap.Options{
8385
Development: true,
@@ -162,6 +164,7 @@ func main() {
162164
Recorder: recorder,
163165
TfExecPath: tfExecPath,
164166
DryRun: dryRun,
167+
AWSProviderVersion: awsProviderVersion,
165168
GetKopsClientSetFactory: utils.GetKopsClientset,
166169
BuildCloudFactory: utils.BuildCloud,
167170
PopulateClusterSpecFactory: controlplane.PopulateClusterSpec,

pkg/utils/terraform_utils.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"os"
88
"path/filepath"
9+
"regexp"
910
"strings"
1011
"text/template"
1112

@@ -61,18 +62,53 @@ func CreateAdditionalTerraformFiles(tfFiles ...Template) error {
6162
return nil
6263
}
6364

65+
// ModifyTerraformProviderVersion modifies the existing Terraform files to add AWS provider version constraint
66+
func ModifyTerraformProviderVersion(terraformOutputDir, awsProviderVersion string) error {
67+
kubernetesFile := terraformOutputDir + "/kubernetes.tf"
68+
69+
cleanVersion := strings.Trim(awsProviderVersion, `"`)
70+
71+
content, err := os.ReadFile(kubernetesFile)
72+
if err != nil {
73+
return fmt.Errorf("failed to read kubernetes.tf: %w", err)
74+
}
75+
76+
awsVersionRegex := regexp.MustCompile(`(?s)(aws\s*=\s*\{[^}]*"version"\s*=\s*)"[^"]*"`)
77+
78+
if !awsVersionRegex.MatchString(string(content)) {
79+
return fmt.Errorf("failed to find AWS provider version pattern in kubernetes.tf")
80+
}
81+
82+
newVersionString := fmt.Sprintf(`${1}"%s"`, cleanVersion)
83+
newContent := awsVersionRegex.ReplaceAllString(string(content), newVersionString)
84+
85+
err = os.WriteFile(kubernetesFile, []byte(newContent), 0644)
86+
if err != nil {
87+
return fmt.Errorf("failed to write modified kubernetes.tf: %w", err)
88+
}
89+
90+
return nil
91+
}
92+
6493
func initTerraform(ctx context.Context, workingDir, terraformExecPath string, credentials aws.Credentials) (*tfexec.Terraform, error) {
6594
tf, err := tfexec.NewTerraform(workingDir, terraformExecPath)
6695
if err != nil {
6796
return nil, err
6897
}
6998

99+
pluginCacheDir := fmt.Sprintf("%s/plugin-cache", filepath.Dir(terraformExecPath))
100+
101+
err = os.MkdirAll(pluginCacheDir, 0755)
102+
if err != nil {
103+
return nil, fmt.Errorf("failed to create plugin cache directory: %w", err)
104+
}
105+
70106
env := map[string]string{
71107
"AWS_ACCESS_KEY_ID": credentials.AccessKeyID,
72108
"AWS_SECRET_ACCESS_KEY": credentials.SecretAccessKey,
73109
"SPOTINST_TOKEN": os.Getenv("SPOTINST_TOKEN"),
74110
"SPOTINST_ACCOUNT": os.Getenv("SPOTINST_ACCOUNT"),
75-
"TF_PLUGIN_CACHE_DIR": fmt.Sprintf("%s/plugin-cache", filepath.Dir(terraformExecPath)),
111+
"TF_PLUGIN_CACHE_DIR": pluginCacheDir,
76112
}
77113

78114
// this overrides all ENVVARs that are passed to Terraform

0 commit comments

Comments
 (0)