skip to Main Content

I am making a deploy using BICEP and it has been working fine. Though now I need to make use of deployment slots as deployment disturbs our users.

I read the documentation and got it working, at least what I thought. I make a deploy to the staging slot, making a swap and everything works. First time I expect the staging slot to be empty after the deploy but not as I deploy another time. As I do a swap I expect the old production code to be the staging code but it is not. Staging is empty, which is bad as I can’t switch back in case something went wrong with the new code.

After lots of reruns of my deploy I have noticed that the functionapp is emptied of its content as the BICEP is run, not what I expect from what I have read should happen with my configuration.

Is there a misconfiguration somewhere I just can’t see? Something goes wrong BEFORE deploying the content to the Azure Function.

My BICEP (or part of it)

resource sites_azfun_xxxxxxxxxxxxxxx_web 'Microsoft.Web/sites@2022-09-01' = {
  name: sites_azfun_xxxxxxxxxxxxxxx_name
  location: location
  tags: {
    DebitCode: vDebitCode
  }
  kind: 'functionapp'
  identity: {
    type: 'SystemAssigned'
  }
  properties: {
    clientAffinityEnabled: false
    clientCertEnabled: false
    clientCertMode: 'Optional'
    containerSize: 1536
    dailyMemoryTimeQuota: 0
    enabled: true
    hostNamesDisabled: false
    hostNameSslStates: [
      {
        name: '${sites_azfun_xxxxxxxxxxxxxxx_name}.azurewebsites.net'
        sslState: 'Disabled'
        hostType: 'Standard'
      }
      {
        name: '${sites_azfun_xxxxxxxxxxxxxxx_name}.scm.azurewebsites.net'
        sslState: 'Disabled'
        hostType: 'Repository'
      }
    ]
    httpsOnly: true
    hyperV: false
    isXenon: false
    redundancyMode: 'None'
    reserved: false
    scmSiteAlsoStopped: false
    serverFarmId: serverfarms_yyyyyyyyyPlan_name_resource.id
  }
}

resource sites_azfun_xxxxxxxxxxxxxxx_web_config 'Microsoft.Web/sites/config@2022-09-01' = {
  parent: sites_azfun_xxxxxxxxxxxxxxx_web
  name: 'web'
  properties: {
    numberOfWorkers: 1
    defaultDocuments: [
      'Default.htm'
      'Default.html'
      'Default.asp'
      'index.htm'
      'index.html'
      'iisstart.htm'
      'default.aspx'
      'index.php'
    ]
    netFrameworkVersion: 'v7.0'
    phpVersion: '5.6'
    requestTracingEnabled: false
    remoteDebuggingEnabled: false
    httpLoggingEnabled: false
    logsDirectorySizeLimit: 35
    detailedErrorLoggingEnabled: false
    publishingUsername: '$${sites_azfun_xxxxxxxxxxxxxxx_name}'
    scmType: 'None'
    use32BitWorkerProcess: true
    webSocketsEnabled: false
    alwaysOn: bool(always_on)
    managedPipelineMode: 'Integrated'
    virtualApplications: [
      {
        virtualPath: '/'
        physicalPath: 'site\wwwroot'
        preloadEnabled: false
      }
    ]
    loadBalancing: 'LeastRequests'
    experiments: {
      rampUpRules: []
    }
    autoHealEnabled: true
    cors: {
      allowedOrigins: [
        'https://functions.azure.com'
        'https://functions-staging.azure.com'
        'https://functions-next.azure.com'
      ]
      supportCredentials: false
    }
    localMySqlEnabled: false
    ipSecurityRestrictions: [
      {
        ipAddress: '***'
        action: '***'
        priority: 1
        name: '***'
        description: '***'
      }
    ]
    scmIpSecurityRestrictions: [
      {
        ipAddress: '***'
        action: '***'
        priority: 1
        name: '***'
        description: '***'
      }
    ]
    scmIpSecurityRestrictionsUseMain: false
    http20Enabled: false
    minTlsVersion: '1.2'
    ftpsState: 'Disabled'
  }
}

resource sites_azfun_xxxxxxxxxxxxxxx_web_azurewebsites_net 'Microsoft.Web/sites/hostNameBindings@2022-09-01' = {
  parent: sites_azfun_xxxxxxxxxxxxxxx_web
  name: '${sites_azfun_xxxxxxxxxxxxxxx_name}.azurewebsites.net'
  properties: {
    siteName: sites_azfun_xxxxxxxxxxxxxxx_name
    hostNameType: 'Verified'
  }
}

resource sites_azfun_xxxxxxxxxxxxxxx_staging 'Microsoft.Web/sites/slots@2022-09-01' = {
  name: stagingslot_azfun_xxxxxxxxxxxxxxx_name
  parent: sites_azfun_xxxxxxxxxxxxxxx_web
  location: location
  kind: 'functionapp'
  properties: {
    serverFarmId: serverfarms_yyyyyyyyyyPlan_name_resource.id
  }
}

resource sites_azfun_xxxxxxxxxxxxxxx_staging_scm 'Microsoft.Web/sites/slots/basicPublishingCredentialsPolicies@2022-09-01' = {
  parent: sites_azfun_xxxxxxxxxxxxxxx_staging
  name: 'scm'
  properties: {
    allow: true
  }
}

resource sites_azfun_xxxxxxxxxxxxxxx_staging_config 'Microsoft.Web/sites/slots/config@2022-09-01' = {
  parent: sites_azfun_xxxxxxxxxxxxxxx_staging
  name: 'web'
  properties: {
    numberOfWorkers: 1
    defaultDocuments: [
      'Default.htm'
      'Default.html'
      'Default.asp'
      'index.htm'
      'index.html'
      'iisstart.htm'
      'default.aspx'
      'index.php'
    ]
    netFrameworkVersion: 'v7.0'
    phpVersion: '5.6'
    requestTracingEnabled: false
    remoteDebuggingEnabled: false
    httpLoggingEnabled: false
    logsDirectorySizeLimit: 35
    detailedErrorLoggingEnabled: false
    publishingUsername: '$${sites_azfun_xxxxxxxxxxxxxxx_name}__staging'
    scmType: 'None'
    use32BitWorkerProcess: true
    webSocketsEnabled: false
    alwaysOn: bool(always_on)
    managedPipelineMode: 'Integrated'
    virtualApplications: [
      {
        virtualPath: '/'
        physicalPath: 'site\wwwroot'
        preloadEnabled: false
      }
    ]
    loadBalancing: 'LeastRequests'
    experiments: {
      rampUpRules: []
    }
    autoHealEnabled: true
    cors: {
      allowedOrigins: [
        'https://functions.azure.com'
        'https://functions-staging.azure.com'
        'https://functions-next.azure.com'
      ]
      supportCredentials: false
    }
    localMySqlEnabled: false
    ipSecurityRestrictions: [
      {
        ipAddress: '***'
        action: '***'
        priority: 1
        name: '***'
        description: '***'
      }
    ]
    scmIpSecurityRestrictions: [
      {
        ipAddress: '***'
        action: '***'
        priority: 1
        name: '***'
        description: '***'
      }
    ]
    scmIpSecurityRestrictionsUseMain: false
    http20Enabled: false
    minTlsVersion: '1.2'
    ftpsState: 'Disabled'
  }
}

resource sites_azfun_xxxxxxxxxxxxxxx_staging_azurewebsites_net 'Microsoft.Web/sites/slots/hostNameBindings@2022-09-01' = {
  parent: sites_azfun_xxxxxxxxxxxxxxx_staging
  name: '${sites_azfun_xxxxxxxxxxxxxxx_name}-staging.azurewebsites.net'
  properties: {
    siteName: 'azfun-xxxxxxxxxxxxxxx-lab(staging)'
    hostNameType: 'Verified'
  }
}

My azure pipeline, in yml (or part of it)

stages:
- stage: ${{ parameters.environmentName }}
  dependsOn: 
    ${{ parameters.dependsOn }}
  variables:
    - ${{ parameters.varGroups }}
  jobs:
  - deployment: azure_resources
    displayName: "Creating or updating resources"
    environment: ${{ parameters.azureDevopsEnvironmentName }}
    variables: 
      - name: templateFile
        value: 'main.bicep'
      - name: parametersFile
        value: 'main.parameters.json'
      - ${{ parameters.varGroups }}
    condition: succeeded()
    pool:
      vmImage: windows-latest
    strategy:
      runOnce:
        deploy:
          steps:
            - task: replacetokens@5
              name: tokens_in_parameterfile
              displayName: 'Replacing tokens in files'
              inputs:
                targetFiles: |
                  ../BuildPipeline/BICEP/$(parametersFile)
                encoding: 'auto'
                tokenPattern: 'octopus'
                writeBOM: true
                actionOnMissing: 'warn'
                keepToken: false
                actionOnNoFiles: 'continue'
                enableTransforms: false
                enableRecursion: false
                useLegacyPattern: false
                enableTelemetry: false
            - task: AzureResourceManagerTemplateDeployment@3
              name: 'deploy'
              displayName: 'Deploy resources to resource group'
              inputs:
                deploymentName: 'deploy'
                deploymentScope: 'Resource Group'
                azureResourceManagerConnection: $(azuredevops_serviceendpoint_azurerm)
                action: 'Create Or Update Resource Group'
                resourceGroupName: ${{ parameters.resourceGroupName }}-${{ lower(parameters.environmentName) }}
                location: ${{ parameters.location }}
                templateLocation: 'Linked artifact'
                csmFile: '../BuildPipeline/BICEP/$(templateFile)'
                csmParametersFile: '../BuildPipeline/BICEP/$(parametersFile)'
                deploymentMode: 'Incremental'

            - ${{ if eq(parameters.deploy_xxxxxxxxxxxxxxx, true) }}:
              - task:  AzureFunctionApp@2
                name: 'xxxxxxxxxxxxxxx_content'
                displayName: 'Deploy content for xxxxxxxxxxxxxxx'
                inputs:
                  ${{ if eq(lower(parameters.environmentName), 'xxxx') }}:
                    appName: azfun-xxxxxxxxxxxxxxx
                  ${{ else }}:
                    appName: azfun-xxxxxxxxxxxxxxx-${{ lower(parameters.environmentName) }}
                  connectedServiceNameARM: '$(azuredevops_serviceendpoint_azurerm)'
                  appType: 'functionApp'
                  package: '../BuildPipeline/xxxxxxxxxxxxxxx/**/*.zip'
                  deployToSlotOrASE: true
                  resourceGroupName: ${{ parameters.resourceGroupName }}-${{ lower(parameters.environmentName) }}
                  slotName: 'staging'
                  deploymentMethod: 'auto'

              - task: AzureAppServiceManage@0
                displayName: 'Swap content for xxxxxxxxxxxxxxx'
                inputs:
                  azureSubscription: '$(azuredevops_serviceendpoint_azurerm)'
                  ${{ if eq(lower(parameters.environmentName), 'xxxx') }}:
                    WebAppName: azfun-xxxxxxxxxxxxxxx
                  ${{ else }}:
                    WebAppName: azfun-xxxxxxxxxxxxxxx-${{ lower(parameters.environmentName) }}
                  ResourceGroupName: ${{ parameters.resourceGroupName }}-${{ lower(parameters.environmentName) }}
                  SourceSlot: staging
                  SwapWithProduction: true

2

Answers


  1. Chosen as BEST ANSWER

    As Kevin Lu pointed out, I had to add the appsettings WEBSITE_RUN_FROM_PACKAGE: '1'.


  2. We can refer to this doc: Run your functions from a package file in Azure

    To enable your function app to run from a package, add a WEBSITE_RUN_FROM_PACKAGE setting to your function app settings.

    1 Indicates that the function app runs from a local package file deployed in the d:homedataSitePackages (Windows) or /home/data/SitePackages (Linux) folder of your function app.

    When you deploy function app code using AzureFunctionApp@2, this app setting will automatically add into function app.

    When redeploying your bicep file, this setting is removed and the function app host does not know where to find the code.

    In this case, the functionapp could show as empty of its content

    We can add the appsetting: WEBSITE_RUN_FROM_PACKAGE: ‘1’ to the bicep file to solve the issue.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search