I currently have a Terraform file that is used to set up a website with s3 and CloudFront. My website has a dynamic component with Lambda Function URL that adds to a Dynamo DB table when my website is viewed. Everything works good, but my problem is I don’t know how to get the function URL after Terraform is complete to automatically update in my javascript file, if this is possible or any other way. Right now, I have to go into the Javascript file and copy and paste the function URL from Lambda after my Terraform has ran, but I would like everything to be fully automated.
My javascript file(XXX= the function url that I have to hardcode):
const counter = document.querySelector(".counter-number");
async function updateCounter() {
let response = await fetch("XXX");
let data = await response.json();
counter.innerHTML = `Website View Count: ${data}`;
}
updateCounter();
The portion of my Terraform where the Javascript file is uploaded to S3 – I currently have it to where any change in my website files is picked up through Terraform:
resource "aws_s3_object" "website_contents" {
for_each = fileset("/Users/andrea/Documents/AWS/CRC/my_website", "**")
bucket = data.aws_s3_bucket.main_bucket.id
key = each.key
source = "/Users/andrea/Documents/AWS/CRC/my_website/${each.value}"
content_type = each.value
etag = filemd5("/Users/andrea/Documents/AWS/CRC/my_website/${each.value}")
}
Please let me know if there is any thing else I can provide, I appreciate any sort of help and assistance- thank you!
2
Answers
What you could try is to save the
function_url
in a variable and then use this variable to edit a local file usingsed
with alocal-exec
provisioner. Hope this helps!The resource
lambda_function_url
exports three attributes:function_arn
The Amazon Resource Name (ARN) of the function.function_url
The HTTP URL endpoint for the function in the format https://<url_id>.lambda-url..on.aws.url_id
A generated ID for the endpoint.This means that the resource provides certain pieces of information that can be used by other parts of your Terraform configuration. These attributes can be referenced and used in other resources or data blocks.
Assuming you have something like this in your
.tf
files:You can define a variable
myURL
And here’s the code to edit the file ./my_website/myfile.js
This will substitute the URL using
sed
in a filemyfile.js
looking like this:Beside the option given in the previous question, let me give you another option you can consider.
Injecting views count as a query parameter
Since you’ve already using CloudFront, you may consider to convert your Web-facing Lambda function into Lambda.Edge function and connect it to the CloudFront Distribution you have as a
viewer-request
handler.This way you will be able to rewrite request before it gets processed by the origin.
The code for your Lambda.Edge might look like the following:
Your frontend code can be simplified, since views count will be provided as a query parameter, so no need to call a Lambda: