FME Flow Express Install using Infrastructure-As-Code Tools

Merline George
Merline George
  • Updated

Introduction

This document outlines an FME Flow Express Deployment on the Azure cloud. It uses Terraform to define the cloud infrastructure [i.e. a virtual machine and associated resources], a single PowerShell script to handle the Flow installation and FME Flow APIs within the script for common post-Flow deployment configuration steps. 

As mentioned, Flow will be installed on a new Azure Windows VM. For our deployment, the front endpoint/proxy will be an existing Azure Application Gateway. 

Please be advised that these scripts were developed and tested for the Flow version 2025.1.3.1.

 

Pre-requisites

On Azure Cloud 

  • These resources were already created within a resource group. 
    • A virtual network [we have two subnets within it- one for the app gateway and one for the VM]
    • An application gateway connected to the virtual network [this application gateway has no VMs in the backend pool yet; the script will add the newly created VM to the backend pool] 
    • A public IP address for the app gateway 
    • A storage account to store the PowerShell scripts used 
    • An optional bastion subnet to connect outside of RDP

The Flow host VM will also be created within the same resource group.

  • The PowerShell script fme-flow-deploy.ps1 is stored in the Azure storage account container called scripts

  • We created a separate empty container under the same storage account to store the state file .tfstate auto-generated in this deployment. This is the output file that records the deployed infrastructure. It will be securely and automatically stored in the Azure Storage container tfstate as a best practice, once the deployment is successful.

  • We generated a read-only Shared Access Signature (SAS) token for fme-flow-deploy.ps1 script at the container or storage account level. This token is then passed with the terraform apply command. 

However, you do not need a SAS token for Terraform to access the tfstate container because your login (via az login) grants Terraform the necessary permissions to read and write the state file.

 

On the Local Machine Running the Terraform Commands 

  • Installed Terraform v1.13.3 and azure-cli 2.77.0, which were the latest at the time of testing. 
  • The terraform main.tf script is stored in the local machine running the commands. Terraform cannot directly run your main.tf file from an Azure Storage container because the Terraform CLI is a local client tool that needs your configuration files to be present in the current working directory.
  • This is where the remote backend configuration for tfstate file is defined in main.tf file. Please edit the Storage_account_name and  container_name with your own storage and container name. 

 

Scripts Explained

main.tf: Infrastructure Definition (Terraform)

The main.tf file serves as the single source of truth for your infrastructure. It defines and provisions all the necessary Azure resources and is responsible for passing environment-specific configurations and credentials securely to the VM/PowerShell script.

Resource/ComponentPurpose in Deployment
terraform Block & BackendConfigures Terraform itself. The backend "azurerm" section ensures the state file is securely stored in Azure Blob Storage, enabling state locking and collaboration. 
Variables (variable)Externalizes all configurable values: naming prefixes, network IDs, administrative credentials (vm_admin_password, fme_admin_password), FME licensing details (e.g., fme_serial_number, fme_email), and the FME installer link (fme_installer_url).
Azure VM & NetworkingDefines the Windows Virtual Machine (azurerm_windows_virtual_machine.vm), its associated Public IP (azurerm_public_ip.vm_pip), Network Interface (azurerm_network_interface.vm_nic), and Network Security Group (azurerm_network_security_group.vm_nsg). Configures firewall rules (like HTTP/HTTPS/RDP access) for the VM.
null_resource.add_to_backend_poolExecutes the Azure CLI command locally to dynamically retrieve the VM's private IP address and add it to the Azure Application Gateway's backend pool. This ensures the VM is integrated into the load-balanced URL path.
azurerm_virtual_machine_extension.fmeflow_customscriptThe Integration Point that initiates the automated configuration. It securely downloads the PowerShell script(s) from Azure Storage and executes the commandToExecute, passing all necessary configuration variables from Terraform directly to the script's command line.

 

fme-flow-deploy.ps1: Software Orchestration (PowerShell)

This script serves as the deployment orchestrator, responsible for all activities that occur within the Windows VM. It executes the FME Flow Express installation and performs the necessary post-configuration using the FME Flow REST API.

Execution Flow (7 Key Stages)

  1. Preparation & Download: The script receives all parameters from Terraform, sets up logging, and executes the installer download logic (Get-FMEInstaller) using the externalized $InstallerUrl.
  2. Installation: It runs the FME Flow installer (Install-FMEFlow) in silent mode (-s), configuring the core services and local PostgreSQL database.
  3. Hardening: It executes post-installation tasks, such as forcefully disabling the Windows VM Firewall. You can customize the Windows firewall rule instead of disabling it. 
  4. Stabilization: The script waits a set time (300 seconds / 5 minutes) to ensure all FME Flow Windows Services start and stabilize.
  5. Configuration & Licensing: This is the critical REST API phase, primarily using the Invoke-RestApiCall function.
    • It sends the license request using the provided FME licensing identity and serial number.
    • It waits for activation (Wait-LicenseActivation).
    • It configures the reverse proxy/Application Gateway URL (Set-ServicesBaseUrl).
    • It initiates engine count optimization based on the license capacity.
  6. Verification & Validation: The script runs multiple test workspace jobs (Start-TestWorkspace) to verify that the FME Core, Engines, and external access (via the reverse proxy) are fully functional.
  7. Security Cleanup: The script updates the default administrator password  fme_admin_password to fme_new_admin_password and confirms the new credentials work via a final test run.

 

Script Execution

Please follow the prerequisites mentioned previously. main.tf and fme-flow-deploy.ps1 scripts are attached to the article.

Then, navigate to a new folder on your local machine, save the main.tf file and run the following commands on the command prompt/terminal from this working directory-
  1. az login 
  2. terraform init
  3. export ARM_SUBSCRIPTION_ID="<YourAzureSubscriptionID>
  4. Choose a base_name_prefix which will be added to the name of the Virtual Machine, VM Computer Name, Public IP Address, Network Security Group (NSG), Network Interface (NIC), OS Disk, and VM Extension. You can choose a name that highlights your environment[Dev/Prod/QA]/Flow version/build number.

terraform apply -auto-approve -var="base_name_prefix=<BaseName>" -var="vm_admin_username=<NewFlowAdminUsername>" -var="resource_owner=<Owner>" -var="project_name=<ProjectName>" -var="storage_account_uri=<getTheFullStorageAccountURLFromAzure>" -var="sas_token=<FullSASTokenForTheContainer>" -var="resource_group_name=<AzureResourceGroupName>" -var="location=<location>" -var="app_gateway_name=<NameOfApplicationGateway>" -var="backend_pool_name=<NameOfAppGatewayBackendPool>" -var="fme_admin_username=admin" -var="fme_admin_password=<CurrentFlowAdminPassword>" -var="fme_new_admin_password=<NewFlowAdminPassword>" -var="reverse_proxy_url=http://<AppGatewayFQDN>" -var="vm_admin_password=<VMHostAdminPassword>" -var="fme_serial_number=<licenseSerialNumber>" -var="fme_job_title=<JobTitle>" -var="fme_company=<CompanyName>" -var="fme_industry=<Industry>" -var="fme_email=<email>" -var="fme_first_name=<firstName>" -var="fme_last_name=<LastName>" -var="virtual_network_name=<ExistingVNetName>" -var="subnet_name=<ExistingSubnetName>" -var="fme_installer_url=<InstallerURLfromDownloadsPage>"

5. If you want to tear down the setup quickly -

terraform destroy -auto-approve -var="base_name_prefix=<BaseName>" -var="vm_admin_username=<NewFlowAdminUsername>" -var="resource_owner=<Owner>" -var="project_name=<ProjectName>" -var="storage_account_uri=<getTheFullStorageAccountURLFromAzure>" -var="sas_token=<FullSASTokenForTheContainer>" -var="resource_group_name=<AzureResourceGroupName>" -var="location=<location>" -var="app_gateway_name=<NameOfApplicationGateway>" -var="backend_pool_name=<NameOfAppGatewayBackendPool>" -var="fme_admin_username=admin" -var="fme_admin_password=<CurrentFlowAdminPassword>" -var="fme_new_admin_password=<NewFlowAdminPassword>" -var="reverse_proxy_url=http://<AppGatewayFQDN>" -var="vm_admin_password=<VMHostAdminPassword>" -var="fme_serial_number=<licenseSerialNumber>" -var="fme_job_title=<JobTitle>" -var="fme_company=<CompanyName>" -var="fme_industry=<Industry>" -var="fme_email=<email>" -var="fme_first_name=<firstName>" -var="fme_last_name=<LastName>" -var="virtual_network_name=<ExistingVNetName>" -var="subnet_name=<ExistingSubnetName>" -var="fme_installer_url=<InstallerURLfromDownloadsPage>"

 

Result

You should be able to access Flow UI via the application gateway URL. 

The admin account password should be changed to the new password. 

The install should be licensed, and the engine count should be set to the limit assigned to the license.

Service URL under "System Configuration"> "Network & Email">"Services" section should be changed to the application gateway URL. 

You will also see three successful job runs. 

Was this article helpful?

We're sorry to hear that.

Please tell us why.

As of January 14th, 2026, comments on knowledge base articles have been closed. To make sure questions don’t get missed and to enable more community support, we’ve moved discussions to the FME Community. If you have a question or a comment about this article, please create a new post or create a support ticket.