How to deploy Azure Function App with Terraform and BitBucket Cloud

Combining the power of the Infrastructure-as-Code platform Terraform by HashiCorp with a serverless environment like Azure Cloud Platform, we gain a reproducable and tracable environmental setup with a basic failover scenario. Of course, a code repository like Bitbucket Cloud allows us to implement a Continuous Deployment pipeline (also of course a Continous Integration pipeline, but different topic).

The scenario describes one or more developers commiting their changes of code for an serverless Azure Function App („Function-as-a-Service“) and managing the required Azure environment resources only by declaration in Terraform scheme in the code repository to remain the Single Point of Truth (SPOT).

We want to use the events on the repository connected with the specified Terraform Cloud Workspace, e.g. the commit push or the successful merge of a Pull Request to a specific branch, to trigger specific updates in certain environments.
Typically, there are some development or quality-check environments, and of course the production.

In the scenario, Terraform will listen to the master branch of the repository, uses the declared configuration of the enviroment to setup Azure Cloud with the required resources, which will already be prepared to be connected to the repository to listen to, as to keep the application up to date if further code changes appear.

Preparations

  1. Create a Terraform cloud account
  2. Download Terraform CLI for testing purposes
  3. Prepare a new BitBucket Cloud repository
  4. Connect Terraform and BitBucket
  5. Prepare Azure Subscription
  6. Create a function app

Create a new Terraform Cloud workspace and connect it to your BitBucket Cloud repository.

Terraform Cloud Workspace
Terraform Cloud Workspace

Add the required environmental variables to deploy to the Azure Cloud Platform.

Required environment variables to allow access to the Azure Cloud Platform
Required environment variables to allow access to the Azure Cloud Platform

Terraform Configuration

The following will be specified as a Terrform configuration file (v0.12), e.g. terraform.tf, in the root directory of the project.
Multiple files and the module scheme usage are possible, but for simplicity, only one file is used in this scenario.
Replace placeholder values with the specific one of your own setup.

variable "prefix" {
    description = "The Prefix used for all resources in this example"
    default = "AllInData"
}

variable "location" {
    description = "The Azure Region in which all resources in this example should be created."
    default = "westeurope"
}

provider "azurerm" {
    version = "~>2.0"
    features {}
}

resource "azurerm_resource_group" "terraformDemo-rg" {
    name = "${var.prefix}_Terraform_Demo"
    location = var.location
}

resource "azurerm_storage_account" "terraformDemo-storage" {
    name                     = "allindatatfdemostorage"
    resource_group_name      = azurerm_resource_group.terraformDemo-rg.name
    location                 = azurerm_resource_group.terraformDemo-rg.location
    account_tier             = "Standard"
    account_replication_type = "LRS"
}

resource "azurerm_app_service_plan" "terraformDemo-appplan" {
    name                = "${var.prefix}-slotAppServicePlan"
    location            = azurerm_resource_group.terraformDemo-rg.location
    resource_group_name = azurerm_resource_group.terraformDemo-rg.name
    sku {
        tier = "Standard"
        size = "S1"
    }
}

resource "azurerm_function_app" "terraformDemo-funcapp" {
    name                      = "${var.prefix}-funcapp"
    location                  = azurerm_resource_group.terraformDemo-rg.location
    resource_group_name       = azurerm_resource_group.terraformDemo-rg.name
    app_service_plan_id       = azurerm_app_service_plan.terraformDemo-appplan.id
    storage_connection_string = azurerm_storage_account.terraformDemo-storage.primary_connection_string
    app_settings              = {
        "APPINSIGHTS_INSTRUMENTATIONKEY" = "XXXXXXXXX",
        "FUNCTIONS_WORKER_RUNTIME" = "dotnet", 
        "FUNCTIONS_EXTENSION_VERSION" = "~2" ,
        "WEBSITE_RUN_FROM_PACKAGE" = ""
    }

    version                   = "~2"
    https_only                = true

    site_config {
        always_on = true
        ftps_state = "Disabled"
        http2_enabled = true
    }

    provisioner "local-exec" {
        command = "az functionapp deployment source config --ids ${azurerm_function_app.terraformDemo-funcapp.id} --repo-url https://bitbucket.org/XXX/YYY --branch master --manual-integration"
    }
}

Test configuration locally

After installing the Terraform CLI locally on your machine, it is possible to test the configuration without the need of triggering events in the git repository.
Currently, the environmental state is persisted on the machine executing the commands. Note, that there will be a fuzzified state mixup, if the state is not persisted remotely in a central storage and the commands are triggered from a different machine.

Terraform Cloud does not know, what your local machine knows about the Azure Cloud environment, but there is a solution for this, which I added as a notification at the end of this article.

For testing your Terraform configuration, run the plan command. This just checks with the target environment, but no changes will be applied, so it is save to execute the command.

terraform plan

For execution the Terraform configuration plan (pre-saved or newly processed), use the apply command. It will ask you, if you are sure to execute, and if you are, you enter yes to the command line.
This is for the local machine. On Terraform Cloud, you can configure in your workspace settings, if a intermitting manual confirmation is required, so both options of supervised and unsupervised execution are possible.

terraform apply

Run remotely on Terraform Cloud

After the correct configuration of our workspace in Terraform Cloud, we add a connection to a BitBucket Cloud repository and add the required Environment variables for Azure Deployment.

If you push code changes to the BitBucket Cloud repository, the Terraform Cloud workspace will recognize those changes nearly immediately and starts the execution of the configuration.

Terraform Cloud workspace plan overview
Terraform Cloud workspace plan overview

Review your workspace, if the Terraform plan has been successfullly placed, and confirm the execution.

If the Terraform Cloud workspace plan has been placed successfully, confirm to apply
If the Terraform Cloud workspace plan has been placed successfully, confirm to apply

You can know revise the Azure Cloud Platform, and see (maybe with some minor delay) the creation and build-up of the declared environment by Terraform.

Review the environment in Azure Cloud applied by Terraform Cloud
Review the environment in Azure Cloud applied by Terraform Cloud

Remote state provider

If you mix the deployment with Terraform Cloud and the local command line, the persisted states get mixed up. The states are stored on the running machine (Terraform Cloud or your local machine), so what you really want in this case is a remote storage for the states. So while we are using Azure Cloud Platform in this scenario, we can store the states there, in a separate and remote Storage Account.

Summary

Infrastructure-as-Code platform Terraform Cloud allows a very easy setup of environmental Continuous Deployment. If you want to learn more or are in need of assistance, we can help. Contact us to discuss how to ensure a fitting Infrastructure-as-Code solution and the support of integrating Terraform Cloud to your deployment stack.

Best regards,
Florian Horn

Gefällt Ihnen der Artikel?

Share on linkedin
Share on Linkdin
Share on xing
Share on XING
Share on twitter
Share on Twitter
Share on facebook
Share on Facebook
Ihre Daten werden gemäß unserer Datenschutzerklärung erhoben und verarbeitet.
Künstliche Intelligenz Machine Learning Parts
Data Analytics
Henrik Hain

Time as a Machine Learning Feature

Quite often it is the case that cyclic data is not sufficiently transformed for machine learning algorithms, e.g. feature representation is missing out on the implicit properties of cyclic features often resulting in wrong distance measures. This article introduces cyclic feature transformation for time based features as a mini-howto.

Weiterlesen »