From 9517059ae0098d52da7f0ffab76db5f2894351aa Mon Sep 17 00:00:00 2001 From: dkistner Date: Tue, 14 Jul 2020 14:25:49 +0200 Subject: [PATCH] Support terraform imports --- example/10-config.yaml | 2 ++ example/50-terraformer-import-pod.yaml | 41 +++++++++++++++++++++++ terraform.sh | 46 ++++++++++++++++++++++++++ 3 files changed, 89 insertions(+) create mode 100644 example/50-terraformer-import-pod.yaml diff --git a/example/10-config.yaml b/example/10-config.yaml index 18a520f9..bb0dc2e5 100644 --- a/example/10-config.yaml +++ b/example/10-config.yaml @@ -43,6 +43,8 @@ data: description = "AWS Secret Access Key" type = "string" } + # imports: | + # aws_route53_record.www Z3ABCDE5FGHIJK.example.com --- apiVersion: v1 diff --git a/example/50-terraformer-import-pod.yaml b/example/50-terraformer-import-pod.yaml new file mode 100644 index 00000000..ddf148d4 --- /dev/null +++ b/example/50-terraformer-import-pod.yaml @@ -0,0 +1,41 @@ +# Copyright (c) 2019 SAP SE or an SAP affiliate company. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +--- +apiVersion: v1 +kind: Pod +metadata: + name: some-name.infra.tf-import + namespace: default +spec: + activeDeadlineSeconds: 1800 + containers: + - name: terraform + image: eu.gcr.io/gardener-project/gardener/terraformer:latest + imagePullPolicy: IfNotPresent + command: + - /terraformer.sh + - import + env: + - name: TF_CONFIGURATION_CONFIG_MAP_NAME + value: some-name.infra.tf-config + - name: TF_STATE_CONFIG_MAP_NAME + value: some-name.infra.tf-state + - name: TF_VARIABLES_SECRET_NAME + value: some-name.infra.tf-vars + resources: + requests: + cpu: 100m + restartPolicy: Never + terminationGracePeriodSeconds: 30 diff --git a/terraform.sh b/terraform.sh index 96405c94..6ac24275 100755 --- a/terraform.sh +++ b/terraform.sh @@ -20,6 +20,7 @@ DIR_CONFIGURATION="/tf" DIR_VARIABLES="/tfvars" DIR_PROVIDERS="/terraform-providers" DIR_PLUGIN_BINARIES=".terraform/plugins/linux_amd64" +DIR_IMPORTS="/terraform-imports" PATH_STATE_CONFIG_MAP="$DIR_STATE_OUT/$TF_STATE_CONFIG_MAP_NAME" PATH_STATE_IN="$DIR_STATE_IN/terraform.tfstate" @@ -27,6 +28,9 @@ PATH_STATE_OUT="$DIR_STATE_OUT/terraform.tfstate" PATH_CONFIGURATION_MAINTF="$DIR_CONFIGURATION/main.tf" PATH_CONFIGURATION_VARIABLESTF="$DIR_CONFIGURATION/variables.tf" PATH_VARIABLES="$DIR_VARIABLES/terraform.tfvars" +PATH_IMPORTS="$DIR_IMPORTS/terraform_imports" +PATH_IMPORT_TMP_STATE_IN="/import_in_tmp_terraform.tfstate" +PATH_IMPORT_TMP_STATE_OUT="/import_out_tmp_terraform.tfstate" NAMESPACE="$(cat /var/run/secrets/kubernetes.io/serviceaccount/namespace)" @@ -65,6 +69,7 @@ mkdir -p "$DIR_CONFIGURATION" mkdir -p "$DIR_VARIABLES" mkdir -p "$DIR_STATE_IN" mkdir -p "$DIR_STATE_OUT" +mkdir -p "$DIR_IMPORTS" # live lookup of terraform resources stored in configmaps echo "Fetching configmap $NAMESPACE/$TF_CONFIGURATION_CONFIG_MAP_NAME and storing data in $PATH_CONFIGURATION_MAINTF..." @@ -81,6 +86,13 @@ kubectl \ --output="jsonpath={.data['variables\.tf']}" \ > "$PATH_CONFIGURATION_VARIABLESTF" +echo "Fetching configmap $NAMESPACE/$TF_CONFIGURATION_CONFIG_MAP_NAME and storing data in $PATH_IMPORTS..." +kubectl \ + --namespace="$NAMESPACE" \ + get configmap "$TF_CONFIGURATION_CONFIG_MAP_NAME" \ + --output="jsonpath={.data['imports']}" \ + > "$PATH_IMPORTS" + echo "Fetching secret $NAMESPACE/$TF_VARIABLES_SECRET_NAME and storing data in $PATH_VARIABLES..." kubectl \ --namespace="$NAMESPACE" \ @@ -210,6 +222,40 @@ else TF_PID=$! wait $TF_PID exitcode=$? + elif [[ "$command" == "import" ]]; then + cat $PATH_STATE_IN > $PATH_IMPORT_TMP_STATE_IN + while read -r line; do + [[ "$line" == '' ]] && continue + resource_ref="$(echo $line | cut -d ' ' -f1 | tr -d ' ')" + resource_value="$(echo $line | cut -d ' ' -f2 | tr -d ' ')" + + terraform \ + import \ + -config="$DIR_CONFIGURATION" \ + -state="$PATH_IMPORT_TMP_STATE_IN" \ + -state-out="$PATH_IMPORT_TMP_STATE_OUT" \ + -var-file="$PATH_VARIABLES" \ + "$resource_ref" "$resource_value" & + TF_PID=$! + wait $TF_PID + exitcode=$? + + [[ "$exitcode" == "0" ]] && cat $PATH_IMPORT_TMP_STATE_OUT > $PATH_IMPORT_TMP_STATE_IN + done < "$PATH_IMPORTS" + rm -f $PATH_IMPORT_TMP_STATE_IN + + if [[ -f $PATH_IMPORT_TMP_STATE_OUT ]]; then + echo "Patching configmap $NAMESPACE/$TF_CONFIGURATION_CONFIG_MAP_NAME to remove imports as they are applied to state..." + kubectl \ + --namespace="$NAMESPACE" \ + patch configmap "$TF_CONFIGURATION_CONFIG_MAP_NAME" \ + --type=json \ + -p='[{"op": "remove", "path": "/data/imports"}]' + + echo "Write the state containing import(s) for persisting to $PATH_STATE_OUT" + cat $PATH_IMPORT_TMP_STATE_OUT > $PATH_STATE_OUT + rm -f $PATH_IMPORT_TMP_STATE_OUT + fi else # Delete trap handler - nothing to do trap - HUP INT QUIT PIPE TERM EXIT