Set vm.max_map_count for SonarQube Elastisearch in Azure Container Apps

103 Views Asked by At

I was trying to automate deployment of SonarQube enterprise edition 10.1 with connection to external database like Azure PostgreSQL flexible servers. While deployment container app is crashing, with error max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]

As Azure Container Apps is serverless and we cannot access OS/Kernel parameters, how do I change my vm.max_map_count

I am using bicep for its deployment.

This is my iac module

//Bicep template for deploying Container App using bicep.

@description('Provide Naming Convention parameter for the Container app')
param namingConventionProperties object = {}

@description('Provide application/resource short name for the Container app.')
param shortName string = ''

@description('Provide name for the Container app')
param resourceName string = ''

@description('Resource tags')
param tags object = {}

//TODO: JIRA PLT-28423 : We will add the support for setting userassigned Service Identity in future
@description('Type of Managed Service Identity')
@allowed([
  // 'None'
  'SystemAssigned'
  // 'SystemAssigned, UserAssgined'
  // 'UserAssgined'    //==> array of user assigned identities.
])
param identityType string = 'SystemAssigned'

@description('Container app location; default is Resource Group location')
param location string = resourceGroup().location

@description('Conatiner app enviorment name')
param containerAppEnvironmentName string

@description('Set image for your container app to use')
param containerImage string

@description('The Container app name')
param containerAppName string

@description('Set whether you want your ingress visible externally, or internally within a VNET')
param useExternalIngress bool = false

@description('The port your container listens to for incoming requests. Your application ingress endpoint is always exposed on port 443')
param containerPort int

@description('The resource CPU to Container app. Required CPU in cores, e.g. 0.5 To specify a decimal value, use the json() function.')
param containerResouceCpu string

@description('The resource memory to Container app')
param containerResouceMemory string 

@description('Transport type for Ingress')
@allowed([
  'auto'
  'http'
  'http2'
])
param transportMethod string = 'auto'

@description('Container environment variables.')
param environmentVariables array = []

@description('The number of minimum replicas needed')
param minReplicas int

@description('The number of maximum replicas needed')
param maxReplicas int

@description('ContainerApp resource specific properties')
param workloadProfileName string

var typeOfResource = 'conapp'

var finalResourceName = (resourceName == '') ? ((shortName == '') ? '${namingConventionProperties.subscriptionName}-${namingConventionProperties.projectCode}-${typeOfResource}-${namingConventionProperties.environment}' : '${namingConventionProperties.subscriptionName}-${namingConventionProperties.projectCode}-${typeOfResource}-${shortName}-${namingConventionProperties.environment}' ) : resourceName


resource containerapp 'Microsoft.App/containerapps@2022-11-01-preview' = {
  name: finalResourceName
  location: location
  tags: tags
  identity: {
    type: identityType
  }
  properties: {
    managedEnvironmentId: containerAppEnvironmentName
    configuration: {
      secrets: [
      ]    
      registries: [
      ]
      ingress: {
        external: useExternalIngress
        targetPort: containerPort
        transport: transportMethod
      }
    }
    template: {
      containers: [
        {
          image: containerImage
          name: containerAppName
          env: environmentVariables
          resources: {
            cpu: json(containerResouceCpu)
            memory: containerResouceMemory
          }
        }
      ]
      scale: {
        maxReplicas: maxReplicas
        minReplicas: minReplicas
      }
    }
    workloadProfileName: workloadProfileName
  }
}

This is my module call

/* 
This Bicep template is used to deploy SonarQube on Azure Containers App.
The resources that are being deployed are:
  - Azure Container App
  - PostgreSQL Flexible Servers
  - PostgreSQL Database
*/
var namingConventionProperties = {
  subscriptionName: ''
  projectCode: ''
  environment: ''
}

param tags object = {
  CreatedVia: ''
  Purpose: ''
}

param location string = resourceGroup().location

var administratorLogin = ''

param sharedVnetName string = ''

param sharedResourceGroupName string = ''

param privEndpointSubnetName string = ''

param privDnsSharedResourceGroup string = ''

param privateDnsZoneName string = ''

param privDnsSubscriptionId string = ''

param charset string = ''

param collation string = ''

@secure()
param administratorLoginPassword string

param dbName string = ''

var containerAppEnvironmentName = ''

var shortName = ''

var postgresqlServerVersion = ''

var skuName = ''

var skuTier = ''

var skuSizeGB = 

var availabilityZone = ''

var identityType = ''

var containerImage = ''

var useExternalIngress = 

var containerPort = 

var containerResouceCpu = ''

var containerResouceMemory = ''

var containerAppName = ''

var transportMethod = ''

var maxReplicas = 

var minReplicas = 

var workloadProfileName = ''


resource containerAppEnvironment 'Microsoft.App/managedEnvironments@2022-11-01-preview' existing = {
  name: containerAppEnvironmentName
}


module postgresql '../../../../../../iac-modules/Infra-As-Code/Modules/Bicep/DBforPostgreSQL/flexibleServers.bicep' = {
  name: 'postgresql-flexibleServers'
  params: {
    namingConventionProperties: namingConventionProperties
    shortName: shortName
    location: location
    tags: tags
    administratorLogin: administratorLogin
    administratorLoginPassword: administratorLoginPassword
    postgresqlServerVersion: postgresqlServerVersion
    skuName: skuName
    skuTier: skuTier
    skuSizeGB: skuSizeGB
    availabilityZone: availabilityZone
    psqlMetadata : {
      sharedResourceGroup: sharedResourceGroupName
      privEndpointSubnetName: privEndpointSubnetName
      sharedVnetName: sharedVnetName
      pvtDnsZone: {
        resourceGroupName: privDnsSharedResourceGroup
        subscriptionId: privDnsSubscriptionId
        privateDnsZoneName: privateDnsZoneName
      }
    }
  }
}

module database '../../../../../../iac-modules/Infra-As-Code/Modules/Bicep/DBforPostgreSQL/Databases/database.bicep' = {
  name: 'postgresqlDb'
  params: {
    dbName : dbName
    postgresqlName: postgresql.outputs.postgresqlServerName
    charset: charset
    collation: collation
  }
  dependsOn: [
    postgresql
  ]
}

module ContainerApp '../../../../../../iac-modules/Infra-As-Code/Modules/Bicep/ContainerApps/containerApps.bicep' = {
  name: 'ContainerAppDeploy'
  params: {
    namingConventionProperties: namingConventionProperties
    location: location
    tags: tags
    shortName: shortName
    identityType: identityType
    containerAppEnvironmentName: containerAppEnvironment.id
    containerImage: containerImage
    useExternalIngress: useExternalIngress
    containerPort: containerPort
    containerResouceCpu: containerResouceCpu
    containerResouceMemory: containerResouceMemory
    containerAppName: containerAppName
    transportMethod: transportMethod
    environmentVariables: [
      {
        name: 'SONAR_JDBC_USERNAME'
        value: administratorLogin
      }
      {
        name: 'SONAR_JDBC_PASSWORD'
        value: administratorLoginPassword
      }
      {
        name: 'SONAR_JDBC_URL'
        value: 'jdbc:postgresql://${postgresql.outputs.postgresqlURL}:5432/sonarqube?user=${administratorLogin}&password=${administratorLoginPassword}&sslmode=require'
        // value: 'jdbc:postgresql://<PSQLEnpointConnectionURL>:5432/<DBName>?user=<UserName>&password=<UserPassword>&sslmode=require'
      }
      // {
      //   name: 'SONAR_SEARCH_JAVAADDITIONALOPTS'
      //   value: '-Dnode.store.allow_mmap=false'
      // }
    ]
      maxReplicas: maxReplicas
      minReplicas: minReplicas
      workloadProfileName: workloadProfileName
  }
  dependsOn: [
    database
  ]
}

I tried many options but was unable to figure it out, and the virtual memory space should be increased of host machine and not the container. Another approach I found a lot of people recommended is SONAR_SEARCH_JAVAADDITIONALOPTS = -Dnode.store.allow_mmap=false which ideally should not be done, as it is not suggested for production environment. Using SONAR_SEARCH_JAVAADDITIONALOPTS = -Dnode.store.allow_mmap=false will give OutOfMemoryException in some cases.

How do I change my vm.max_map_count in any case, either through Azure Portal or Bicep automation?

0

There are 0 best solutions below