Deploying a HTTP Function using Terraform¶
This section describes on how to deploy an HTTP Function using Terraform.
Prerequisite¶
Terraform configured according to Prepare the Terraform environment
Exiting API Gateway instance to create the trigger for the HTTP Function.
Full sample can be found on Github: Building HTTP Function.
Terraform Scripts¶
Terraform deployment scripts can be found in: samples-doc/buildinghttpfunction/terraform
provider.tf¶
This script configures the OpenTelekomCloud provider for Terraform.
# ----------------------------------------------------------------------------
# Secret variables to be injected as envvar (capital letters for Windows systems)
# - no defaults
# - Declared as sensitive --> Not printed in console or log if used in resources
# ----------------------------------------------------------------------------
# set by environment variable TF_VAR_OTC_SDK_AK
variable "OTC_SDK_AK" {
description = "Personal access key"
type = string
sensitive = true
}
# set by environment variable TF_VAR_OTC_SDK_SK
variable "OTC_SDK_SK" {
description = "Personal secret key"
type = string
sensitive = true
}
# set by environment variable TF_VAR_OTC_SDK_DOMAIN_NAME
variable "OTC_SDK_DOMAIN_NAME" {
description = "Domain Name, eg. OTC-EU-DE-000000000010000XXXXX"
type = string
}
# set by environment variable TF_VAR_OTC_SDK_PROJECTID
variable "OTC_SDK_PROJECTID" {
description = "Project Id"
type = string
}
# set by environment variable TF_VAR_OTC_SDK_PROJECTNAME
variable "OTC_SDK_PROJECTNAME" {
description = "Project Name, eg. eu-de_MYPROJECT"
type = string
}
# set by environment variable TF_VAR_OTC_IAM_ENDPOINT
variable "OTC_IAM_ENDPOINT" {
description = "IAM Endpoint"
type = string
default = "https://iam.eu-de.otc.t-systems.com/v3"
}
terraform {
required_providers {
# specifies required provider, source and version
# see https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest
opentelekomcloud = {
source = "opentelekomcloud/opentelekomcloud"
version = ">= 1.36.57"
}
}
backend "s3" {
# See: https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest/docs/guides/backends
# (Required) Specifies the endpoint for OpenTelekomCloud OBS.
# The value is https://obs.{{region}}.otc.t-systems.com.
# This can also be sourced from the AWS_S3_ENDPOINT environment variable
endpoints = {
s3 = "https://obs.eu-de.otc.t-systems.com"
}
# (Required) Specifies the bucket name where to store the state.
# Make sure to create it before.
bucket = "<your-bucket-name>"
# (Required) Specifies the path to the state file inside the bucket.
key = "<path/to/your/terraform.tfstate>"
# (Required) Specifies the region where the bucket is located.
# This can also be sourced from the AWS_DEFAULT_REGION and
# AWS_REGION environment variables.
region = "<your-region>"
# (Required) Skip credentials validation via the STS API.
# It's mandatory for OpenTelekomCloud.
skip_credentials_validation = true
# (Required) Skip validation of provided region name.
# It's mandatory for OpenTelekomCloud.
skip_region_validation = true
skip_requesting_account_id = true
# (Required) Skip usage of EC2 Metadata API.
# It's mandatory for OpenTelekomCloud.
skip_metadata_api_check = true
# (Optional) Do not include checksum when uploading S3 Objects.
# Useful for some S3-Compatible APIs.
skip_s3_checksum = true
# Although the terraform block does not accept variables or locals and
# all backend configuration values must be hardcoded, you can provide
# the credentials via the AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY
# environment variables to access OBS, respectively:
#
# export AWS_ACCESS_KEY_ID="your accesskey"
# export AWS_SECRET_ACCESS_KEY="your secretkey"
#
# secret_key set env var: AWS_ACCESS_KEY_ID
# access_key set env var: AWS_SECRET_ACCESS_KEY
}
}
# ----------------------------------------------------------------------------
# Providers settings --> OTC
# We use the AKSK auth scheme
# See https://registry.terraform.io/providers/opentelekomcloud/opentelekomcloud/latest/docs
# ----------------------------------------------------------------------------
#
provider "opentelekomcloud" {
auth_url = var.OTC_IAM_ENDPOINT
access_key = var.OTC_SDK_AK
secret_key = var.OTC_SDK_SK
domain_name = var.OTC_SDK_DOMAIN_NAME
tenant_name = var.OTC_SDK_PROJECTNAME
}
variables.tf¶
This script defines the variables used in the Terraform scripts.
# prefix will be prepended to all resource names
variable "prefix" {
type = string
default = "sample"
}
# FunctionGraph: Function name
variable "function_name" {
type = string
default = "function_name"
}
# name of zip file to deploy, generated by 'mvn package' command
variable "zip_file_name" {
type = string
default = "deploy.zip"
}
# Resource tag:
variable "tag_app_group" {
type = string
default = "your_tag_app_group_here"
}
variable "API_GATEWAY_INSTANCE_ID" {
type = string
default = "your_api_gateway_instance_id"
}
variables.tfvars¶
This file provides values for the variables defined in variables.tf.
# Terraform variables for http_minimalWebAPI sample
# prefix of all resources
prefix = "go"
# name of the function (will be prefixed)
function_name = "go-doc-sample-http"
# resources will be tagged with this app_group tag
tag_app_group = "go-doc-sample-http"
# 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"
loggroup.tf¶
This script creates a log group and log stream in LTS.
##########################################################
# 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
}
}
function.tf¶
This script creates the HTTP Function using the container image.
##########################################################
# Create http function
##########################################################
resource "opentelekomcloud_fgs_function_v2" "MyFunction" {
name = format("%s_%s", var.prefix, var.function_name)
app = "default"
handler = "bootstrap"
runtime = "http"
code_type = "zip"
func_code = filebase64(format("${path.module}/../%s", var.zip_file_name))
code_filename = var.zip_file_name
description = "Sample on deploy http function in go"
memory_size = 512
timeout = 30
max_instance_num = 1
# if you need security access key, security secret key and security token
# to access other OTC services, set enable_auth_in_header to true
enable_auth_in_header = false
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
# set some environment variables
user_data = jsonencode({
"RUNTIME_LOG_LEVEL" : "DEBUG",
})
tags = {
"app_group" = var.tag_app_group
}
}
In the function.tf script, the relevant part to create the HTTP Function using code from zip file is as follows:
handler = "bootstrap"
code_type = "zip"
runtime = "http"
func_code = filebase64(format("${path.module}/../%s", var.zip_file_name))
code_filename = var.zip_file_name
api_trigger.tf¶
This script creates an API Gateway trigger and all relevant resources to invoke the HTTP Function:
API gateway group (opentelekomcloud_apigw_group_v2)
API resource (opentelekomcloud_apigw_api_v2) that connects this API to the FunctionGraph function
publish API using (opentelekomcloud_apigw_api_publishment_v2)
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
}
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)
}
Note
To have full control over resources being created this sample does not use opentelekomcloud_fgs_trigger_v2 for APIG Trigger creation,
testevent.tf¶
This script creates a test event to test the HTTP Function.
##########################################################
# Create Test Event
##########################################################
resource "opentelekomcloud_fgs_event_v2" "test_event" {
function_urn = opentelekomcloud_fgs_function_v2.MyFunction.urn
name = "TestEvent"
content = filebase64("../test_event.json")
}
Deployment¶
MakefileTF¶
To simplify the development and testing process, see MakefileTF in the project root folder:
# Makefile for Terraform deployment of the HTTP Function sample
# Include Makefile for build
include ./Makefile
# Terraform backend configuration
BACKEND_CONFIG_BUCKET := "doc-samples-tf-backend"
BACKEND_CONFIG_KEY := "terraform_state/go/go-buildinghttpfunction.tf"
BACKEND_CONFIG_REGION := "eu-de"
BACKEND_CONFIG_ENDPOINTS := "endpoints={s3=\"https://obs.eu-de.otc.t-systems.com\"}"
CURRENT_MAKEFILE := $(firstword $(MAKEFILE_LIST))
tf_init:
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)"
tf_plan:
if [ ! -f "terraform/.terraform.lock.hcl" ]; then \
$(MAKE) -f $(CURRENT_MAKEFILE) initTerraform; \
fi
terraform -chdir=terraform \
plan \
-var-file="variables.tfvars"
tf_apply: all
if [ ! -f "terraform/.terraform.lock.hcl" ]; then \
$(MAKE) -f $(CURRENT_MAKEFILE) initTerraform; \
fi
terraform -chdir=terraform \
apply -auto-approve \
-var-file="variables.tfvars"
tf_destroy:
terraform -chdir=terraform \
destroy -auto-approve \
-var-file="variables.tfvars"
test_deployed:
# get the API Gateway URL from terraform output
$(eval API_GATEWAY_TRIGGER_URL := $(shell terraform -chdir=terraform output -raw API_GATEWAY_TRIGGER_URL))
@echo "Using API Gateway URL: $(API_GATEWAY_TRIGGER_URL)"
# execute a curl request against the deployed function via API Gateway
curl -X GET $(API_GATEWAY_TRIGGER_URL)/hello
@echo ""
.PHONY: tf_init tf_plan tf_apply tf_destroy test_deployed
This MakefileTF imports all targets from the build Makefile and provides additional targets for Terraform deployment.
Initialize Terraform¶
To initialize Terraform, run following command in the project root folder:
make -f MakefileTF tf_init
Plan Terraform deployment¶
To plan the Terraform deployment, run following command in the project root folder:
make -f MakefileTF tf_plan
Deploy using Terraform¶
To deploy the HTTP Function using Terraform, run following command in the project root folder:
make -f MakefileTF tf_apply
Test deployed Function¶
To test the deployed HTTP Function using the API Gateway trigger, run following command in the project root folder:
make -f MakefileTF test_deployed
Cleanup deployed resources¶
Note
To destroy the deployed resources, run following command in the project root folder:
make -f MakefileTF tf_destroy