Skip to content

Instantly share code, notes, and snippets.

@kharandziuk
Created June 25, 2020 11:50
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save kharandziuk/261946c0eabc66cf6fb96f0cd7d3ecae to your computer and use it in GitHub Desktop.
Save kharandziuk/261946c0eabc66cf6fb96f0cd7d3ecae to your computer and use it in GitHub Desktop.
A hack to generate a presigned url in terraform
variable "bucket_name" {
default = "max-bucket-for-testing"
}
provider "aws" {
region = var.aws_region
profile = var.aws_profile
}
resource "aws_s3_bucket" "artifacts" {
bucket = var.bucket_name
}
resource "aws_s3_bucket_object" "file" {
bucket = aws_s3_bucket.artifacts.id
key = "temp_file.txt"
content = "hey, bro"
}
resource "null_resource" "url" {
provisioner "local-exec" {
command = "aws s3 presign s3://${aws_s3_bucket.artifacts.id}/${aws_s3_bucket_object.file.key} >> url"
}
}
data "local_file" "url" {
depends_on = [
null_resource.url
]
filename = "${path.module}/url"
}
output "url" {
value = data.local_file.url.content
}
@matthewhembree
Copy link

I had to do this to consume the url in another resource:

resource "null_resource" "url" {
  triggers = {
    build_number = "${timestamp()}"
  }

  provisioner "local-exec" {
    command = "printf '%s' $(aws s3 presign s3://${aws_s3_object.artifacts.bucket}/${aws_s3_object.file.key}) > url"
  }
}

data "local_file" "url" {
  depends_on = [
    null_resource.url
  ]

  filename = "${path.root}/url"
}

resource "aws_cloudformation_stack" "foo" {
  name = "somethingThatICouldOnlyDoWithCloudFormation"
  ...
  template_url = data.local_file.url.content
}
  • Changed the append >> to a > and added a trigger to make this idempotent.
  • Added the printf to eliminate the line-feed (0x0A) the the redirect adds.

This was a big help. Thank you!

@jack-at-circle
Copy link

Thanks for the resource! This didn't exactly work for my use case, but here's what I wound up using for those who come after:

data "external" "presigned_url" {
  program = ["bash", "${path.module}/presign.sh"]
  query = {
    region = var.s3_region
    bucket = var.s3_bucket
    object = var.s3_object
  }
}

resource "aws_cloudformation_stack" "foo" {
  name = "somethingThatICouldOnlyDoWithCloudFormation"
  ...
  template_url = data.external.presigned_url.result.url
}

presign.sh

# Script template: https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/external 
set -e
eval "$(jq -r '@sh "REGION=\(.region) BUCKET=\(.bucket) OBJECT=\(.object)"')"
URL="$(AWS_REGION=$REGION aws s3 presign s3://$BUCKET/$OBJECT)"
jq -n --arg url "$URL" '{"url":$url}'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment