Reputation: 16226
I'm working within Terraform to configure an AWS Lambda - and initially, I've had the JS file that is the entirety of the lambda function within my Terraform directory:
data "archive_file" "auth_requests" {
type = "zip"
source_file = "${path.module}/auth_requests/index.js"
output_path = "${path.module}/auth_requests.zip"
}
resource "aws_lambda_function" "auth_requests" {
function_name = "auth_requests"
filename = "${data.archive_file.auth_requests.output_path}"
role = "${aws_iam_role.auth_requests.arn}"
handler = "index.handler"
source_code_hash = "${data.archive_file.auth_requests.output_base64sha256}"
runtime = "nodejs8.10"
}
However, it's clear that the Lambda function should get its own git repo, rather than living within our broader Terraform repo. Is there a way to use Terraform to source files from a git repo (and then brought into the generated archive)?
I could define the lambda's GitHub repo as a resource, but then what would be the next steps for getting it cloned/updated so the archive_file
can refer to it? Or can a Terraform module be repurposed for something like this?
Upvotes: 10
Views: 6700
Reputation: 5184
Another option is to use Terraform for your infrastructure setup & maintenance, but then manage deploys directly through Github Actions.
Your Terraform setup will just bootstrap an initial version of the function code, with subsequent updates coming straight from GitHub. Use the ignore_changes meta-argument so that Terraform doesn't get mad about the drift.
terraform-repo/lambda.tf
will set up the lambda but ignore changes from deploy:resource "aws_lambda_function" "lambda" {
function_name = ...
role = ...
handler = ...
# just include a basic "hello world, this is a stub" handler in here
filename = '${module}/lambda_stub.zip'
lifecycle {
ignore_changes = [
'last_modified',
'source_code_hash'
]
}
}
Code-repo/.github/workflows/deploy_lambda.yml
will actually do the deploy:name: Deploy Lambda
on:
push:
branches:
- main
workflow_dispatch:
jobs:
deploy_zip:
name: deploy lambda function
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Zip up the code
run: zip -r build.zip ./src
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ secrets.AWS_REGION }}
- name: Update Lambda code
run: aws lambda update-function-code --function-name=${{ secrets.LAMBDA_NAME }} --zip-file=fileb://build.zip
This way you can deploy quickly without doing an entire terraform plan
cycle, and you can still use terraform to update and maintain your infrastructure.
Upvotes: 1
Reputation: 2269
Assuming you use a Github repository to store your JS function, you can make use of the Github Content API to download a zip of the repo using curl
:
curl -L -o <output zip filename> https://<github repo url>/zipball/master
You can achieve this in Terraform using the External
provider instead of the Archive
provider:
data "external" "download_function" {
program = ["curl", "-L", "-o",
"${path.module}/auth_requests.zip", "${var.github_repo_url}"]
}
The downside is that you now have an external dependency (curl).
Upvotes: 1