Skip to content

webstean/terraform-azurerm-compute-function-app

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

592 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Andrew's Terraform module for creating an Azure Function App

Function as a Service (FaaS) with Azure, you'll need to specify runtime, such as support python, etc.. The default is "powershell"

GitHub Repository

Terraform Registry for this module

Terraform Registry Home - my other modules

[![Python][terraform-shield]][tf-version] [![Latest][version-shield]][release-url] [![Tests][test-shield]][test-url] [![License][license-shield]][license-url]

This module is intended to be an example of how you can use Terraform Azure modules in a enterprise like environment.

Important

This module is NOT intended to be used directly. You should fork them and then customise to your own purposes.

Note

At the moment, these modules only support deployment into the Australia regions (australiaeast, australiasoutheast, australiacentral) And, they don't support any value for the SKU variable other than "free", this is to avoid the deployment of super expensive resources. Plus, the variable: private_endpoints_always_deployed must be false, to prevent Private Endpoint from being created and costing you money.

You'll need to fork and customise files like region.tf, main.tf, variables.tf and redeploy into your own Terraform repository (public or private)

The real work is done by the Microsoft supplied and supported Azure Verified Modules. So as things change, you can rely on the Microsoft Azure Verified Modules (AVM) to do the heavy lifting for you and you can just concentre on the high-level.

For more information on Azure Verified Modules, please visit the AVM portal.

This module is ultimately, just boilerplate, validation and some opinions on some of input variables into the Microsoft AVM's should be. Although, if you don't like these choices, you can simple edit this module to suit your own needs.

Another intention of this module, is to be permit to be called via the Azure Deployment Environment via the extensiblity model, although is currently a work in prgoress is not currently supported.

Important

This modules assigns permissions to these resources it creates. Non-Humans are assigned user-assigned permission, whilst actual humans that are members of an Entra ID groups can review the resources and most of its contents. One goal of these modules is that changes should be done by these modules, not by manually by humans. So the assigned permsisions are very low to what you would typically see. The permissions are generally just "Reader and Data Access".

# Example of how to create a release of any module
gh release create v0.0.1 --title "v0.0.1" --notes "Initial release"
gh release delete v0.0.1 --cleanup-tag -yes

gh release create v0.0.2 --title "v0.0.2" --notes "New release"

Example:

module "function_app" {
  source  = "webstean/compute-function-app/azurerm"
  version = "~>0.0, < 1.0"

  ## identity
  entra_group_unified_id         = module.application_landing_zone.entra_group_unified_id         ## services/applications
  entra_group_pag_id             = module.application_landing_zone.entra_group_pag_id             ## services/applications
  user_assigned_identity_name    = module.application_landing_zone.user_assigned_identity_name    ## humans/admin users
  ## naming
  resource_group_name = module.application_landing_zone.resource_group_name
  landing_zone_name   = module.application_landing_zone.landing_zone_name
  project_name        = "main"
  application_name    = "webstean"
  ## sizing
  sku_name            = "free"          ## other options are: basic, standard, premium or isolated
  size_name           = "small"         ## other options are: medium, large or x-large
  location_key        = "australiaeast" ## other supported options are: australiasoutheast, australiacentral
  private_endpoints_always_deployed = false ## other option is: true
  ## these are just use for the tags to be applied to each resource
  owner_service        = "unknown@myorg.com"          ## business owner  - email address, used for visbility & alerts
  owner_tech           = "unknown@myorg.com"          ## business owner  - email address, used for visbility & alerts
  cost_centre          = "unknown"                    ## from the accountants, its the owner's cost centre. Freeform text
  monitoring           = "not-monitored"              ## other options are: 24-7 or 8-5
  ##
  subscription_id     = data.azurerm_client_config.current.subscription_id

  ## Specific to Azure Functions    
  runtime            = "python" ## supported runtimes are: python, nodejs, .net, java, powershell, custom. Defaults to powershell

}

License

Distributed under the Mozilla Public License Version 2.0 License. See LICENSE for more information.

Requirements

Name Version
terraform ~>1.0, < 2.0
acme ~>2.0, < 3.0
alz ~>0.0, < 1.0
azapi ~> 2.0, < 3.0
azuread ~> 3.0, < 4.0
azurerm ~>4.0, < 5.0
random ~>3.0, < 4.0

Resources

Name Type
azuread_service_principal.existing-apim resource
azuread_service_principal.existing-dynamicserp resource
azuread_service_principal.msgraph resource
random_string.naming_seed resource
azuread_application_published_app_ids.well_known data source
azuread_client_config.current data source
azuread_domains.admin data source
azuread_domains.default data source
azuread_domains.initial data source
azuread_domains.root data source
azuread_domains.unmanaged data source
azuread_group.this data source
azuread_service_principal.existing-apim data source
azuread_service_principal.existing-dynamicserp data source
azuread_service_principal.msgraph data source
azurerm_client_config.current data source
azurerm_dns_zone.this data source
azurerm_management_group.root data source
azurerm_resource_group.this data source
azurerm_role_definition.blob_contributor data source
azurerm_role_definition.blob_owner data source
azurerm_role_definition.blob_reader data source
azurerm_role_definition.contributor data source
azurerm_role_definition.file_contributor data source
azurerm_role_definition.owner data source
azurerm_role_definition.queue_contributor data source
azurerm_role_definition.queue_processor data source
azurerm_role_definition.queue_reader data source
azurerm_role_definition.queue_sender data source
azurerm_role_definition.reader data source
azurerm_role_definition.reader_and_access data source
azurerm_role_definition.smb_contributor data source
azurerm_role_definition.smb_reader data source
azurerm_role_definition.storage_defender data source
azurerm_role_definition.table_contributor data source
azurerm_role_definition.table_reader data source
azurerm_subscription.current data source
azurerm_subscriptions.current data source
azurerm_user_assigned_identity.graph data source
azurerm_user_assigned_identity.lz data source

Inputs

Name Description Type Default Required
dns_zone_name This variable provides the name public (future maybe private) DNS zone for the landing zone. The landing zone module will create this DNS zone and two sub-zones for the application (appi) and apis (api)
Any custom names will be defined with this DNS zone, so that the DNS zone can be used to resolve the names of the resources in the landing zone.
string n/a yes
entra_group_pag_id The existing Entra ID Workforce group id (a UUID) that will be given full-ish permissions to the resource.
This is intended for humans, not applications, so that they can access and perform some manage the resources.
One of the intention of this module, is to only allow very limit admin access, so they everything can be managed by the module. (ie by code)
Therefore you'll tpyically see that reosurce creates won't give high-level priviledge like Owner, Contributor to users.
string n/a yes
org_fullname The full name (long form) for your organisation. This is used for more , for use in descriptive and display names.
This is intended to be a human readable name, so that it can be used in the Azure
string n/a yes
org_shortname The short name (abbreviation) of the entire organisation, use for naming Azure resources.
Avoid using exotic characters, so that it can be used in all sorts of places, like DNS names, Azure resource names, Azure AD display names etc...
string n/a yes
resource_group_name (Required) The name of the resource group to deploy the resources into. This resource group needs to be already exist! string n/a yes
subscription_id The Azure Subscription ID for the AzureRM, AzureAD, AzApi providers to use for their deployment.
This is the subscription where the resources will be deployed and whoever is running the module (terraform code) must have high-level permission to this subscription.
Typically this needs to be the following Azure RBAC roles: User Access Administrator and Contributor permissions.
If you using GitHub / Azure DevOps (ADO), then you should leverage OIDC to provide federation, instead of having to maintain secrets, which can be compromised.
string n/a yes
user_assigned_identity_landing_zone_name The Entra ID / Azure Managed Identity that will give access to this resource.
Note, that Managed Identities can be created in either Entra ID (azuread_application) or Azure ()
Unless you need a secret for things, like external authentication, then you should use the Azure variety.
This module only support user-assigned managed identities, not system-assigned managed identities.
string n/a yes
application_name (Required) application_name (freeform) so we can tell what each resource is being used for
This should be a readily recongnisable name for you organisation, and is intended to be a large group of resources that comprise that application.
A common mistake with Azure (and other clouds), is creating too many "applications", like spliting thing into integration, website, database etc...
This usually just makes it harder to manage, so we recommend that you create a single application for each "application" that you are deploying.
Unlike what you may have experience on-premises, put the components like a frontend and database in the same namespace (like as application) you can still every securely separate them from both a security and opertational perspecitve.
The default is "main". Another good options would be "default" but even better would be your internal application name.
string "main" no
bypass_ip_cidr (Required) bypass_ip_cidr (CIDR notation) is a list of IP addresses or CIDR ranges that should be allowed to bypass the firewall for Azure PaaS service like storage accounts, sql servers etc..
This is typically used for management purposes, such as allowing access from a specific IP address or range of IP addresses, such as a management workstation or a specific network.
list(string) [] no
cost_centre Cost Centre for assigning resource costs, can be be anything number or string or combination (perhaps consider using an email address string "unknown" no
data_phi (Required) data_phi (true or false) These resources will contain and/or process Personally Health Information (PHI)
Note, this WILL NOT enable priivate endppoints, since is conntrolled via the var.always_enable_private_endpoints variable.
However, is does enable a lot of security services, that are typcially called "Defender" by Microsoft.
These services add a lot of values, such as vulnerability scanning, threat detection, security alerts, and more.
But, they come at a cost, so you need to be aware of that.
string "unknown" no
data_pii (Required) data_pii (true or false) These resources will contain and/or process Personally Identifiable Information (PII)
Note, this WILL NOT enable priivate endppoints, since is conntrolled via the var.always_enable_private_endpoints variable.
However, is does enable a lot of security services, that are typcially called "Defender" by Microsoft.
These services add a lot of values, such as vulnerability scanning, threat detection, security alerts, and more.
But, they come at a cost, so you need to be aware of that.
string "unknown" no
enable_telemetry This variable controls whether or not Microsoft telemetry is enabled for the AVM modules, that this module will ultimately call.
For more information see https://aka.ms/avm/telemetryinfo.
If it is set to false, then no telemetry will be collected.
The default is true.
bool false no
entra_group_unified_id The Entra ID Workforce group id (a UUID) that will be given full-ish permissions to the resource.
This is intended for humans, not applications, so that they can access and perform some management of the created resources.
One of the intention of this module, is to only allow very limit admin access, so they everything can be managed by the module. (ie by code)
Therefore you'll typically see that module wwill NOT grant high-level priviledge like Owner, Contributor to users.
string null no
landing_zone_name (Required) environment_name (freeform) must be one of ("core", "platform", "play", "dev", "test", "mvp", "uat", "sit", "preprod", "prod", "production", "live") so we can tell what each resource is being used for
This also coressponds to the Application Landing Zone that the resource/resources will be deployed into.
An application landing zone consist of a set of secure, compliant and container type resources, intended to support many applications, web sites and databases.
Some people in our opinion, over use landing zones and create too many of them, which makes it harder to manage.
We would suggest, you consider a landing_zone as what you might call an environment: DEV, TEST, UAT, PreProd etc...
The default is "test"
string "test" no
location_key The Azure location where the resource is to be deployed into. This is a key into the local.regions map (see locals.tf), which contains the applicable Azure region information.
The local.tf is used to map the location_key to the actual Azure region name, so that it can be used in the azurerm/azapi providers.
Unless you are using Australian regions, then you will need to customise the local.regions map to include your region amd alter the validation statements below, since they initially only support the Australia regions (australieast, australiasoutheast, australiacentral)
string "australiaeast" no
monitoring Set the resource tags for all the resources, so you know what sort of monitoring the resources will be eligible for.
You can even use these tags, to only enrolled resources in certain monitoring solutions and what time alerts should be generated (anytime, office hours only).
You'll typically need to be comply with ITIL and other opertional frameworks and potentially enteprise requirements.
like Azure Monitor, Azure Log Analytics, Azure Application Insights etc...
The supported values are"24-7", "8-5" or "not-monitored"
The default is "not-monitored" which means that the resources will not be enrolled in any monitoring solution.
string "not-monitored" no
owner_service The name (preferably email address) of the service owner for contacting in a disaster or seeking guiandance.
This is intended to assist in complying with frameworks like ITIL, COBIT, ISO27001, NIST etc...
He basically tell who is responsible for the resource, so that if when these is a problem, we know who to contact.
This will appear in the owner tag of the resource, so that it can be easily found.
string "unknown" no
owner_tech The name (preferably email address) of the technicalwner for contacting in a disaster or seeking guiandance.
This is intended to assist in complying with frameworks like ITIL, COBIT, ISO27001, NIST etc...
He basically tell who is responsible for the resource, so that if when these is a problem, we know who to contact.
This will appear in the owner tag of the resource, so that it can be easily found.
string "unknown" no
private_endpoints_always_deployed (Required) private_endpoints_always_deployed (true or false) If private endpoints should be deployed, where available. This requires the sku_name to be either "premium" or "isolated"
The use of Private Endpoints is typically a hardcore requirement for hosting real data. Any PEN test will almost always want Private Endpoints everywhere.
Looking at the Azure Pricing, you might think that Private Endpoints arn't that expensive. But you would be WROMG!
You are paying for the private endpoint basically for every second that it exists. It does not take long for these costs to add up.
Unless you are hosting real data (PII and PHI) then you should not use Private Endpoints, unless you want to waste money, and for really large organisation this might not be a concern.
We have as a separate configuration option for private endpoints, because sometimes people want to test private endpoints in DEV scenarios.
Technically private endpoint should never be needed, as any Azure endpoint is protected via Entra ID authentcation/authorisation, but this is a single point of failure. If Entra was misconfigured for example, your data would potneitally be exposed.
Hence, Prviate Endpoints are a good idea, by providing a 2nd layer of security (look up the swiss cheese approach to security. But they ultimately NOT CHEAP
The default is false And, it can only be set to true, unless the sku_name is set to either "premium" or "isolated".
This is because Private Endpoints are typically only available for the higher end skus
bool false no
private_endpoints_subnet_name (Required) private_endpoints_subnet_name (string) the name of the Azure VNet subnet, you want the Private Endpoint created in string null no
private_endpoints_vnet_name (Required) private_endpoints_subnet_name (string) the name of the Azure VNet subnet, you want the Private Endpoint created in string null no
project_name (Required) project_name (freeform) is used in special cases, where you want to deploy two or more applications, with the same name in the same landing zone.
This would be usualy, typically you would only deploy the application once per landing zone, once in UAT, once in DEV and once in SIT etc..
However, sometimes in DEV for example, you need to support multiple developer teams, working on the same code or different parts of the project and they historically clash.
The default is "default" and we recommend you pick a project_name and stick to the same one.
It should only be changed, when in the special case of deploying the same app in the same landing zone more than once.
string "default" no
size_name (Required) The size_name (only specific values) for the size of resources to be deployed.
This is an option for some resources, in addition to the SKU and the module makes decisions, which obviously just our opinion.
Feel free to adjust the module as you see fit, but we are pretty confident our resources are pretty reasonable for most circumstances.
The support vaalues are "small", "medium", "large" or "x-large"
Note: The larger the size the higher the cost! These cost differecnes can be very significant, so please be careful.
Currently the validation only support the use of the "small" SKU, please edit to use the others.
string "small" no
sku_name (Required) The sku_name (only specific values) of the resource to be created (free, basic, standard, premium or isolated)
The higher the sku, the more capabilities such as high availability and auto scalling are available.
These modules, determine which sku_name corresponds to which actual Azure SKU, that you would like to deploy.
Obviously, this is subject to opinion, so whilst we are configdent our choices work well in most environments, you are free to adjust this module to so that you can use the same sku_name across all modules.
The higher end skus (premium, isolated) are typically very expensive and totaly overkill for most applications.
Note: The free sku is only applicable to some resources and in some cases the resources created with the "free" sku may not actually be free, but should be very minimal cost.
The validation rules, only permit the use of the "free" and "basic" sku to prevent unintended consequences (ie a huge bill at the end of the month)
The module will happily create these higher SKU resource, so simply edit the validation rule (below) to leverage them.
string "free" no
user_assigned_identity_graph_name The Entra ID / Azure Managed Identity that will give access to this resource.
Note, that Managed Identities (as they known in Azure portal) can be created in either within Entra ID (with azuread_application) or within Azure (with azurerm_user_assigned_identity)
Unless you need a secret for things, like external authentication, then is generally better to use the Azure variety.
This module only support user-assigned managed identities, not system-assigned managed identities.
string null no

Outputs

Name Description
application_name (Required) application name (freeform) so we can tell what each resource is being used for
This also coressponds to the Application Landing Zone that the resource/resources will be deployed into.
This is ignored, when creatting an Application Landing Zone, as the name is derived from the environment_name.
cost_centre Cost Centre for assigning resource costs, can be be anything number or string or combination (perhaps consider using an email address
data_phi (Required) These resources will contain and/or process Personally Health Information (PHI)
data_pii (Required) These resources will contain and/or process Personally Identifiable Information (PII)
landing_zone_name (Required) environment_name must be one of ("core", "platform", "play", "dev", "test", "uat", "sit", "preprod", "prod", "live") so we can tell what each resource is being used for
This also coressponds to the Application Landing Zone that the resource/resources will be deployed into.
location_key The Azure location where the resource is to be deployed into. This is a key into the local.regions map, which contains the applicable Azure region information.
monitoring Set the tags, that defines what sort of monitoring the resources will be eligible for
owner_service The name (preferably email address) of the resource owner for contacting in a disaster or seeking guiandance
owner_tech The name (preferably email address) of the resource owner for contacting in a disaster or seeking guiandance
private_endpoints_always_deployed (Required) If private endpoints should be deployed, where available. Requires the cost to be set to High
project_name (Required) project name used to distinguish that exist to enable the rare case where you want the same application deployed
multiple times (as a different) projects within the same application landing zone.
region_lake_containers n/a
size_name (Required) The size of the resultant resource/resources (small, medium, large or x-large).
Note: The larger the size the higher the cost!
sku_name (Required) The sku_name of the resource to be created (for example, free, basic, standard, premium or isolated)
The higher the sku, the more capabilities such as high availability and auto scalling are available.
subscription_display_name Azure Subscription Display Name
subscription_id Azure Subscription ID
tenant_id Azure Tenant ID

Modules

Name Source Version
naming-application Azure/naming/azurerm ~>0.0, < 1.0

Additional References

Click to expand

Generated with terraform-docs

Releases

No releases published

Packages

No packages published

Contributors 2

  •  
  •