Deploy FunctionGraph Event Function from OBS¶
This sample demonstrates how to deploy a simple event function to FunctionGraph with code from OBS using Terraform.
This approach is used, if your unpacked FunctionGraph deployment package is less than 40MB.
Source code of this sample is available on GitHub.
Prerequisites¶
running on Linux / Windows Subsystem for Linux (WSL)
make installed
Terraform installed and configured, see Terraform Setup.
Example¶
An example for deploying a HTTP Function using Terraform can be found in: samples-doc/http_minimalWebAPI/terraform.
This example deploys a minimal C# HTTP Function and demonstrates how to:
upload the Function code as zip file to an OBS bucket (and update on changes), see: code_from_obs_bucket.tf
################################################################################### # Code bucket to store function code zip file ################################################################################### resource "opentelekomcloud_obs_bucket" "codebucket" { bucket = format("%s-%s", var.prefix, "codebucket") acl = "private" tags = { "app_group" = var.tag_app_group } } ################################################################################### # Code bucket object to upload function code zip file ################################################################################### resource "opentelekomcloud_obs_bucket_object" "code_object" { bucket = opentelekomcloud_obs_bucket.codebucket.bucket key = format("%s/%s", "code", basename(var.zip_file_local)) source = var.zip_file_local etag = filemd5(var.zip_file_local) content_type = "application/zip" }
create the Function using the code from the OBS bucket, see: function.tf
########################################################## # Create Function ########################################################## resource "opentelekomcloud_fgs_function_v2" "MyFunction" { depends_on = [opentelekomcloud_obs_bucket_object.code_object] name = format("%s_%s", var.prefix, var.function_name) app = "default" handler = var.function_handler_name description = "Minimal WebAPI deployed with terraform." memory_size = 256 timeout = 30 max_instance_num = 10 runtime = var.function_runtime user_data = jsonencode({ "USE_SWAGGER_UI" = var.use_swagger_ui }) ###### relevant part for deploy function code from obs file ###### code_type = "obs" code_url = format("https://%s/%s/%s", opentelekomcloud_obs_bucket.codebucket.bucket_domain_name, "code", basename(var.zip_file_local) ) # on change of the code object etag (hash) new code version will be deployed. source_code_hash = opentelekomcloud_obs_bucket_object.code_object.etag ###### ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ###### log_group_id = opentelekomcloud_lts_group_v2.MyLogGroup.id log_group_name = opentelekomcloud_lts_group_v2.MyLogGroup.group_name log_topic_id = opentelekomcloud_lts_stream_v2.MyLogStream.id log_topic_name = opentelekomcloud_lts_stream_v2.MyLogStream.stream_name tags = { "app_group" = var.tag_app_group } } output "MY_FUNCTION_URN" { value = opentelekomcloud_fgs_function_v2.MyFunction.urn } output "MY_FUNCTION_VERSION" { value = opentelekomcloud_fgs_function_v2.MyFunction.version }
configure the API Trigger for the Function using
API-Group,
API and
publishment to an environment,
locals { API_GATEWAY_INSTANCE_ID = var.API_GATEWAY_INSTANCE_ID ENV_NAME = "RELEASE" ENV_ID = "DEFAULT_ENVIRONMENT_RELEASE_ID" } ########################################################## # opentelekomcloud_apigw_group_v2.group ########################################################## resource "opentelekomcloud_apigw_group_v2" "group1" { # depends_on = [ opentelekomcloud_fgs_function_v2.MyFunction ] name = replace(format("%s_%s_api_group", var.prefix, var.function_name), "-", "_") instance_id = local.API_GATEWAY_INSTANCE_ID description = format("API Group for %s, %s", var.prefix, var.function_name) } ########################################################## # opentelekomcloud_apigw_api_v2.api1 # This is used to create the API Gateway trigger for the # FunctionGraph function. ########################################################## resource "opentelekomcloud_apigw_api_v2" "api1" { # TRIGGER-INSTANCE_id gateway_id = local.API_GATEWAY_INSTANCE_ID # TRIGGER-GROUP_id group_id = opentelekomcloud_apigw_group_v2.group1.id # TRIGGER-Name name = replace(format("%s_%s_apig_trigger", var.prefix, var.function_name), "-", "_") # TRIGGER-TYPE:1 type = "Public" # TRIGGER-PROTOCOL: HTTPS request_protocol = "HTTPS" # TRIGGER-REG_METHOD: HTTPS request_method = "ANY" # TRIGGER-PATH request_uri = "/" # TRIGGER-AUTH: NONE security_authentication_type = "NONE" # TRIGGER-MATCH_MODE: SWA match_mode = "PREFIX" success_response = "Success response" failure_response = "Failed response" description = format("Created by script for %s-%s", var.prefix, var.function_name) func_graph { function_urn = opentelekomcloud_fgs_function_v2.MyFunction.urn version = "latest" timeout = 5000 invocation_type = "sync" network_type = "NON-VPC" } } ########################################################## # Publish API to specific environment ########################################################## resource "opentelekomcloud_apigw_api_publishment_v2" "default" { gateway_id = local.API_GATEWAY_INSTANCE_ID environment_id = local.ENV_ID api_id = opentelekomcloud_apigw_api_v2.api1.id version_id = opentelekomcloud_apigw_api_v2.api1.version # force publishing on change of api lifecycle { replace_triggered_by = [ opentelekomcloud_apigw_api_v2.api1 ] } } output "API_GATEWAY_TRIGGER_URL" { description = "The URL of the API Gateway triggering the FunctionGraph function" value = format("https://%s.apic.%s.otc.t-systems.com", opentelekomcloud_apigw_group_v2.group1.id , opentelekomcloud_apigw_group_v2.group1.region) } output "SWAGGER_UI_URL" { description = "The URL for Swagger UI to test the API endpoints" value = var.use_swagger_ui == "true" ? format("https://%s.apic.%s.otc.t-systems.com/swagger/index.html", opentelekomcloud_apigw_group_v2.group1.id , opentelekomcloud_apigw_group_v2.group1.region) : "Swagger UI is disabled" }
configure logging for the Function using LTS Log Group and Log Stream, see loggroup.tf
########################################################## # Create Log Group ########################################################## resource "opentelekomcloud_lts_group_v2" "MyLogGroup" { group_name = format("%s_%s_%s", var.prefix, var.function_name, "log_group") ttl_in_days = 1 tags = { "app_group" = var.tag_app_group } } ########################################################## # Create Log Stream ########################################################## resource "opentelekomcloud_lts_stream_v2" "MyLogStream" { group_id = opentelekomcloud_lts_group_v2.MyLogGroup.id stream_name = format("%s_%s_%s", var.prefix, var.function_name, "log_stream") tags = { "app_group" = var.tag_app_group } }
configure test events for the Function to be used in the Function Graph console, see func_testevents.tf
########################################################## # Create Test Event ########################################################## resource "opentelekomcloud_fgs_event_v2" "apievent_hello" { function_urn = opentelekomcloud_fgs_function_v2.MyFunction.urn name = "hello-event" content = filebase64("${path.module}/../resources/apievent_hello.json") } ########################################################## # Create Test Event ########################################################## resource "opentelekomcloud_fgs_event_v2" "apievent_root" { function_urn = opentelekomcloud_fgs_function_v2.MyFunction.urn name = "root-event" content = filebase64("${path.module}/../resources/apievent_root.json") }
To deploy the HTTP Function using Terraform follow these steps:
Create an API Gateway or use an existing one. (Creating an API Gateway is not part of this Terraform setup.) See Creating a Gateway for instructions on how to create an API Gateway. Note down the instance ID to be used in Terraform configuration.
Adjust the
http.tfvarsfile according to your needs.Set the API_GATEWAY_INSTANCE_ID variable to your API Gateway instance ID (or define it as environment variable TF_VAR_API_GATEWAY_INSTANCE_ID).
# Terraform variables for http_minimalWebAPI sample # prefix of all resources prefix="csharp" # name of the function (will be prefixed) function_name="doc-sample-minimal-webapi" # function handler name, for http functions always "bootstrap" function_handler_name="bootstrap" # function runtime, for http functions always "http" function_runtime="http" # path to local zip file to be deployed zip_file_local="../src/http_minimalWebAPI_net8.0.zip" # resources will be tagged with this app_group tag tag_app_group="csharp-doc-sample-minimal-webapi" # change to your API Gateway instance ID # set as env var TF_VAR_API_GATEWAY_INSTANCE_ID or uncomment and set here #API_GATEWAY_INSTANCE_ID="YOUR_API_GATEWAY_INSTANCE_ID"
Create a Makefile in the project folder and adjust the variables in the Makefile according to your needs:
mkfile_path := $(abspath $(lastword $(MAKEFILE_LIST)))/.. current_dir := $(notdir $(patsubst %/,%,$(dir $(mkfile_path)))) BACKEND_CONFIG_BUCKET := "doc-samples-tf-backend" BACKEND_CONFIG_KEY := "terraform_state/csharp/http_minimalWebAPI.tf" BACKEND_CONFIG_REGION := "eu-de" BACKEND_CONFIG_ENDPOINTS := "endpoints={s3=\"https://obs.eu-de.otc.t-systems.com\"}" clean: rm -f $(mkfile_path)/src/*.zip rm -rf $(mkfile_path)/src/bin rm -rf $(mkfile_path)/src/obj build: dotnet build all: build release: dotnet publish -c Release initTerraform: terraform -chdir=terraform \ init \ -backend-config=$(BACKEND_CONFIG_ENDPOINTS) \ -backend-config="bucket=$(BACKEND_CONFIG_BUCKET)" \ -backend-config="key=$(BACKEND_CONFIG_KEY)" \ -backend-config="region=$(BACKEND_CONFIG_REGION)" plan: release if [ ! -f "terraform/.terraform.lock.hcl" ]; then \ $(MAKE) initTerraform; \ fi terraform -chdir=terraform \ plan \ -var-file="http.tfvars" deploy: release if [ ! -f "terraform/.terraform.lock.hcl" ]; then \ $(MAKE) initTerraform; \ fi terraform -chdir=terraform \ apply -auto-approve \ -var-file="http.tfvars" deploy_nobuild: @if [ ! -f "terraform/.terraform.lock.hcl" ]; then \ echo "backend not initialized..."; \ else \ terraform -chdir=terraform \ apply -auto-approve \ -var-file="http.tfvars"; \ fi destroy: terraform -chdir=terraform \ destroy -auto-approve \ -var-file="http.tfvars" .PHONY: build zip clean all release deploy destroy initTerraform plan
To deploy using the terraform/http.tfvars configuration, execute the following commands in the project root folder:
make deploy
Note
To destroy the deployed resources again you can use:
make destroy