Last active
November 23, 2023 09:10
-
-
Save rfennell/c0aca11e656486b3fdb57845b18b9e3f to your computer and use it in GitHub Desktop.
A BICEP file to deploy Snipe IT to Azure - see the comments below for usage details
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
version: "3" | |
services: | |
snipe-it: | |
image: snipe/snipe-it:latest | |
volumes: | |
- snipeit:/var/lib/snipeit | |
- snipeit-logs:/var/www/html/storage/logs | |
volumes: | |
snipeit: | |
external: true | |
snipeit-logs: | |
external: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param SnipeITStorageAccount_name string | |
param SnipeITMySQLServer_name string | |
param SnipeITDB_name string | |
param SnipeITServerFarm_name string | |
param SnipeITWebsite_name string | |
param SnipeITMySQLLogin string | |
@secure() | |
param SnipeITMySQLPassword string | |
param SnipeITAppKey string | |
param SendGridAPIKey string | |
var dockerFile = loadFileAsBase64('./DockerCompose.yml') | |
var DockerComposeString = 'COMPOSE|${dockerFile}' | |
var azFileSettings = true | |
// Deployment of the storage account | |
resource SnipeITStorageAccount 'Microsoft.Storage/storageAccounts@2022-09-01' = { | |
name: SnipeITStorageAccount_name | |
location: resourceGroup().location | |
tags: { | |
Project: 'SnipeIT' | |
} | |
sku: { | |
name: 'Standard_LRS' | |
} | |
kind: 'StorageV2' | |
properties: { | |
minimumTlsVersion: 'TLS1_2' | |
allowBlobPublicAccess: true | |
allowSharedKeyAccess: true | |
largeFileSharesState: 'Enabled' | |
networkAcls: { | |
bypass: 'AzureServices' | |
virtualNetworkRules: [] | |
ipRules: [] | |
defaultAction: 'Allow' | |
} | |
supportsHttpsTrafficOnly: true | |
encryption: { | |
services: { | |
file: { | |
keyType: 'Account' | |
enabled: true | |
} | |
blob: { | |
keyType: 'Account' | |
enabled: true | |
} | |
} | |
keySource: 'Microsoft.Storage' | |
} | |
accessTier: 'Hot' | |
} | |
// Nested deployments implicitly depend on parent resource | |
// Nested deployment of file services for the storage account | |
resource SnipeITStorageAccountFileServices 'fileServices' = { | |
name: 'default' | |
// Nested deployment of specific file shares | |
// SSL cert and app data file share | |
resource SnipeITCertFileShare 'shares' = { | |
name: 'snipeit' | |
properties: { | |
accessTier: 'TransactionOptimized' | |
shareQuota: 102400 | |
enabledProtocols: 'SMB' | |
} | |
} | |
// Logs file share | |
resource SnipeITLogsFileShare 'shares' = { | |
name: 'snipeit-logs' | |
properties: { | |
accessTier: 'TransactionOptimized' | |
shareQuota: 102400 | |
enabledProtocols: 'SMB' | |
} | |
} | |
} | |
} | |
resource SnipeITMySQLServer 'Microsoft.DBforMySQL/flexibleServers@2022-09-30-preview' = { | |
name: SnipeITMySQLServer_name | |
location: resourceGroup().location | |
tags: { | |
Project: 'SnipeIT' | |
} | |
sku: { | |
name: 'Standard_B1s' | |
tier: 'Burstable' | |
} | |
properties: { | |
administratorLogin: SnipeITMySQLLogin | |
administratorLoginPassword: SnipeITMySQLPassword | |
storage: { | |
storageSizeGB: 20 | |
iops: 360 | |
autoGrow: 'Enabled' | |
autoIoScaling: 'Enabled' | |
} | |
version: '8.0.21' | |
backup: { | |
backupRetentionDays: 7 | |
geoRedundantBackup: 'Disabled' | |
} | |
replicationRole: 'None' | |
network: { | |
publicNetworkAccess: 'Enabled' | |
} | |
} | |
} | |
// MySql settings required else the initial migration fails | |
resource MySqlServer_innodb_buffer_pool_dump_at_shutdown 'Microsoft.DBforMySQL/flexibleServers/configurations@2022-01-01' = { | |
parent: SnipeITMySQLServer | |
name: 'innodb_buffer_pool_dump_at_shutdown' | |
properties: { | |
value: 'OFF' | |
} | |
} | |
resource MySqlServer_innodb_buffer_pool_load_at_startup 'Microsoft.DBforMySQL/flexibleServers/configurations@2022-01-01' = { | |
parent: SnipeITMySQLServer | |
name: 'innodb_buffer_pool_load_at_startup' | |
properties: { | |
value: 'OFF' | |
} | |
} | |
resource MySqlServer_sql_generate_invisible_primary_key 'Microsoft.DBforMySQL/flexibleServers/configurations@2022-01-01' = { | |
parent: SnipeITMySQLServer | |
name: 'sql_generate_invisible_primary_key' | |
properties: { | |
value: 'OFF' | |
} | |
} | |
resource MySqlServerFirewallRules_AzureIps 'Microsoft.DBforMySQL/flexibleServers/firewallRules@2022-01-01' = { | |
name: 'AllowAllWindowsAzureIps' | |
parent: SnipeITMySQLServer | |
properties: { | |
startIpAddress: '0.0.0.0' | |
endIpAddress: '0.0.0.0' | |
} | |
} | |
//Deployment of the server farm | |
resource SnipeITServerFarm 'Microsoft.Web/serverfarms@2022-03-01' = { | |
name: SnipeITServerFarm_name | |
location: resourceGroup().location | |
tags: { | |
Project: 'SnipeIT' | |
} | |
sku: { | |
name: 'B1' | |
tier: 'Basic' | |
size: 'B1' | |
family: 'B' | |
capacity: 1 | |
} | |
kind: 'linux' | |
properties: { | |
reserved: true | |
} | |
} | |
// SQL Database deployment | |
resource SnipeITDatabase 'Microsoft.DBforMySQL/flexibleServers/databases@2022-01-01' = { | |
name: SnipeITDB_name | |
parent: SnipeITMySQLServer | |
location: resourceGroup().location | |
properties: { | |
charset: 'utf8mb4' | |
collation: 'utf8mb4_general_ci' | |
} | |
} | |
resource SonarQubeWebSite 'Microsoft.Web/sites@2022-09-01' = { | |
name: SnipeITWebsite_name | |
location: resourceGroup().location | |
dependsOn: [ | |
SnipeITDatabase | |
SnipeITStorageAccount | |
] | |
tags: { | |
Project: 'SnipeIT' | |
} | |
kind: 'app,linux,container' | |
properties: { | |
enabled: true | |
serverFarmId: SnipeITServerFarm.id | |
siteConfig: { | |
appCommandLine: '' | |
linuxFxVersion: DockerComposeString | |
acrUseManagedIdentityCreds: false | |
alwaysOn: true | |
scmType: 'None' | |
} | |
} | |
resource SnipeITWebsiteAppSettings 'config@2021-02-01' = { | |
name: 'appsettings' | |
properties: { | |
APP_DEBUG: 'false' | |
APP_KEY: SnipeITAppKey | |
APP_URL: 'https://${SnipeITWebsite_name}.azurewebsites.net' | |
DB_CONNECTION: 'mysql' | |
DB_SSL: 'true' | |
DB_SSL_IS_PAAS: 'true' | |
DB_SSL_CA_PATH: '/var/lib/snipeit/DigiCertGlobalRootCA.crt.pem' | |
MYSQL_DATABASE: SnipeITDB_name | |
MYSQL_USER: SnipeITMySQLLogin | |
MYSQL_PASSWORD: SnipeITMySQLPassword | |
MYSQL_PORT_3306_TCP_ADDR: '${SnipeITMySQLServer_name}.mysql.database.azure.com' | |
MYSQL_PORT_3306_TCP_PORT: '3306' | |
DOCKER_REGISTRY_SERVER_URL: 'https://index.docker.io/' | |
DOCKER_REGISTRY_SERVER_USERNAME: '' | |
DOCKER_REGISTRY_SERVER_PASSWORD: '' | |
WEBSITES_ENABLE_APP_SERVICE_STORAGE: 'false' | |
MAIL_DRIVER: 'smtp' | |
MAIL_ENV_ENCRYPTION: 'tcp' | |
MAIL_PORT_587_TCP_ADDR: 'smtp.sendgrid.net' | |
MAIL_PORT_587_TCP_PORT: '587' | |
MAIL_ENV_USERNAME: 'apikey' | |
MAIL_ENV_PASSWORD: SendGridAPIKey | |
MAIL_ENV_FROM_ADDR: 'alerts@mydomain.com' | |
MAIL_ENV_FROM_NAME: 'Snipe IT' | |
} | |
} | |
resource SnipeITWebsiteConfig 'config@2021-02-01' = if (azFileSettings == true) { | |
name: 'web' | |
properties: { | |
azureStorageAccounts: { | |
'snipeit': { | |
type: 'AzureFiles' | |
accountName: SnipeITStorageAccount.name | |
shareName: 'snipeit' | |
mountPath: '/var/lib/snipeit' | |
accessKey: SnipeITStorageAccount.listKeys().keys[0].value | |
} | |
'snipeit-logs': { | |
type: 'AzureFiles' | |
accountName: SnipeITStorageAccount.name | |
shareName: 'snipeit-logs' | |
mountPath: '/var/www/html/storage/logs' | |
accessKey: SnipeITStorageAccount.listKeys().keys[0].value | |
} | |
} | |
} | |
} | |
} |
Strange, I had not seen these problems, but great that the Docker compose file got it sorted for you.
A factor maybe, in our instances we let the Web App use it's default URL and provide a 'real domain name' via Frontdoor
Thanks, Richard. Curious what your use-case is for Frontdoor?
The key reason we use Frontdoor as it allows us to centralise the management of the publicly accessible Azure hosted systems. Specifically the domain are managed in Frontdoor not on each separate service and it also automatically manages short lived SSL Certificates.
Might be important to others, but it is a bonus for us that it also provides global load balancing and CDN caching.
So the quick answer is easier admin
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks for putting this together! We followed your blog post and got everything almost working. Question for you, the
APP_URL
env variable seems to be causing redirect issues. Setting it to the default domain duplicates the URL value, and on page loadhttps://gh-test.azurewebsites.net
becomeshttps://gh-test.azurewebsites.net/gh-test.azurewebsites.net/setup
Coming from our on-prem docker install, we were able to fix this using localhost as the URL key, but open to suggestions on Azure PaaS.
Edit: After digging into this, I was able to set the
APP_URL
variable through the docker compose file, and everything works!