Skip to content

Instantly share code, notes, and snippets.

@asaf400
Created October 24, 2022 03:01
Show Gist options
  • Save asaf400/0c34f2e5d39953dba88fea360291ca11 to your computer and use it in GitHub Desktop.
Save asaf400/0c34f2e5d39953dba88fea360291ca11 to your computer and use it in GitHub Desktop.
#!/bin/bash
# AUTHOR: github.com/asaf400
# This script iterates over all S3 objects in terraform state,
# in order to import any S3 resource that has been split from the main aws_s3_bucket resource
# following the terraform aws v4 breaking changes which requires existing s3 attributes to exists as 'linked' resources
# The script assumes that the hcl files has already been modifed to reflect the v4 change,
# and it is useful for allowing terraform to import the new resources which already existed in aws.
# SCRIPT IS DISTRIBUTED AS IS, NOT SUPPORT REQUESTS.
# The resources are:
# aws_s3_bucket_server_side_encryption_configuration
# aws_s3_bucket_lifecycle_configuration
# aws_s3_bucket_versioning
# aws_s3_bucket_cors_configuration
# aws_s3_bucket_acl
terraform_directory="$1"
pushd "$terraform_directory"
terraform show -json >/tmp/terraform-state.json
popd
function log_found() {
echo -e " \e[32m$1 is:\e[0m\n$2\n"
}
function log_notfound() {
echo -e " \e[33mno $1:\e[0m\n$2\n"
}
function log_error() {
echo -e " \e[31mERROR: $1\e[0m\n"
}
function handle_terraform_import() {
if [[ $1 == "acl" ]]; then
acl=",$(jq -r .values.acl <<<"$full_object")"
else
acl=""
fi
echo -e "Would perform:\n# terraform import $(sed 's/aws_s3_bucket/aws_s3_bucket_'"$1"'/' <<<"$object") "$bucket_name""$acl""
echo -e "To remove: # terraform state rm $(sed 's/aws_s3_bucket/aws_s3_bucket_'"$1"'/' <<<"$object")"
status="$(terraform import $(sed 's/aws_s3_bucket/aws_s3_bucket_'"$1"'/' <<<"$object") "$bucket_name""$acl")"
if [ $? -ne 0 ]; then
log_error "!!!!\n!!!! Failed to Import resource !!!!\n$status\n!!!!"
else
log_found "Successfully Imported Resource!" "$object"
fi
}
function jq_find_object(){
jq '..|objects|select(has("'$2'") and .'$2' == "'$3'")' $1
}
function process_value() {
resource_name=$1
resource=$2
condition=$3
if [[ $resource != "$condition" ]]; then
log_found $resource_name $resource
handle_terraform_import $resource_name
else
log_notfound $resource_name $resource
fi
}
pushd "$terraform_directory"
terraform init -upgrade
objects="$(jq_find_object "/tmp/terraform-state.json" type aws_s3_bucket | jq -r .address)"
echo "$objects"
for object in $objects; do
full_object="$(jq_find_object "/tmp/terraform-state.json" address $object)"
echo "---- Working on $object ----"
bucket_name="$(jq -r '.values.bucket' <<<"$full_object")"
server_side_encryption_configuration="$(jq -c '.values.server_side_encryption_configuration?' <<<"$full_object")"
lifecycle_rule="$(jq -c '.values.lifecycle_rule?' <<<"$full_object")"
versioning="$(jq -c '.values.versioning?' <<<"$full_object")"
cors_rule="$(jq -c '.values.cors_rule?' <<<"$full_object")"
process_value server_side_encryption_configuration $server_side_encryption_configuration ""
process_value lifecycle_configuration $lifecycle_rule "[]"
process_value versioning $versioning "[]"
process_value cors_configuration $cors_rule "[]"
handle_terraform_import acl
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment