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

Support Terraform Imports #43

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 2 additions & 0 deletions example/10-config.yaml
Expand Up @@ -43,6 +43,8 @@ data:
description = "AWS Secret Access Key"
type = "string"
}
# imports: |
# aws_route53_record.www Z3ABCDE5FGHIJK.example.com

---
apiVersion: v1
Expand Down
41 changes: 41 additions & 0 deletions 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
46 changes: 46 additions & 0 deletions terraform.sh
Expand Up @@ -20,13 +20,17 @@ 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"
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)"

Expand Down Expand Up @@ -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..."
Expand All @@ -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" \
Expand Down Expand Up @@ -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
Expand Down