Skip to content

Commit 5a4bdca

Browse files
authored
Merge pull request #90 from PerfectThymeTech/marvinbuss/upgrade_infra_container
Update Function IaC for Containers
2 parents b3016f9 + 6cb1584 commit 5a4bdca

File tree

6 files changed

+162
-63
lines changed

6 files changed

+162
-63
lines changed

.github/workflows/_functionAppDeployTemplate.yml

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,21 @@ on:
2121
required: true
2222
type: string
2323
description: "Specifies the name of the Azure Function."
24-
secrets:
25-
TENANT_ID:
24+
tenant_id:
2625
required: true
26+
type: string
2727
description: "Specifies the tenant id of the deployment."
28+
subscription_id:
29+
required: true
30+
type: string
31+
description: "Specifies the subscription id of the deployment."
32+
secrets:
2833
CLIENT_ID:
2934
required: true
3035
description: "Specifies the client id."
3136
CLIENT_SECRET:
3237
required: true
3338
description: "Specifies the client secret."
34-
SUBSCRIPTION_ID:
35-
required: true
36-
description: "Specifies the client id."
3739

3840
jobs:
3941
deployment:
@@ -75,7 +77,7 @@ jobs:
7577
id: azure_login
7678
uses: azure/login@v1
7779
with:
78-
creds: '{"clientId":"${{ secrets.CLIENT_ID }}","clientSecret":"${{ secrets.CLIENT_SECRET }}","subscriptionId":"${{ secrets.SUBSCRIPTION_ID }}","tenantId":"${{ secrets.TENANT_ID }}"}'
80+
creds: '{"clientId":"${{ secrets.CLIENT_ID }}","clientSecret":"${{ secrets.CLIENT_SECRET }}","subscriptionId":"${{ inputs.subscription_id }}","tenantId":"${{ inputs.tenant_id }}"}'
7981

8082
# Deploy Function
8183
- name: Deploy Function

.github/workflows/functionApp.yml

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,18 @@ jobs:
3636
USER_NAME: ${{ github.actor }}
3737
PASSWORD: ${{ secrets.GITHUB_TOKEN }}
3838

39-
function_deploy:
40-
uses: ./.github/workflows/_functionAppDeployTemplate.yml
41-
name: "Function App Deploy"
42-
needs: [function_test]
43-
if: github.event_name == 'push' || github.event_name == 'release'
44-
with:
45-
environment: "dev"
46-
python_version: "3.10"
47-
function_directory: "./code/function"
48-
function_name: "myfunc-dev-fctn001"
49-
secrets:
50-
TENANT_ID: ${{ secrets.TENANT_ID }}
51-
CLIENT_ID: ${{ secrets.CLIENT_ID }}
52-
CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}
53-
SUBSCRIPTION_ID: ${{ secrets.SUBSCRIPTION_ID }}
39+
# function_deploy:
40+
# uses: ./.github/workflows/_functionAppDeployTemplate.yml
41+
# name: "Function App Deploy"
42+
# needs: [function_test]
43+
# if: github.event_name == 'push' || github.event_name == 'release'
44+
# with:
45+
# environment: "dev"
46+
# python_version: "3.10"
47+
# function_directory: "./code/function"
48+
# function_name: "myfunc-dev-fctn001"
49+
# tenant_id: "3556be79-2979-4b19-a1af-4dd4e6d9ed7e"
50+
# subscription_id: "8f171ff9-2b5b-4f0f-aed5-7fa360a1d094"
51+
# secrets:
52+
# CLIENT_ID: ${{ secrets.CLIENT_ID }}
53+
# CLIENT_SECRET: ${{ secrets.CLIENT_SECRET }}

code/infra/function.tf

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ resource "azurerm_service_plan" "service_plan" {
77
# maximum_elastic_worker_count = 20
88
os_type = "Linux"
99
per_site_scaling_enabled = false
10-
sku_name = "P1v3"
10+
sku_name = var.function_sku
1111
worker_count = 1 # Update to '3' for production
1212
zone_balancing_enabled = false # Update to 'true' for production
1313
}
@@ -50,7 +50,7 @@ resource "azapi_resource" "function" {
5050
}
5151

5252
body = jsonencode({
53-
kind = "functionapp,linux"
53+
kind = "functionapp,linux,container"
5454
properties = {
5555
clientAffinityEnabled = false
5656
clientCertEnabled = false
@@ -64,14 +64,28 @@ resource "azapi_resource" "function" {
6464
publicNetworkAccess = "Disabled"
6565
redundancyMode = "None"
6666
reserved = true
67-
scmSiteAlsoStopped = false
67+
scmSiteAlsoStopped = true
6868
serverFarmId = azurerm_service_plan.service_plan.id
6969
storageAccountRequired = false
7070
vnetContentShareEnabled = true
71+
vnetImagePullEnabled = true
7172
virtualNetworkSubnetId = azapi_resource.subnet_function.id
7273
vnetRouteAllEnabled = true
7374
siteConfig = {
74-
autoHealEnabled = false
75+
autoHealEnabled = true
76+
autoHealRules = {
77+
actions = {
78+
actionType = "LogEvent"
79+
}
80+
triggers = {
81+
statusCodes = [
82+
"429",
83+
"504",
84+
"507",
85+
"508"
86+
]
87+
}
88+
}
7589
acrUseManagedIdentityCreds = false
7690
alwaysOn = true
7791
appSettings = [
@@ -80,8 +94,12 @@ resource "azapi_resource" "function" {
8094
value = azurerm_application_insights.application_insights.connection_string
8195
},
8296
{
83-
name = "APPINSIGHTS_INSTRUMENTATIONKEY"
84-
value = azurerm_application_insights.application_insights.instrumentation_key
97+
name = "AZURE_FUNCTIONS_ENVIRONMENT"
98+
value = "Production"
99+
},
100+
{
101+
name = "FUNCTIONS_WORKER_PROCESS_COUNT"
102+
value = "${var.function_sku_cpus}"
85103
},
86104
{
87105
name = "FUNCTIONS_EXTENSION_VERSION"
@@ -91,6 +109,22 @@ resource "azapi_resource" "function" {
91109
name = "FUNCTIONS_WORKER_RUNTIME"
92110
value = "python"
93111
},
112+
{
113+
name = "FUNCTIONS_WORKER_SHARED_MEMORY_DATA_TRANSFER_ENABLED"
114+
value = "1"
115+
},
116+
{
117+
name = "DOCKER_SHM_SIZE"
118+
value = "268435456"
119+
},
120+
{
121+
name = "PYTHON_THREADPOOL_THREAD_COUNT"
122+
value = "None"
123+
},
124+
{
125+
name = "PYTHON_ENABLE_DEBUG_LOGGING"
126+
value = "0"
127+
},
94128
{
95129
name = "WEBSITE_CONTENTOVERVNET"
96130
value = "1"
@@ -115,6 +149,14 @@ resource "azapi_resource" "function" {
115149
name = "AzureWebJobsStorage__accountName"
116150
value = azurerm_storage_account.storage.name
117151
},
152+
{
153+
name = "AzureWebJobsSecretStorageType"
154+
value = "keyvault"
155+
},
156+
{
157+
name = "AzureWebJobsSecretStorageKeyVaultUri"
158+
value = azurerm_key_vault.key_vault.vault_uri
159+
},
118160
{
119161
name = "MY_SECRET_CONFIG"
120162
value = "@Microsoft.KeyVault(SecretUri=${azurerm_key_vault_secret.key_vault_secret_sample.id})"
@@ -126,15 +168,18 @@ resource "azapi_resource" "function" {
126168
functionsRuntimeScaleMonitoringEnabled = false
127169
ftpsState = "Disabled"
128170
healthCheckPath = var.function_health_path
129-
http20Enabled = false
171+
http20Enabled = true
130172
ipSecurityRestrictionsDefaultAction = "Deny"
131-
linuxFxVersion = "Python|${var.function_python_version}"
173+
linuxFxVersion = "DOCKER|${var.function_container_image}"
132174
localMySqlEnabled = false
133175
loadBalancing = "LeastRequests"
134176
minTlsVersion = "1.2"
177+
minTlsCipherSuite = "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
135178
minimumElasticInstanceCount = 0
136179
numberOfWorkers = 1
137180
preWarmedInstanceCount = 0
181+
remoteDebuggingEnabled = false
182+
requestTracingEnabled = true
138183
scmMinTlsVersion = "1.2"
139184
scmIpSecurityRestrictionsUseMain = false
140185
scmIpSecurityRestrictionsDefaultAction = "Deny"
@@ -144,6 +189,18 @@ resource "azapi_resource" "function" {
144189
}
145190
}
146191
})
192+
193+
schema_validation_enabled = false
194+
# ignore_body_changes = [
195+
# "properties.siteConfig.appSettings"
196+
# ]
197+
depends_on = [
198+
azurerm_private_endpoint.key_vault_private_endpoint,
199+
azurerm_private_endpoint.storage_private_endpoint_blob,
200+
azurerm_private_endpoint.storage_private_endpoint_file,
201+
azurerm_private_endpoint.storage_private_endpoint_queue,
202+
azurerm_private_endpoint.storage_private_endpoint_table,
203+
]
147204
}
148205

149206
data "azurerm_monitor_diagnostic_categories" "diagnostic_categories_function" {

code/infra/roleassignments.tf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ resource "azurerm_role_assignment" "function_role_assignment_storage" {
1212

1313
resource "azurerm_role_assignment" "function_role_assignment_key_vault" {
1414
scope = azurerm_key_vault.key_vault.id
15-
role_definition_name = "Key Vault Secrets User"
15+
role_definition_name = "Key Vault Secrets Officer"
1616
principal_id = azapi_resource.function.identity[0].principal_id
1717
}
1818

code/infra/variables.tf

Lines changed: 55 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
# General variables
12
variable "location" {
23
description = "Specifies the location for all Azure resources."
34
type = string
@@ -32,44 +33,42 @@ variable "tags" {
3233
default = {}
3334
}
3435

35-
variable "vnet_id" {
36-
description = "Specifies the resource ID of the Vnet used for the Azure Function."
36+
# Function variables
37+
variable "function_container_image" {
38+
description = "Specifies the container image reference of the Azure Function."
3739
type = string
3840
sensitive = false
3941
validation {
40-
condition = length(split("/", var.vnet_id)) == 9
41-
error_message = "Please specify a valid resource ID."
42+
condition = alltrue([
43+
length(var.function_container_image) > 2,
44+
length(split("/", var.function_container_image)) >= 2,
45+
length(split(":", var.function_container_image)) == 2,
46+
])
47+
error_message = "Please specify a valid container image reference."
4248
}
4349
}
4450

45-
variable "nsg_id" {
46-
description = "Specifies the resource ID of the default network security group for the Azure Function."
51+
variable "function_sku" {
52+
description = "Specifies the sku name used in the function app service plan."
4753
type = string
4854
sensitive = false
55+
nullable = false
56+
default = "P0v3"
4957
validation {
50-
condition = length(split("/", var.nsg_id)) == 9
51-
error_message = "Please specify a valid resource ID."
58+
condition = contains(["F1", "B1", "B2", "B3", "S1", "S2", "S3", "P0v3", "P1v3", "P2v3", "P3v3", "P1mv3", "P2mv3", "P3mv3", "P4mv3", "P5mv3"], var.function_sku)
59+
error_message = "Please specify a valid sku name."
5260
}
5361
}
5462

55-
variable "route_table_id" {
56-
description = "Specifies the resource ID of the default route table for the Azure Function."
57-
type = string
63+
variable "function_sku_cpus" {
64+
description = "Specifies the number of CPUs available for the function sku used in the app service plan."
65+
type = number
5866
sensitive = false
67+
nullable = false
68+
default = 1
5969
validation {
60-
condition = length(split("/", var.route_table_id)) == 9
61-
error_message = "Please specify a valid resource ID."
62-
}
63-
}
64-
65-
variable "function_python_version" {
66-
description = "Specifies the python version of the Azure Function."
67-
type = string
68-
sensitive = false
69-
default = "3.10"
70-
validation {
71-
condition = contains(["3.9", "3.10"], var.function_python_version)
72-
error_message = "Please specify a valid Python version."
70+
condition = var.function_sku_cpus > 0
71+
error_message = "Please specify a valid number of cpus."
7372
}
7473
}
7574

@@ -93,6 +92,38 @@ variable "my_secret" {
9392
}
9493
}
9594

95+
# Network variables
96+
variable "vnet_id" {
97+
description = "Specifies the resource ID of the Vnet used for the Azure Function."
98+
type = string
99+
sensitive = false
100+
validation {
101+
condition = length(split("/", var.vnet_id)) == 9
102+
error_message = "Please specify a valid resource ID."
103+
}
104+
}
105+
106+
variable "nsg_id" {
107+
description = "Specifies the resource ID of the default network security group for the Azure Function."
108+
type = string
109+
sensitive = false
110+
validation {
111+
condition = length(split("/", var.nsg_id)) == 9
112+
error_message = "Please specify a valid resource ID."
113+
}
114+
}
115+
116+
variable "route_table_id" {
117+
description = "Specifies the resource ID of the default route table for the Azure Function."
118+
type = string
119+
sensitive = false
120+
validation {
121+
condition = length(split("/", var.route_table_id)) == 9
122+
error_message = "Please specify a valid resource ID."
123+
}
124+
}
125+
126+
# DNS variables
96127
variable "private_dns_zone_id_blob" {
97128
description = "Specifies the resource ID of the private DNS zone for Azure Storage blob endpoints. Not required if DNS A-records get created via Azue Policy."
98129
type = string

config/PerfectThymeTech/vars.tfvars

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
1-
location = "northeurope"
2-
environment = "dev"
3-
prefix = "myfunc"
4-
tags = {}
5-
function_python_version = "3.10"
6-
function_health_path = "/v1/health/heartbeat"
7-
vnet_id = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-function-network-rg/providers/Microsoft.Network/virtualNetworks/mycrp-prd-function-vnet001"
8-
nsg_id = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-function-network-rg/providers/Microsoft.Network/networkSecurityGroups/mycrp-prd-function-nsg001"
9-
route_table_id = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-function-network-rg/providers/Microsoft.Network/routeTables/mycrp-prd-function-rt001"
1+
# General variables
2+
location = "northeurope"
3+
environment = "dev"
4+
prefix = "myfunc"
5+
tags = {}
6+
7+
# Function variables
8+
function_container_image = "ghcr.io/perfectthymetech/azurefunctionpython:main"
9+
function_sku = "P0v3"
10+
function_sku_cpus = 1
11+
function_health_path = "/v1/health/heartbeat"
12+
13+
# Network variables
14+
vnet_id = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-function-network-rg/providers/Microsoft.Network/virtualNetworks/mycrp-prd-function-vnet001"
15+
nsg_id = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-function-network-rg/providers/Microsoft.Network/networkSecurityGroups/mycrp-prd-function-nsg001"
16+
route_table_id = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-function-network-rg/providers/Microsoft.Network/routeTables/mycrp-prd-function-rt001"
17+
18+
# DNS variables
1019
private_dns_zone_id_blob = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-global-dns/providers/Microsoft.Network/privateDnsZones/privatelink.blob.core.windows.net"
1120
private_dns_zone_id_queue = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-global-dns/providers/Microsoft.Network/privateDnsZones/privatelink.queue.core.windows.net"
1221
private_dns_zone_id_table = "/subscriptions/8f171ff9-2b5b-4f0f-aed5-7fa360a1d094/resourceGroups/mycrp-prd-global-dns/providers/Microsoft.Network/privateDnsZones/privatelink.table.core.windows.net"

0 commit comments

Comments
 (0)