add openhack files
This commit is contained in:
26
iac/bicep/appInsights.bicep
Normal file
26
iac/bicep/appInsights.bicep
Normal file
@ -0,0 +1,26 @@
|
||||
param resourcesPrefix string
|
||||
var location = resourceGroup().location
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.insights/components?tabs=bicep
|
||||
resource appInsights 'Microsoft.Insights/components@2020-02-02' = {
|
||||
name: '${resourcesPrefix}appi'
|
||||
location: location
|
||||
kind: 'web'
|
||||
properties: {
|
||||
Application_Type: 'web'
|
||||
}
|
||||
}
|
||||
|
||||
resource appInsightsStaging 'Microsoft.Insights/components@2020-02-02' = {
|
||||
name: '${resourcesPrefix}appistaging'
|
||||
location: location
|
||||
kind: 'web'
|
||||
properties: {
|
||||
Application_Type: 'web'
|
||||
}
|
||||
}
|
||||
|
||||
output appInsightsInstrumentationKey string = appInsights.properties.InstrumentationKey
|
||||
output appInsightsConnectionString string = appInsights.properties.ConnectionString
|
||||
output appInsightsStagingInstrumentationKey string = appInsightsStaging.properties.InstrumentationKey
|
||||
output appInsightsStagingConnectionString string = appInsightsStaging.properties.ConnectionString
|
35
iac/bicep/appService.Test.ps1
Normal file
35
iac/bicep/appService.Test.ps1
Normal file
@ -0,0 +1,35 @@
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string[]] $HostNames
|
||||
)
|
||||
|
||||
$TestCases = @()
|
||||
|
||||
$HostNames.ForEach{ $TestCases += @{HostName = $_ } }
|
||||
Describe 'Testing connection to Websites' {
|
||||
|
||||
It ' <HostName> over HTTPS' -ForEach $TestCases {
|
||||
try {
|
||||
$request = [System.Net.WebRequest]::Create("https://$HostName")
|
||||
$request.AllowAutoRedirect = $false
|
||||
$statusCode = [int]$request.GetResponse().StatusCode
|
||||
}
|
||||
catch [System.Net.WebException] {
|
||||
$statusCode = [int]$_.Exception.Response.StatusCode
|
||||
}
|
||||
$statusCode | Should -BeIn @(200, 404) -Because "the website requires HTTPS"
|
||||
}
|
||||
|
||||
It ' <HostName> over HTTP' -ForEach $TestCases {
|
||||
try {
|
||||
$request = [System.Net.WebRequest]::Create("http://$HostName")
|
||||
$request.AllowAutoRedirect = $false
|
||||
$statusCode = [int]$request.GetResponse().StatusCode
|
||||
}
|
||||
catch [System.Net.WebException] {
|
||||
$statusCode = [int]$_.Exception.Response.StatusCode
|
||||
}
|
||||
$statusCode | Should -BeIn (300..399) -Because "HTTP is not secure"
|
||||
}
|
||||
}
|
774
iac/bicep/appService.bicep
Normal file
774
iac/bicep/appService.bicep
Normal file
@ -0,0 +1,774 @@
|
||||
param resourcesPrefix string
|
||||
param sqlServerAdminLogin string
|
||||
@secure()
|
||||
param sqlServerAdminPassword string
|
||||
param sqlServerFqdn string
|
||||
param sqlDatabaseName string
|
||||
param containerRegistryLoginServer string
|
||||
param containerRegistryName string
|
||||
param containerRegistryAdminUsername string
|
||||
param containerRegistryAdminPassword string
|
||||
param keyVaultName string // for Key Vault integration
|
||||
param appInsightsInstrumentationKey string
|
||||
param appInsightsConnectionString string
|
||||
param appInsightsStagingInstrumentationKey string
|
||||
param appInsightsStagingConnectionString string
|
||||
param apiPoiBaseImageTag string
|
||||
param apiTripsBaseImageTag string
|
||||
param apiUserJavaBaseImageTag string
|
||||
param apiUserprofileBaseImageTag string
|
||||
|
||||
var location = resourceGroup().location
|
||||
var varfile = json(loadTextContent('./variables.json'))
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles
|
||||
// AcrPull
|
||||
var acrPullRoleDefinitionId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
|
||||
|
||||
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = {
|
||||
name: containerRegistryName
|
||||
}
|
||||
|
||||
// Prepared for Key Vault integration
|
||||
resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' existing = {
|
||||
name: keyVaultName
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/serverfarms?tabs=bicep
|
||||
resource appServicePlan 'Microsoft.Web/serverfarms@2021-02-01' = {
|
||||
name: '${resourcesPrefix}plan'
|
||||
kind: 'linux'
|
||||
location: location
|
||||
properties: {
|
||||
reserved: true
|
||||
}
|
||||
sku: {
|
||||
name: 'S1'
|
||||
tier: 'Standard'
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites?tabs=bicep
|
||||
resource appServiceTripviewer 'Microsoft.Web/sites@2021-02-01' = {
|
||||
name: '${resourcesPrefix}tripviewer'
|
||||
location: location
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
properties: {
|
||||
serverFarmId: appServicePlan.id
|
||||
siteConfig: {
|
||||
acrUseManagedIdentityCreds: true
|
||||
linuxFxVersion: 'DOCKER|${containerRegistryLoginServer}/devopsoh/tripviewer:latest'
|
||||
appSettings: [
|
||||
{
|
||||
name: 'BING_MAPS_KEY'
|
||||
value: varfile.bingMapsKey
|
||||
}
|
||||
{
|
||||
name: 'USER_ROOT_URL'
|
||||
value: 'https://${appServiceApiUserprofile.properties.defaultHostName}'
|
||||
}
|
||||
{
|
||||
name: 'USER_JAVA_ROOT_URL'
|
||||
value: 'https://${appServiceApiUserJava.properties.defaultHostName}'
|
||||
}
|
||||
{
|
||||
name: 'TRIPS_ROOT_URL'
|
||||
value: 'https://${appServiceApiTrips.properties.defaultHostName}'
|
||||
}
|
||||
{
|
||||
name: 'POI_ROOT_URL'
|
||||
value: 'https://${appServiceApiPoi.properties.defaultHostName}'
|
||||
}
|
||||
{
|
||||
name: 'STAGING_USER_ROOT_URL'
|
||||
value: 'https://${appServiceApiUserprofileStaging.properties.defaultHostName}'
|
||||
}
|
||||
{
|
||||
name: 'STAGING_USER_JAVA_ROOT_URL'
|
||||
value: 'https://${appServiceApiUserJavaStaging.properties.defaultHostName}'
|
||||
}
|
||||
{
|
||||
name: 'STAGING_TRIPS_ROOT_URL'
|
||||
value: 'https://${appServiceApiTripsStaging.properties.defaultHostName}'
|
||||
}
|
||||
{
|
||||
name: 'STAGING_POI_ROOT_URL'
|
||||
value: 'https://${appServiceApiPoiStaging.properties.defaultHostName}'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_URL'
|
||||
value: 'https://${containerRegistryLoginServer}'
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: appInsightsInstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: appInsightsConnectionString
|
||||
}
|
||||
]
|
||||
alwaysOn: true
|
||||
}
|
||||
httpsOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/config-logs?tabs=bicep
|
||||
resource appServiceTripviewerExtension 'Microsoft.Web/sites/config@2021-02-01' = {
|
||||
parent: appServiceTripviewer
|
||||
name: 'logs'
|
||||
properties: {
|
||||
httpLogs: {
|
||||
fileSystem: {
|
||||
retentionInMb: 50
|
||||
retentionInDays: 7
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep
|
||||
resource acrPullRoleAssignmentTripviewer 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = {
|
||||
name: guid(resourceGroup().id, containerRegistry.id, 'tripviewer', acrPullRoleDefinitionId)
|
||||
scope: containerRegistry
|
||||
properties: {
|
||||
roleDefinitionId: acrPullRoleDefinitionId
|
||||
principalId: appServiceTripviewer.identity.principalId
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites?tabs=bicep
|
||||
resource appServiceApiPoi 'Microsoft.Web/sites@2021-02-01' = {
|
||||
name: '${resourcesPrefix}poi'
|
||||
location: location
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
properties: {
|
||||
serverFarmId: appServicePlan.id
|
||||
siteConfig: {
|
||||
linuxFxVersion: 'DOCKER|${containerRegistryLoginServer}/devopsoh/api-poi:${apiPoiBaseImageTag}'
|
||||
healthCheckPath: '/api/healthcheck/poi'
|
||||
appSettings: [
|
||||
{
|
||||
name: 'SQL_USER'
|
||||
value: sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_PASSWORD'
|
||||
value: sqlServerAdminPassword
|
||||
//value: '@Microsoft.KeyVault(VaultName=${keyVault.name};SecretName=SQL-PASSWORD)' // for Key Vault integration
|
||||
}
|
||||
{
|
||||
name: 'SQL_SERVER'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_DBNAME'
|
||||
value: sqlDatabaseName
|
||||
}
|
||||
{
|
||||
name: 'WEBSITES_PORT'
|
||||
value: '8080'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_URL'
|
||||
value: 'https://${containerRegistryLoginServer}'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_USERNAME'
|
||||
value: containerRegistryAdminUsername
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
|
||||
value: containerRegistryAdminPassword
|
||||
//value: '@Microsoft.KeyVault(VaultName=${keyVault.name};SecretName=DOCKER-REGISTRY-SERVER-PASSWORD)' // for Key Vault integration
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: appInsightsInstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: appInsightsConnectionString
|
||||
}
|
||||
]
|
||||
alwaysOn: true
|
||||
}
|
||||
httpsOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/config-logs?tabs=bicep
|
||||
resource appServiceApiPoiExtension 'Microsoft.Web/sites/config@2021-02-01' = {
|
||||
parent: appServiceApiPoi
|
||||
name: 'logs'
|
||||
properties: {
|
||||
httpLogs: {
|
||||
fileSystem: {
|
||||
retentionInMb: 50
|
||||
retentionInDays: 7
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepared for Key Vault integration
|
||||
// resource keyVaultAccessPolicyApiPoi 'Microsoft.KeyVault/vaults/accessPolicies@2021-06-01-preview' = {
|
||||
// name: 'add'
|
||||
// parent: keyVault
|
||||
// properties: {
|
||||
// accessPolicies: [
|
||||
// {
|
||||
// tenantId: appServiceApiPoi.identity.tenantId
|
||||
// objectId: appServiceApiPoi.identity.principalId
|
||||
// permissions: {
|
||||
// secrets: [
|
||||
// 'get'
|
||||
// 'list'
|
||||
// 'set'
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/slots?tabs=bicep
|
||||
resource appServiceApiPoiStaging 'Microsoft.Web/sites/slots@2021-02-01' = {
|
||||
parent: appServiceApiPoi
|
||||
name: 'staging'
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
location: location
|
||||
properties: {
|
||||
serverFarmId: appServicePlan.id
|
||||
siteConfig: {
|
||||
linuxFxVersion: 'DOCKER|${containerRegistryLoginServer}/devopsoh/api-poi:${apiPoiBaseImageTag}'
|
||||
healthCheckPath: '/api/healthcheck/poi'
|
||||
appSettings: [
|
||||
{
|
||||
name: 'SQL_USER'
|
||||
value: sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_PASSWORD'
|
||||
value: sqlServerAdminPassword
|
||||
//value: '@Microsoft.KeyVault(VaultName=${keyVault.name};SecretName=SQL-PASSWORD)' // for Key Vault integration
|
||||
}
|
||||
{
|
||||
name: 'SQL_SERVER'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_DBNAME'
|
||||
value: sqlDatabaseName
|
||||
}
|
||||
{
|
||||
name: 'WEBSITES_PORT'
|
||||
value: '8080'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_URL'
|
||||
value: 'https://${containerRegistryLoginServer}'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_USERNAME'
|
||||
value: containerRegistryAdminUsername
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
|
||||
value: containerRegistryAdminPassword
|
||||
//value: '@Microsoft.KeyVault(VaultName=${keyVault.name};SecretName=DOCKER-REGISTRY-SERVER-PASSWORD)' // for Key Vault integration
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: appInsightsStagingInstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: appInsightsStagingConnectionString
|
||||
}
|
||||
]
|
||||
alwaysOn: true
|
||||
}
|
||||
httpsOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/config-logs?tabs=bicep
|
||||
resource appServiceApiPoiStagingExtension 'Microsoft.Web/sites/slots/config@2021-02-01' = {
|
||||
parent: appServiceApiPoiStaging
|
||||
name: 'logs'
|
||||
properties: {
|
||||
httpLogs: {
|
||||
fileSystem: {
|
||||
retentionInMb: 50
|
||||
retentionInDays: 7
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Prepared for Key Vault integration
|
||||
// resource keyVaultAccessPolicyApiPoiStaging 'Microsoft.KeyVault/vaults/accessPolicies@2021-06-01-preview' = {
|
||||
// name: 'add'
|
||||
// parent: keyVault
|
||||
// properties: {
|
||||
// accessPolicies: [
|
||||
// {
|
||||
// tenantId: appServiceApiPoiStaging.identity.tenantId
|
||||
// objectId: appServiceApiPoiStaging.identity.principalId
|
||||
// permissions: {
|
||||
// secrets: [
|
||||
// 'get'
|
||||
// 'list'
|
||||
// 'set'
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
// ]
|
||||
// }
|
||||
// }
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites?tabs=bicep
|
||||
resource appServiceApiTrips 'Microsoft.Web/sites@2021-02-01' = {
|
||||
name: '${resourcesPrefix}trips'
|
||||
location: location
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
properties: {
|
||||
serverFarmId: appServicePlan.id
|
||||
siteConfig: {
|
||||
linuxFxVersion: 'DOCKER|${containerRegistryLoginServer}/devopsoh/api-trips:${apiTripsBaseImageTag}'
|
||||
healthCheckPath: '/api/healthcheck/trips'
|
||||
appSettings: [
|
||||
{
|
||||
name: 'SQL_USER'
|
||||
value: sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_PASSWORD'
|
||||
value: sqlServerAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'SQL_SERVER'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_DBNAME'
|
||||
value: sqlDatabaseName
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_URL'
|
||||
value: 'https://${containerRegistryLoginServer}'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_USERNAME'
|
||||
value: containerRegistryAdminUsername
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
|
||||
value: containerRegistryAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: appInsightsInstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: appInsightsConnectionString
|
||||
}
|
||||
]
|
||||
alwaysOn: true
|
||||
}
|
||||
httpsOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/config-logs?tabs=bicep
|
||||
resource appServiceApiTripsExtension 'Microsoft.Web/sites/config@2021-02-01' = {
|
||||
parent: appServiceApiTrips
|
||||
name: 'logs'
|
||||
properties: {
|
||||
httpLogs: {
|
||||
fileSystem: {
|
||||
retentionInMb: 50
|
||||
retentionInDays: 7
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/slots?tabs=bicep
|
||||
resource appServiceApiTripsStaging 'Microsoft.Web/sites/slots@2021-02-01' = {
|
||||
parent: appServiceApiTrips
|
||||
name: 'staging'
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
location: location
|
||||
properties: {
|
||||
serverFarmId: appServicePlan.id
|
||||
siteConfig: {
|
||||
linuxFxVersion: 'DOCKER|${containerRegistryLoginServer}/devopsoh/api-trips:${apiTripsBaseImageTag}'
|
||||
healthCheckPath: '/api/healthcheck/trips'
|
||||
appSettings: [
|
||||
{
|
||||
name: 'SQL_USER'
|
||||
value: sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_PASSWORD'
|
||||
value: sqlServerAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'SQL_SERVER'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_DBNAME'
|
||||
value: sqlDatabaseName
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_URL'
|
||||
value: 'https://${containerRegistryLoginServer}'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_USERNAME'
|
||||
value: containerRegistryAdminUsername
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
|
||||
value: containerRegistryAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: appInsightsStagingInstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: appInsightsStagingConnectionString
|
||||
}
|
||||
]
|
||||
alwaysOn: true
|
||||
}
|
||||
httpsOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/config-logs?tabs=bicep
|
||||
resource appServiceApiTripsStagingExtension 'Microsoft.Web/sites/slots/config@2021-02-01' = {
|
||||
parent: appServiceApiTripsStaging
|
||||
name: 'logs'
|
||||
properties: {
|
||||
httpLogs: {
|
||||
fileSystem: {
|
||||
retentionInMb: 50
|
||||
retentionInDays: 7
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites?tabs=bicep
|
||||
resource appServiceApiUserJava 'Microsoft.Web/sites@2021-02-01' = {
|
||||
name: '${resourcesPrefix}userjava'
|
||||
location: location
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
properties: {
|
||||
serverFarmId: appServicePlan.id
|
||||
siteConfig: {
|
||||
linuxFxVersion: 'DOCKER|${containerRegistryLoginServer}/devopsoh/api-user-java:${apiUserJavaBaseImageTag}'
|
||||
healthCheckPath: '/api/healthcheck/user-java'
|
||||
appSettings: [
|
||||
{
|
||||
name: 'SQL_USER'
|
||||
value: sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_PASSWORD'
|
||||
value: sqlServerAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'SQL_SERVER'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_DBNAME'
|
||||
value: sqlDatabaseName
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_URL'
|
||||
value: 'https://${containerRegistryLoginServer}'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_USERNAME'
|
||||
value: containerRegistryAdminUsername
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
|
||||
value: containerRegistryAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: appInsightsInstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: appInsightsConnectionString
|
||||
}
|
||||
]
|
||||
alwaysOn: true
|
||||
}
|
||||
httpsOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/config-logs?tabs=bicep
|
||||
resource appServiceApiUserJavaExtension 'Microsoft.Web/sites/config@2021-02-01' = {
|
||||
parent: appServiceApiUserJava
|
||||
name: 'logs'
|
||||
properties: {
|
||||
httpLogs: {
|
||||
fileSystem: {
|
||||
retentionInMb: 50
|
||||
retentionInDays: 7
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/slots?tabs=bicep
|
||||
resource appServiceApiUserJavaStaging 'Microsoft.Web/sites/slots@2021-02-01' = {
|
||||
parent: appServiceApiUserJava
|
||||
name: 'staging'
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
location: location
|
||||
properties: {
|
||||
serverFarmId: appServicePlan.id
|
||||
siteConfig: {
|
||||
linuxFxVersion: 'DOCKER|${containerRegistryLoginServer}/devopsoh/api-user-java:${apiUserJavaBaseImageTag}'
|
||||
healthCheckPath: '/api/healthcheck/user-java'
|
||||
appSettings: [
|
||||
{
|
||||
name: 'SQL_USER'
|
||||
value: sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_PASSWORD'
|
||||
value: sqlServerAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'SQL_SERVER'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_DBNAME'
|
||||
value: sqlDatabaseName
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_URL'
|
||||
value: 'https://${containerRegistryLoginServer}'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_USERNAME'
|
||||
value: containerRegistryAdminUsername
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
|
||||
value: containerRegistryAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: appInsightsStagingInstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: appInsightsStagingConnectionString
|
||||
}
|
||||
]
|
||||
alwaysOn: true
|
||||
}
|
||||
httpsOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/config-logs?tabs=bicep
|
||||
resource appServiceApiUserJavaStagingExtension 'Microsoft.Web/sites/slots/config@2021-02-01' = {
|
||||
parent: appServiceApiUserJavaStaging
|
||||
name: 'logs'
|
||||
properties: {
|
||||
httpLogs: {
|
||||
fileSystem: {
|
||||
retentionInMb: 50
|
||||
retentionInDays: 7
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites?tabs=bicep
|
||||
resource appServiceApiUserprofile 'Microsoft.Web/sites@2021-02-01' = {
|
||||
name: '${resourcesPrefix}userprofile'
|
||||
location: location
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
properties: {
|
||||
serverFarmId: appServicePlan.id
|
||||
siteConfig: {
|
||||
linuxFxVersion: 'DOCKER|${containerRegistryLoginServer}/devopsoh/api-userprofile:${apiUserprofileBaseImageTag}'
|
||||
healthCheckPath: '/api/healthcheck/user'
|
||||
appSettings: [
|
||||
{
|
||||
name: 'SQL_USER'
|
||||
value: sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_PASSWORD'
|
||||
value: sqlServerAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'SQL_SERVER'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_DBNAME'
|
||||
value: sqlDatabaseName
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_URL'
|
||||
value: 'https://${containerRegistryLoginServer}'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_USERNAME'
|
||||
value: containerRegistryAdminUsername
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
|
||||
value: containerRegistryAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: appInsightsInstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: appInsightsConnectionString
|
||||
}
|
||||
]
|
||||
alwaysOn: true
|
||||
}
|
||||
httpsOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/config-logs?tabs=bicep
|
||||
resource appServiceApiUserprofileExtension 'Microsoft.Web/sites/config@2021-02-01' = {
|
||||
parent: appServiceApiUserprofile
|
||||
name: 'logs'
|
||||
properties: {
|
||||
httpLogs: {
|
||||
fileSystem: {
|
||||
retentionInMb: 50
|
||||
retentionInDays: 7
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/slots?tabs=bicep
|
||||
resource appServiceApiUserprofileStaging 'Microsoft.Web/sites/slots@2021-02-01' = {
|
||||
parent: appServiceApiUserprofile
|
||||
name: 'staging'
|
||||
identity: {
|
||||
type: 'SystemAssigned'
|
||||
}
|
||||
location: location
|
||||
properties: {
|
||||
serverFarmId: appServicePlan.id
|
||||
siteConfig: {
|
||||
linuxFxVersion: 'DOCKER|${containerRegistryLoginServer}/devopsoh/api-userprofile:${apiUserprofileBaseImageTag}'
|
||||
healthCheckPath: '/api/healthcheck/user'
|
||||
appSettings: [
|
||||
{
|
||||
name: 'SQL_USER'
|
||||
value: sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_PASSWORD'
|
||||
value: sqlServerAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'SQL_SERVER'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_DBNAME'
|
||||
value: sqlDatabaseName
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_URL'
|
||||
value: 'https://${containerRegistryLoginServer}'
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_USERNAME'
|
||||
value: containerRegistryAdminUsername
|
||||
}
|
||||
{
|
||||
name: 'DOCKER_REGISTRY_SERVER_PASSWORD'
|
||||
value: containerRegistryAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'APPINSIGHTS_INSTRUMENTATIONKEY'
|
||||
value: appInsightsStagingInstrumentationKey
|
||||
}
|
||||
{
|
||||
name: 'APPLICATIONINSIGHTS_CONNECTION_STRING'
|
||||
value: appInsightsStagingConnectionString
|
||||
}
|
||||
]
|
||||
alwaysOn: true
|
||||
}
|
||||
httpsOnly: true
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.web/sites/config-logs?tabs=bicep
|
||||
resource appServiceApiUserprofileStagingExtension 'Microsoft.Web/sites/slots/config@2021-02-01' = {
|
||||
parent: appServiceApiUserprofileStaging
|
||||
name: 'logs'
|
||||
properties: {
|
||||
httpLogs: {
|
||||
fileSystem: {
|
||||
retentionInMb: 50
|
||||
retentionInDays: 7
|
||||
enabled: true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
output appServiceApiPoiHostname string = appServiceApiPoi.properties.defaultHostName
|
||||
output appServiceApiTripsHostname string = appServiceApiTrips.properties.defaultHostName
|
||||
output appServiceApiUserJavaHostname string = appServiceApiUserJava.properties.defaultHostName
|
||||
output appServiceApiUserprofileHostname string = appServiceApiUserprofile.properties.defaultHostName
|
147
iac/bicep/apps.bicep
Normal file
147
iac/bicep/apps.bicep
Normal file
@ -0,0 +1,147 @@
|
||||
param resourcesPrefix string
|
||||
param sqlServerFqdn string
|
||||
param sqlServerName string
|
||||
param sqlServerAdminPassword string
|
||||
param containerRegistryLoginServer string
|
||||
param containerRegistryName string
|
||||
param userAssignedManagedIdentityId string
|
||||
param userAssignedManagedIdentityPrincipalId string
|
||||
|
||||
var location = resourceGroup().location
|
||||
var varfile = json(loadTextContent('./variables.json'))
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles
|
||||
// Contributor
|
||||
var contributorRoleDefinitionId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b24988ac-6180-42a0-ab88-20f7382dd24c')
|
||||
|
||||
resource sqlServer 'Microsoft.Sql/servers@2021-02-01-preview' existing = {
|
||||
name: sqlServerName
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep
|
||||
resource sqlContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = {
|
||||
name: guid(resourceGroup().id, sqlServer.id, userAssignedManagedIdentityId, contributorRoleDefinitionId)
|
||||
scope: sqlServer
|
||||
properties: {
|
||||
roleDefinitionId: contributorRoleDefinitionId
|
||||
principalId: userAssignedManagedIdentityPrincipalId
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.resources/deploymentscripts?tabs=bicep
|
||||
resource dataInit 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
|
||||
name: '${resourcesPrefix}dataInit'
|
||||
location: location
|
||||
kind: 'AzureCLI'
|
||||
identity: {
|
||||
type: 'UserAssigned'
|
||||
userAssignedIdentities: {
|
||||
'${userAssignedManagedIdentityId}': {}
|
||||
}
|
||||
}
|
||||
properties: {
|
||||
azCliVersion: '2.33.1'
|
||||
cleanupPreference: 'Always'
|
||||
containerSettings: {
|
||||
containerGroupName: '${resourcesPrefix}datainit'
|
||||
}
|
||||
scriptContent: loadTextContent('datainit.sh')
|
||||
environmentVariables: [
|
||||
{
|
||||
name: 'SQL_SERVER_NAME'
|
||||
value: sqlServerName
|
||||
}
|
||||
{
|
||||
name: 'SQL_SERVER_FQDN'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_ADMIN_LOGIN'
|
||||
value: varfile.sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_ADMIN_PASSWORD'
|
||||
secureValue: sqlServerAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'SQL_DB_NAME'
|
||||
value: 'mydrivingDB'
|
||||
}
|
||||
{
|
||||
name: 'RESOURCE_GROUP'
|
||||
value: resourceGroup().name
|
||||
}
|
||||
{
|
||||
name: 'TEAM_REPO'
|
||||
value: varfile.publicTeamRepo
|
||||
}
|
||||
{
|
||||
name: 'TEAM_REPO_BRANCH'
|
||||
value: varfile.publicTeamRepoBranch
|
||||
}
|
||||
]
|
||||
retentionInterval: 'PT1H'
|
||||
timeout: 'PT15M'
|
||||
}
|
||||
dependsOn: [
|
||||
sqlContributorRoleAssignment
|
||||
]
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.containerregistry/registries?tabs=bicep
|
||||
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = {
|
||||
name: containerRegistryName
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep
|
||||
resource acrContributorRoleAssignment 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = {
|
||||
name: guid(resourceGroup().id, containerRegistry.id, userAssignedManagedIdentityId, contributorRoleDefinitionId)
|
||||
scope: containerRegistry
|
||||
properties: {
|
||||
roleDefinitionId: contributorRoleDefinitionId
|
||||
principalId: userAssignedManagedIdentityPrincipalId
|
||||
}
|
||||
}
|
||||
|
||||
//https://docs.microsoft.com/en-us/azure/templates/microsoft.resources/deploymentscripts?tabs=bicep
|
||||
resource dockerBuild 'Microsoft.Resources/deploymentScripts@2020-10-01' = {
|
||||
name: '${resourcesPrefix}dockerBuild'
|
||||
location: location
|
||||
kind: 'AzureCLI'
|
||||
identity: {
|
||||
type: 'UserAssigned'
|
||||
userAssignedIdentities: {
|
||||
'${userAssignedManagedIdentityId}': {}
|
||||
}
|
||||
}
|
||||
properties: {
|
||||
azCliVersion: '2.33.1'
|
||||
cleanupPreference: 'Always'
|
||||
containerSettings: {
|
||||
containerGroupName: '${resourcesPrefix}dockerdbuild'
|
||||
}
|
||||
scriptContent: loadTextContent('dockerbuild.sh')
|
||||
environmentVariables: [
|
||||
{
|
||||
name: 'CONTAINER_REGISTRY'
|
||||
value: containerRegistryLoginServer
|
||||
}
|
||||
{
|
||||
name: 'BASE_IMAGE_TAG'
|
||||
value: varfile.baseImageTag
|
||||
}
|
||||
{
|
||||
name: 'TEAM_REPO'
|
||||
value: varfile.publicTeamRepo
|
||||
}
|
||||
{
|
||||
name: 'TEAM_REPO_BRANCH'
|
||||
value: varfile.publicTeamRepoBranch
|
||||
}
|
||||
]
|
||||
retentionInterval: 'P1D'
|
||||
}
|
||||
dependsOn: [
|
||||
acrContributorRoleAssignment
|
||||
]
|
||||
}
|
28
iac/bicep/bicepconfig.json
Normal file
28
iac/bicep/bicepconfig.json
Normal file
@ -0,0 +1,28 @@
|
||||
{
|
||||
"analyzers": {
|
||||
"core": {
|
||||
"enabled": true,
|
||||
"verbose": true,
|
||||
"rules": {
|
||||
"no-hardcoded-env-urls": {
|
||||
"level": "error"
|
||||
},
|
||||
"no-unused-params": {
|
||||
"level": "error"
|
||||
},
|
||||
"no-unused-vars": {
|
||||
"level": "error"
|
||||
},
|
||||
"prefer-interpolation": {
|
||||
"level": "error"
|
||||
},
|
||||
"secure-parameter-default": {
|
||||
"level": "error"
|
||||
},
|
||||
"simplify-interpolation": {
|
||||
"level": "error"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
138
iac/bicep/containerGroup.bicep
Normal file
138
iac/bicep/containerGroup.bicep
Normal file
@ -0,0 +1,138 @@
|
||||
param resourcesPrefix string
|
||||
param sqlServerAdminLogin string
|
||||
@secure()
|
||||
param sqlServerAdminPassword string
|
||||
param sqlServerFqdn string
|
||||
param sqlDatabaseName string
|
||||
param containerRegistryLoginServer string
|
||||
param containerRegistryAdminUsername string
|
||||
@secure()
|
||||
param containerRegistryAdminPassword string
|
||||
param appServiceApiPoiHostname string
|
||||
param appServiceApiTripsHostname string
|
||||
param appServiceApiUserJavaHostname string
|
||||
param appServiceApiUserprofileHostname string
|
||||
param logAnalyticsWorkspaceId string
|
||||
@secure()
|
||||
param logAnalyticsWorkspaceKey string
|
||||
// param containerRegistryName string
|
||||
// param userAssignedManagedIdentityId string
|
||||
// param userAssignedManagedIdentityPrincipalId string
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles
|
||||
// AcrPull
|
||||
// var acrPullRoleDefinitionId = subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '7f951dda-4ed3-4680-a7ca-43fe172d538d')
|
||||
|
||||
// resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' existing = {
|
||||
// name: containerRegistryName
|
||||
// }
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.authorization/roleassignments?tabs=bicep
|
||||
// resource acrPullRoleAssignmentSimulator 'Microsoft.Authorization/roleAssignments@2020-08-01-preview' = {
|
||||
// name: guid(resourceGroup().id, containerRegistry.id, 'simulator', acrPullRoleDefinitionId)
|
||||
// scope: containerRegistry
|
||||
// properties: {
|
||||
// roleDefinitionId: acrPullRoleDefinitionId
|
||||
// principalId: userAssignedManagedIdentityPrincipalId
|
||||
// }
|
||||
// }
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.containerinstance/containergroups?tabs=bicep
|
||||
resource containerGroup 'Microsoft.ContainerInstance/containerGroups@2021-09-01' = {
|
||||
name: '${resourcesPrefix}simulator'
|
||||
location: resourceGroup().location
|
||||
// identity: {
|
||||
// type: 'UserAssigned'
|
||||
// userAssignedIdentities: {
|
||||
// '${userAssignedManagedIdentityId}': {}
|
||||
// }
|
||||
// }
|
||||
properties: {
|
||||
containers: [
|
||||
{
|
||||
name: 'simulator'
|
||||
properties: {
|
||||
environmentVariables: [
|
||||
{
|
||||
name: 'SQL_SERVER'
|
||||
value: sqlServerFqdn
|
||||
}
|
||||
{
|
||||
name: 'SQL_USER'
|
||||
value: sqlServerAdminLogin
|
||||
}
|
||||
{
|
||||
name: 'SQL_PASSWORD'
|
||||
secureValue: sqlServerAdminPassword
|
||||
}
|
||||
{
|
||||
name: 'SQL_DBNAME'
|
||||
value: sqlDatabaseName
|
||||
}
|
||||
{
|
||||
name: 'TEAM_NAME'
|
||||
value: resourcesPrefix
|
||||
}
|
||||
{
|
||||
name: 'USER_ROOT_URL'
|
||||
value: 'https://${appServiceApiUserprofileHostname}'
|
||||
}
|
||||
{
|
||||
name: 'USER_JAVA_ROOT_URL'
|
||||
value: 'https://${appServiceApiUserJavaHostname}'
|
||||
}
|
||||
{
|
||||
name: 'TRIPS_ROOT_URL'
|
||||
value: 'https://${appServiceApiTripsHostname}'
|
||||
}
|
||||
{
|
||||
name: 'POI_ROOT_URL'
|
||||
value: 'https://${appServiceApiPoiHostname}'
|
||||
}
|
||||
]
|
||||
image: '${containerRegistryLoginServer}/devopsoh/simulator:latest'
|
||||
ports: [
|
||||
{
|
||||
port: 8080
|
||||
protocol: 'TCP'
|
||||
}
|
||||
]
|
||||
resources: {
|
||||
requests: {
|
||||
cpu: 1
|
||||
memoryInGB: 2
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
imageRegistryCredentials: [
|
||||
{
|
||||
password: containerRegistryAdminPassword
|
||||
server: containerRegistryLoginServer
|
||||
username: containerRegistryAdminUsername
|
||||
}
|
||||
]
|
||||
ipAddress: {
|
||||
dnsNameLabel: '${resourcesPrefix}simulator'
|
||||
ports: [
|
||||
{
|
||||
port: 8080
|
||||
protocol: 'TCP'
|
||||
}
|
||||
]
|
||||
type: 'Public'
|
||||
}
|
||||
osType: 'Linux'
|
||||
diagnostics: {
|
||||
logAnalytics: {
|
||||
logType: 'ContainerInsights'
|
||||
workspaceId: logAnalyticsWorkspaceId
|
||||
workspaceKey: logAnalyticsWorkspaceKey
|
||||
}
|
||||
}
|
||||
}
|
||||
// dependsOn: [
|
||||
// acrPullRoleAssignmentSimulator
|
||||
// ]
|
||||
}
|
20
iac/bicep/containerRegistry.bicep
Normal file
20
iac/bicep/containerRegistry.bicep
Normal file
@ -0,0 +1,20 @@
|
||||
param resourcesPrefix string
|
||||
|
||||
var location = resourceGroup().location
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.containerregistry/registries?tabs=bicep
|
||||
resource containerRegistry 'Microsoft.ContainerRegistry/registries@2021-09-01' = {
|
||||
name: '${resourcesPrefix}cr'
|
||||
location: location
|
||||
sku: {
|
||||
name: 'Standard'
|
||||
}
|
||||
properties: {
|
||||
adminUserEnabled: true
|
||||
}
|
||||
}
|
||||
|
||||
output containerRegistryLoginServer string = containerRegistry.properties.loginServer
|
||||
output containerRegistryAdminUsername string = containerRegistry.listCredentials().username
|
||||
output containerRegistryAdminPassword string = containerRegistry.listCredentials().passwords[0].value
|
||||
output containerRegistryName string = containerRegistry.name
|
34
iac/bicep/datainit.sh
Normal file
34
iac/bicep/datainit.sh
Normal file
@ -0,0 +1,34 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd ~/
|
||||
export ACCEPT_EULA="Y"
|
||||
MSSQL_VERSION="17.8.1.1-1"
|
||||
|
||||
curl -O "https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/msodbcsql17_${MSSQL_VERSION}_amd64.apk"
|
||||
curl -O "https://download.microsoft.com/download/e/4/e/e4e67866-dffd-428c-aac7-8d28ddafb39b/mssql-tools_${MSSQL_VERSION}_amd64.apk"
|
||||
|
||||
apk add --allow-untrusted msodbcsql17_${MSSQL_VERSION}_amd64.apk
|
||||
apk add --allow-untrusted mssql-tools_${MSSQL_VERSION}_amd64.apk
|
||||
apk update && apk add bind-tools
|
||||
|
||||
export PATH="$PATH:/opt/mssql-tools/bin"
|
||||
|
||||
echo "MSSQL_VERSION: ${MSSQL_VERSION}" 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/vars.txt"
|
||||
echo "RESOURCE_GROUP: ${RESOURCE_GROUP}" 2>&1 | tee -a "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/vars.txt"
|
||||
echo "TEAM_REPO: ${TEAM_REPO}" 2>&1 | tee -a "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/vars.txt"
|
||||
echo "TEAM_REPO_BRANCH: ${TEAM_REPO_BRANCH}" 2>&1 | tee -a "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/vars.txt"
|
||||
echo "SQL_SERVER_NAME: ${SQL_SERVER_NAME}" 2>&1 | tee -a "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/vars.txt"
|
||||
echo "SQL_ADMIN_LOGIN: ${SQL_ADMIN_LOGIN}" 2>&1 | tee -a "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/vars.txt"
|
||||
echo "SQL_SERVER_FQDN: ${SQL_SERVER_FQDN}" 2>&1 | tee -a "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/vars.txt"
|
||||
echo "SQL_DB_NAME: ${SQL_DB_NAME}" 2>&1 | tee -a "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/vars.txt"
|
||||
|
||||
MYIP="$(dig +short myip.opendns.com @resolver1.opendns.com -4)"
|
||||
az sql server firewall-rule create --resource-group ${RESOURCE_GROUP} --server ${SQL_SERVER_NAME} --name dataInit --start-ip-address ${MYIP} --end-ip-address ${MYIP} 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/sqlFwCreate.txt"
|
||||
|
||||
git clone "${TEAM_REPO}" --branch "${TEAM_REPO_BRANCH}" ~/openhack
|
||||
cd ~/openhack/support/datainit
|
||||
|
||||
sqlcmd -U ${SQL_ADMIN_LOGIN} -P ${SQL_ADMIN_PASSWORD} -S ${SQL_SERVER_FQDN} -d ${SQL_DB_NAME} -i ./MYDrivingDB.sql -e 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/sqlCmd.txt"
|
||||
bash ./sql_data_init.sh -s ${SQL_SERVER_FQDN} -u ${SQL_ADMIN_LOGIN} -p ${SQL_ADMIN_PASSWORD} -d ${SQL_DB_NAME} 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/dataInit.txt"
|
||||
|
||||
az sql server firewall-rule delete --resource-group ${RESOURCE_GROUP} --server ${SQL_SERVER_NAME} --name dataInit 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/sqlFwDelete.txt"
|
130
iac/bicep/deploy.sh
Normal file
130
iac/bicep/deploy.sh
Normal file
@ -0,0 +1,130 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare UNIQUER=""
|
||||
declare LOCATION=""
|
||||
declare RESOURCES_PREFIX=""
|
||||
declare -r USAGE_HELP="Usage: ./deploy.sh -l <LOCATION> [-u <UNIQUER> -r <RESOURCES_PREFIX>]"
|
||||
|
||||
declare -r BUILD_ID="${RANDOM:0:5}"
|
||||
|
||||
_error() {
|
||||
echo "##[error] $@" 2>&1
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
_error "${USAGE_HELP}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":l:u:r:" arg; do
|
||||
case "${arg}" in
|
||||
l) # Process -l (LOCATION)
|
||||
LOCATION="${OPTARG}"
|
||||
;;
|
||||
u) # Process -u (UNIQUER)
|
||||
UNIQUER="${OPTARG}"
|
||||
;;
|
||||
r) # Process -r (RESOURCES_PREFIX)
|
||||
RESOURCES_PREFIX="${OPTARG}"
|
||||
;;
|
||||
\?)
|
||||
_error "Invalid options found: -${OPTARG}."
|
||||
_error "${USAGE_HELP}" 2>&1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ ${#LOCATION} -eq 0 ]; then
|
||||
_error "Required LOCATION parameter is not set!"
|
||||
_error "${USAGE_HELP}" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for programs
|
||||
if ! [ -x "$(command -v az)" ]; then
|
||||
_error "az is not installed!"
|
||||
exit 1
|
||||
elif ! [ -x "$(command -v jq)" ]; then
|
||||
_error "jq is not installed!"
|
||||
exit 1
|
||||
elif ! [ -x "$(command -v pwsh)" ]; then
|
||||
_error "pwsh is not installed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
azure_login() {
|
||||
_azuresp_json=$(cat azuresp.json)
|
||||
export ARM_CLIENT_ID=$(echo "${_azuresp_json}" | jq -r ".clientId")
|
||||
export ARM_CLIENT_SECRET=$(echo "${_azuresp_json}" | jq -r ".clientSecret")
|
||||
export ARM_SUBSCRIPTION_ID=$(echo "${_azuresp_json}" | jq -r ".subscriptionId")
|
||||
export ARM_TENANT_ID=$(echo "${_azuresp_json}" | jq -r ".tenantId")
|
||||
az login --service-principal --username "${ARM_CLIENT_ID}" --password "${ARM_CLIENT_SECRET}" --tenant "${ARM_TENANT_ID}"
|
||||
az account set --subscription "${ARM_SUBSCRIPTION_ID}"
|
||||
}
|
||||
|
||||
azure_logout() {
|
||||
az logout
|
||||
az cache purge
|
||||
az account clear
|
||||
}
|
||||
|
||||
lint_bicep() {
|
||||
az bicep build --file main.bicep
|
||||
rm main.json
|
||||
}
|
||||
|
||||
validate_bicep() {
|
||||
if [ ${#RESOURCES_PREFIX} -gt 0 ]; then
|
||||
az deployment sub validate --name "${RESOURCES_PREFIX}-${BUILD_ID}" --template-file main.bicep --location "${LOCATION}" --parameters resourcesPrefix="${RESOURCES_PREFIX}"
|
||||
elif [[ ${#RESOURCES_PREFIX} -eq 0 && ${#UNIQUER} -gt 0 ]]; then
|
||||
az deployment sub validate --name "${UNIQUER}-${BUILD_ID}" --template-file main.bicep --location "${LOCATION}" --parameters uniquer="${UNIQUER}"
|
||||
else
|
||||
az deployment sub validate --name "${BUILD_ID}" --template-file main.bicep --location "${LOCATION}"
|
||||
fi
|
||||
}
|
||||
|
||||
preview_bicep() {
|
||||
if [ ${#RESOURCES_PREFIX} -gt 0 ]; then
|
||||
az deployment sub what-if --name "${RESOURCES_PREFIX}-${BUILD_ID}" --template-file main.bicep --location "${LOCATION}" --parameters resourcesPrefix="${RESOURCES_PREFIX}"
|
||||
elif [[ ${#RESOURCES_PREFIX} -eq 0 && ${#UNIQUER} -gt 0 ]]; then
|
||||
az deployment sub what-if --name "${UNIQUER}-${BUILD_ID}" --template-file main.bicep --location "${LOCATION}" --parameters uniquer="${UNIQUER}"
|
||||
else
|
||||
az deployment sub what-if --name "${BUILD_ID}" --template-file main.bicep --location "${LOCATION}"
|
||||
fi
|
||||
}
|
||||
|
||||
deploy_bicep() {
|
||||
if [ ${#RESOURCES_PREFIX} -gt 0 ]; then
|
||||
_deployment_output=$(az deployment sub create --name "${RESOURCES_PREFIX}-${BUILD_ID}" --template-file main.bicep --location "${LOCATION}" --parameters resourcesPrefix="${RESOURCES_PREFIX}")
|
||||
elif [[ ${#RESOURCES_PREFIX} -eq 0 && ${#UNIQUER} -gt 0 ]]; then
|
||||
_deployment_output=$(az deployment sub create --name "${UNIQUER}-${BUILD_ID}" --template-file main.bicep --location "${LOCATION}" --parameters uniquer=${UNIQUER})
|
||||
else
|
||||
_deployment_output=$(az deployment sub create --name "${BUILD_ID}" --template-file main.bicep --location "${LOCATION}")
|
||||
fi
|
||||
|
||||
echo "${_deployment_output}"
|
||||
}
|
||||
|
||||
test_deploy() {
|
||||
local _hostnames="${1}"
|
||||
|
||||
sleep 30
|
||||
pwsh -Command ./smokeTest.ps1 -HostNames "${_hostnames}"
|
||||
}
|
||||
|
||||
azure_login
|
||||
|
||||
lint_bicep
|
||||
validate_bicep
|
||||
preview_bicep
|
||||
deployment_output=$(deploy_bicep)
|
||||
echo "${deployment_output}"
|
||||
# hostnames=$(echo "${deployment_output}" | jq -r -c '.properties.outputs | map(.value) | join(",")')
|
||||
# test_deploy "${hostnames}"
|
||||
|
||||
azure_logout
|
||||
|
||||
echo "Build ID: ${BUILD_ID}"
|
22
iac/bicep/dockerbuild.sh
Normal file
22
iac/bicep/dockerbuild.sh
Normal file
@ -0,0 +1,22 @@
|
||||
#!/bin/bash
|
||||
|
||||
cd ~/
|
||||
git clone "${TEAM_REPO}" --branch "${TEAM_REPO_BRANCH}" ~/openhack
|
||||
|
||||
cd ~/openhack/support/simulator
|
||||
az acr build --image devopsoh/simulator:latest --registry "${CONTAINER_REGISTRY}" --file Dockerfile . 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/simulator.txt"
|
||||
|
||||
cd ~/openhack/support/tripviewer
|
||||
az acr build --image devopsoh/tripviewer:latest --registry ${CONTAINER_REGISTRY} --file Dockerfile . 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/tripviewer.txt"
|
||||
|
||||
cd ~/openhack/apis/poi/web
|
||||
az acr build --image devopsoh/api-poi:${BASE_IMAGE_TAG} --registry ${CONTAINER_REGISTRY} --build-arg build_version=${BASE_IMAGE_TAG} --file Dockerfile . 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/poi.txt"
|
||||
|
||||
cd ~/openhack/apis/trips
|
||||
az acr build --image devopsoh/api-trips:${BASE_IMAGE_TAG} --registry ${CONTAINER_REGISTRY} --build-arg build_version=${BASE_IMAGE_TAG} --file Dockerfile . 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/trips.txt"
|
||||
|
||||
cd ~/openhack/apis/user-java
|
||||
az acr build --image devopsoh/api-user-java:${BASE_IMAGE_TAG} --registry ${CONTAINER_REGISTRY} --build-arg build_version=${BASE_IMAGE_TAG} --file Dockerfile . 2>&1 | tee "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/userjava.txt"
|
||||
|
||||
cd ~/openhack/apis/userprofile
|
||||
az acr build --image devopsoh/api-userprofile:${BASE_IMAGE_TAG} --registry ${CONTAINER_REGISTRY} --build-arg build_version=${BASE_IMAGE_TAG} --file Dockerfile . > "${AZ_SCRIPTS_PATH_OUTPUT_DIRECTORY}/userprofile.txt"
|
55
iac/bicep/keyVault.bicep
Normal file
55
iac/bicep/keyVault.bicep
Normal file
@ -0,0 +1,55 @@
|
||||
// Key Vault bootstap for further challenges - not used in the beginning.
|
||||
param resourcesPrefix string
|
||||
param location string = resourceGroup().location
|
||||
param sqlServerAdminLogin string
|
||||
param sqlServerId string
|
||||
@secure()
|
||||
param sqlServerAdminPassword string
|
||||
@secure()
|
||||
param containerRegistryAdminPassword string
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.keyvault/vaults?tabs=bicep
|
||||
resource keyVault 'Microsoft.KeyVault/vaults@2021-06-01-preview' = {
|
||||
name: '${resourcesPrefix}kv'
|
||||
location: location
|
||||
|
||||
properties: {
|
||||
sku: {
|
||||
name: 'standard'
|
||||
family: 'A'
|
||||
}
|
||||
tenantId: subscription().tenantId
|
||||
|
||||
accessPolicies: []
|
||||
softDeleteRetentionInDays: 7
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.keyvault/vaults/secrets?tabs=bicep
|
||||
resource sqlPassword 'Microsoft.KeyVault/vaults/secrets@2021-06-01-preview' = {
|
||||
parent: keyVault
|
||||
name: 'SQL-PASSWORD'
|
||||
tags: {
|
||||
CredentialId: sqlServerAdminLogin
|
||||
ProviderAddress: sqlServerId
|
||||
ValidityPeriodDays: '60'
|
||||
}
|
||||
properties: {
|
||||
attributes: {
|
||||
enabled: true
|
||||
//exp: '' // needs to be int - timestamp in seconds
|
||||
}
|
||||
value: sqlServerAdminPassword
|
||||
}
|
||||
}
|
||||
|
||||
resource dockerRegistryServerPassword 'Microsoft.KeyVault/vaults/secrets@2021-06-01-preview' = {
|
||||
parent: keyVault
|
||||
name: 'DOCKER-REGISTRY-SERVER-PASSWORD'
|
||||
|
||||
properties: {
|
||||
value: containerRegistryAdminPassword
|
||||
}
|
||||
}
|
||||
|
||||
output name string = keyVault.name
|
85
iac/bicep/logAnalytics.bicep
Normal file
85
iac/bicep/logAnalytics.bicep
Normal file
@ -0,0 +1,85 @@
|
||||
param resourcesPrefix string
|
||||
var location = resourceGroup().location
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.operationalinsights/workspaces?tabs=bicep
|
||||
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' = {
|
||||
name: '${resourcesPrefix}log'
|
||||
location: location
|
||||
|
||||
properties: {
|
||||
sku: {
|
||||
name: 'PerGB2018'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.operationsmanagement/solutions?tabs=bicep
|
||||
resource logAnalyticsSolutionContainers 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = {
|
||||
name: 'Containers(${logAnalyticsWorkspace.name})'
|
||||
location: location
|
||||
|
||||
plan: {
|
||||
name: 'Containers(${logAnalyticsWorkspace.name})'
|
||||
product: 'OMSGallery/Containers'
|
||||
publisher: 'Microsoft'
|
||||
promotionCode: '' // this is ignored, but has to be present
|
||||
}
|
||||
|
||||
properties: {
|
||||
workspaceResourceId: logAnalyticsWorkspace.id
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.operationsmanagement/solutions?tabs=bicep
|
||||
resource logAnalyticsSolutionSQLAssessment 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = {
|
||||
name: 'SQLAssessment(${logAnalyticsWorkspace.name})'
|
||||
location: location
|
||||
|
||||
plan: {
|
||||
name: 'SQLAssessment(${logAnalyticsWorkspace.name})'
|
||||
product: 'OMSGallery/SQLAssessment'
|
||||
publisher: 'Microsoft'
|
||||
promotionCode: '' // this is ignored, but has to be present
|
||||
}
|
||||
|
||||
properties: {
|
||||
workspaceResourceId: logAnalyticsWorkspace.id
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.operationsmanagement/solutions?tabs=bicep
|
||||
resource logAnalyticsSolutionAzureSQLAnalytics 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = {
|
||||
name: 'AzureSQLAnalytics(${logAnalyticsWorkspace.name})'
|
||||
location: location
|
||||
|
||||
plan: {
|
||||
name: 'AzureSQLAnalytics(${logAnalyticsWorkspace.name})'
|
||||
product: 'OMSGallery/AzureSQLAnalytics'
|
||||
publisher: 'Microsoft'
|
||||
promotionCode: '' // this is ignored, but has to be present
|
||||
}
|
||||
|
||||
properties: {
|
||||
workspaceResourceId: logAnalyticsWorkspace.id
|
||||
}
|
||||
}
|
||||
|
||||
// resource logAnalyticsSolutionContainerInsights 'Microsoft.OperationsManagement/solutions@2015-11-01-preview' = {
|
||||
// name: 'ContainerInsights(${logAnalyticsWorkspace.name})'
|
||||
// location: location
|
||||
|
||||
// plan: {
|
||||
// name: 'ContainerInsights(${logAnalyticsWorkspace.name})'
|
||||
// product: 'OMSGallery/ContainerInsights'
|
||||
// publisher: 'Microsoft'
|
||||
// promotionCode: '' // this is ignored, but has to be present
|
||||
// }
|
||||
|
||||
// properties: {
|
||||
// workspaceResourceId: logAnalyticsWorkspace.id
|
||||
// }
|
||||
// }
|
||||
|
||||
output logAnalyticsWorkspaceName string = logAnalyticsWorkspace.name
|
||||
output logAnalyticsWorkspaceId string = logAnalyticsWorkspace.properties.customerId
|
||||
output logAnalyticsWorkspaceKey string = logAnalyticsWorkspace.listKeys().primarySharedKey
|
193
iac/bicep/main.bicep
Normal file
193
iac/bicep/main.bicep
Normal file
@ -0,0 +1,193 @@
|
||||
targetScope = 'subscription'
|
||||
|
||||
param uniquer string = uniqueString(newGuid())
|
||||
param location string = deployment().location
|
||||
param resourcesPrefix string = ''
|
||||
param apiPoiBaseImageTag string = ''
|
||||
param apiTripsBaseImageTag string = ''
|
||||
param apiUserJavaBaseImageTag string = ''
|
||||
param apiUserprofileBaseImageTag string = ''
|
||||
param sqlServerAdminPassword string = ''
|
||||
|
||||
var varfile = json(loadTextContent('./variables.json'))
|
||||
var resourcesPrefixCalculated = empty(resourcesPrefix) ? '${varfile.namePrefix}${uniquer}' : resourcesPrefix
|
||||
var resourceGroupName = '${resourcesPrefixCalculated}rg'
|
||||
|
||||
var apiPoiBaseImageTagCalculated = empty(apiPoiBaseImageTag) ? varfile.baseImageTag : apiPoiBaseImageTag
|
||||
var apiTripsBaseImageTagCalculated = empty(apiTripsBaseImageTag) ? varfile.baseImageTag : apiTripsBaseImageTag
|
||||
var apiUserJavaBaseImageTagCalculated = empty(apiUserJavaBaseImageTag) ? varfile.baseImageTag : apiUserJavaBaseImageTag
|
||||
var apiUserprofileBaseImageTagCalculated = empty(apiUserprofileBaseImageTag) ? varfile.baseImageTag : apiUserprofileBaseImageTag
|
||||
|
||||
var sqlServerAdminPasswordCalculated = empty(sqlServerAdminPassword) ? varfile.sqlServerAdminPassword : sqlServerAdminPassword
|
||||
|
||||
module openhackResourceGroup './resourceGroup.bicep' = {
|
||||
name: '${resourcesPrefixCalculated}-resourceGroupDeployment'
|
||||
params: {
|
||||
resourceGroupName: resourceGroupName
|
||||
location: location
|
||||
}
|
||||
}
|
||||
|
||||
module managedIdentity './managedIdentity.bicep' = {
|
||||
name: 'managedIdentityDeployment'
|
||||
params: {
|
||||
resourcesPrefix: resourcesPrefixCalculated
|
||||
}
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [
|
||||
openhackResourceGroup
|
||||
]
|
||||
}
|
||||
|
||||
module containerRegistry './containerRegistry.bicep' = {
|
||||
name: 'containerRegistryDeployment'
|
||||
params: {
|
||||
resourcesPrefix: resourcesPrefixCalculated
|
||||
}
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [
|
||||
openhackResourceGroup
|
||||
managedIdentity
|
||||
]
|
||||
}
|
||||
|
||||
module sqlServer './sqlServer.bicep' = {
|
||||
name: 'sqlServerDeployment'
|
||||
params: {
|
||||
resourcesPrefix: resourcesPrefixCalculated
|
||||
sqlServerAdminPassword: sqlServerAdminPasswordCalculated
|
||||
logAnalyticsWorkspaceName: logAnalytics.outputs.logAnalyticsWorkspaceName
|
||||
}
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [
|
||||
openhackResourceGroup
|
||||
managedIdentity
|
||||
logAnalytics
|
||||
]
|
||||
}
|
||||
|
||||
module appInsights './appInsights.bicep' = {
|
||||
name: 'appInsightsDeployment'
|
||||
params: {
|
||||
resourcesPrefix: resourcesPrefixCalculated
|
||||
}
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [
|
||||
openhackResourceGroup
|
||||
]
|
||||
}
|
||||
|
||||
module appService './appService.bicep' = {
|
||||
name: 'appServiceDeployment'
|
||||
params: {
|
||||
resourcesPrefix: resourcesPrefixCalculated
|
||||
sqlServerFqdn: sqlServer.outputs.sqlServerFqdn
|
||||
sqlServerAdminLogin: sqlServer.outputs.sqlServerAdminLogin
|
||||
sqlServerAdminPassword: sqlServerAdminPasswordCalculated
|
||||
sqlDatabaseName: sqlServer.outputs.sqlDatabaseName
|
||||
containerRegistryLoginServer: containerRegistry.outputs.containerRegistryLoginServer
|
||||
containerRegistryName: containerRegistry.outputs.containerRegistryName
|
||||
// userAssignedManagedIdentityId: managedIdentity.outputs.userAssignedManagedIdentityId
|
||||
// userAssignedManagedIdentityPrincipalId: managedIdentity.outputs.userAssignedManagedIdentityPrincipalId
|
||||
containerRegistryAdminUsername: containerRegistry.outputs.containerRegistryAdminUsername
|
||||
containerRegistryAdminPassword: containerRegistry.outputs.containerRegistryAdminPassword
|
||||
keyVaultName: keyVault.outputs.name
|
||||
appInsightsInstrumentationKey: appInsights.outputs.appInsightsInstrumentationKey
|
||||
appInsightsConnectionString: appInsights.outputs.appInsightsConnectionString
|
||||
appInsightsStagingInstrumentationKey: appInsights.outputs.appInsightsStagingInstrumentationKey
|
||||
appInsightsStagingConnectionString: appInsights.outputs.appInsightsStagingConnectionString
|
||||
apiPoiBaseImageTag: apiPoiBaseImageTagCalculated
|
||||
apiTripsBaseImageTag: apiTripsBaseImageTagCalculated
|
||||
apiUserJavaBaseImageTag: apiUserJavaBaseImageTagCalculated
|
||||
apiUserprofileBaseImageTag: apiUserprofileBaseImageTagCalculated
|
||||
}
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [
|
||||
containerRegistry
|
||||
sqlServer
|
||||
apps
|
||||
appInsights
|
||||
]
|
||||
}
|
||||
|
||||
module apps './apps.bicep' = {
|
||||
name: 'appsDeployment'
|
||||
params: {
|
||||
resourcesPrefix: resourcesPrefixCalculated
|
||||
sqlServerFqdn: sqlServer.outputs.sqlServerFqdn
|
||||
sqlServerName: sqlServer.outputs.sqlServerName
|
||||
sqlServerAdminPassword: sqlServerAdminPasswordCalculated
|
||||
containerRegistryLoginServer: containerRegistry.outputs.containerRegistryLoginServer
|
||||
containerRegistryName: containerRegistry.outputs.containerRegistryName
|
||||
userAssignedManagedIdentityId: managedIdentity.outputs.userAssignedManagedIdentityId
|
||||
userAssignedManagedIdentityPrincipalId: managedIdentity.outputs.userAssignedManagedIdentityPrincipalId
|
||||
}
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [
|
||||
sqlServer
|
||||
containerRegistry
|
||||
managedIdentity
|
||||
]
|
||||
}
|
||||
|
||||
module logAnalytics './logAnalytics.bicep' = {
|
||||
name: 'logAnalyticsDeployment'
|
||||
params: {
|
||||
resourcesPrefix: resourcesPrefixCalculated
|
||||
}
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [
|
||||
openhackResourceGroup
|
||||
]
|
||||
}
|
||||
|
||||
module containerGroup './containerGroup.bicep' = {
|
||||
name: 'containerGroupDeployment'
|
||||
params: {
|
||||
resourcesPrefix: resourcesPrefixCalculated
|
||||
sqlServerFqdn: sqlServer.outputs.sqlServerFqdn
|
||||
sqlServerAdminLogin: sqlServer.outputs.sqlServerAdminLogin
|
||||
sqlServerAdminPassword: sqlServerAdminPasswordCalculated
|
||||
sqlDatabaseName: sqlServer.outputs.sqlDatabaseName
|
||||
containerRegistryLoginServer: containerRegistry.outputs.containerRegistryLoginServer
|
||||
// containerRegistryName: containerRegistry.outputs.containerRegistryName
|
||||
containerRegistryAdminUsername: containerRegistry.outputs.containerRegistryAdminUsername
|
||||
containerRegistryAdminPassword: containerRegistry.outputs.containerRegistryAdminPassword
|
||||
appServiceApiPoiHostname: appService.outputs.appServiceApiPoiHostname
|
||||
appServiceApiTripsHostname: appService.outputs.appServiceApiTripsHostname
|
||||
appServiceApiUserJavaHostname: appService.outputs.appServiceApiUserJavaHostname
|
||||
appServiceApiUserprofileHostname: appService.outputs.appServiceApiUserprofileHostname
|
||||
logAnalyticsWorkspaceId: logAnalytics.outputs.logAnalyticsWorkspaceId
|
||||
logAnalyticsWorkspaceKey: logAnalytics.outputs.logAnalyticsWorkspaceKey
|
||||
// userAssignedManagedIdentityId: managedIdentity.outputs.userAssignedManagedIdentityId
|
||||
// userAssignedManagedIdentityPrincipalId: managedIdentity.outputs.userAssignedManagedIdentityPrincipalId
|
||||
}
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [
|
||||
containerRegistry
|
||||
sqlServer
|
||||
appService
|
||||
apps
|
||||
logAnalytics
|
||||
]
|
||||
}
|
||||
|
||||
module keyVault './keyVault.bicep' = {
|
||||
name: 'keyVaultDeployment'
|
||||
params: {
|
||||
resourcesPrefix: resourcesPrefixCalculated
|
||||
containerRegistryAdminPassword: containerRegistry.outputs.containerRegistryAdminPassword
|
||||
sqlServerAdminLogin: sqlServer.outputs.sqlServerAdminLogin
|
||||
sqlServerAdminPassword: sqlServerAdminPasswordCalculated
|
||||
sqlServerId: sqlServer.outputs.sqlServerId
|
||||
}
|
||||
scope: resourceGroup(resourceGroupName)
|
||||
dependsOn: [
|
||||
openhackResourceGroup
|
||||
]
|
||||
}
|
||||
|
||||
output appServiceApiPoiHealthcheck string = '${appService.outputs.appServiceApiPoiHostname}/api/healthcheck/poi'
|
||||
output appServiceApiTripsHealthcheck string = '${appService.outputs.appServiceApiTripsHostname}/api/healthcheck/trips'
|
||||
output appServiceApiUserJavaHealthcheck string = '${appService.outputs.appServiceApiUserJavaHostname}/api/healthcheck/user-java'
|
||||
output appServiceApiUserprofileHealthcheck string = '${appService.outputs.appServiceApiUserprofileHostname}/api/healthcheck/user'
|
12
iac/bicep/managedIdentity.bicep
Normal file
12
iac/bicep/managedIdentity.bicep
Normal file
@ -0,0 +1,12 @@
|
||||
param resourcesPrefix string
|
||||
|
||||
var location = resourceGroup().location
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.managedidentity/userassignedidentities?tabs=bicep
|
||||
resource userAssignedManagedIdentity 'Microsoft.ManagedIdentity/userAssignedIdentities@2018-11-30' = {
|
||||
name: '${resourcesPrefix}uami'
|
||||
location: location
|
||||
}
|
||||
|
||||
output userAssignedManagedIdentityId string = userAssignedManagedIdentity.id
|
||||
output userAssignedManagedIdentityPrincipalId string = userAssignedManagedIdentity.properties.principalId
|
10
iac/bicep/resourceGroup.bicep
Normal file
10
iac/bicep/resourceGroup.bicep
Normal file
@ -0,0 +1,10 @@
|
||||
targetScope = 'subscription'
|
||||
|
||||
param resourceGroupName string
|
||||
param location string
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.resources/resourcegroups?tabs=bicep
|
||||
resource resourceGroup 'Microsoft.Resources/resourceGroups@2021-04-01' = {
|
||||
name: resourceGroupName
|
||||
location: location
|
||||
}
|
31
iac/bicep/smokeTest.ps1
Normal file
31
iac/bicep/smokeTest.ps1
Normal file
@ -0,0 +1,31 @@
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string[]] $HostNames = @()
|
||||
)
|
||||
|
||||
if (!(Get-Module -Name Pester)) {
|
||||
Write-Host "Pester module does not exist. Installing ..."
|
||||
try {
|
||||
Install-Module Pester -AllowClobber -Force -Confirm:$False -SkipPublisherCheck
|
||||
}
|
||||
catch [Exception] {
|
||||
$_.message
|
||||
exit
|
||||
}
|
||||
}
|
||||
Import-Module Pester
|
||||
|
||||
$container = New-PesterContainer `
|
||||
-Path 'appService.Test.ps1' `
|
||||
-Data @{ HostNames = $HostNames }
|
||||
|
||||
$config = New-PesterConfiguration
|
||||
$config.Run.PassThru = $true
|
||||
$config.Run.Container = $container
|
||||
$config.TestResult.Enabled = $true
|
||||
$config.TestResult.OutputFormat = 'NUnitXml'
|
||||
$config.TestResult.OutputPath = 'testResultsNunit.xml'
|
||||
|
||||
$p = Invoke-Pester -Configuration $config
|
||||
$p | Export-JUnitReport -Path 'testResultsJunit.xml'
|
120
iac/bicep/sqlServer.bicep
Normal file
120
iac/bicep/sqlServer.bicep
Normal file
@ -0,0 +1,120 @@
|
||||
param resourcesPrefix string
|
||||
param logAnalyticsWorkspaceName string
|
||||
param sqlServerAdminPassword string
|
||||
|
||||
var location = resourceGroup().location
|
||||
var varfile = json(loadTextContent('./variables.json'))
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.sql/servers?tabs=bicep
|
||||
resource sqlServer 'Microsoft.Sql/servers@2021-05-01-preview' = {
|
||||
name: '${resourcesPrefix}sql'
|
||||
location: location
|
||||
properties: {
|
||||
administratorLogin: varfile.sqlServerAdminLogin
|
||||
administratorLoginPassword: sqlServerAdminPassword
|
||||
minimalTlsVersion: '1.2'
|
||||
version: '12.0'
|
||||
}
|
||||
}
|
||||
|
||||
resource sqlFirewallRuleAzure 'Microsoft.Sql/servers/firewallRules@2021-05-01-preview' = {
|
||||
parent: sqlServer
|
||||
name: 'AzureAccess'
|
||||
properties: {
|
||||
endIpAddress: '0.0.0.0'
|
||||
startIpAddress: '0.0.0.0'
|
||||
}
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.sql/servers/databases?tabs=bicep
|
||||
resource sqlDatabase 'Microsoft.Sql/servers/databases@2021-05-01-preview' = {
|
||||
parent: sqlServer
|
||||
name: 'mydrivingDB'
|
||||
location: location
|
||||
sku: {
|
||||
name: 'S0'
|
||||
}
|
||||
properties: {
|
||||
collation: 'SQL_Latin1_General_CP1_CI_AS'
|
||||
}
|
||||
}
|
||||
|
||||
resource logAnalyticsWorkspace 'Microsoft.OperationalInsights/workspaces@2021-06-01' existing = {
|
||||
name: logAnalyticsWorkspaceName
|
||||
}
|
||||
|
||||
// https://docs.microsoft.com/en-us/azure/azure-monitor/essentials/resource-manager-diagnostic-settings#diagnostic-setting-for-azure-sql-database
|
||||
// https://docs.microsoft.com/en-us/azure/templates/microsoft.insights/diagnosticsettings?tabs=bicep
|
||||
resource sqlDatabaseDiagnostic 'microsoft.insights/diagnosticSettings@2021-05-01-preview' = {
|
||||
name: 'sqlDbDiag'
|
||||
scope: sqlDatabase
|
||||
properties: {
|
||||
workspaceId: logAnalyticsWorkspace.id
|
||||
logs: [
|
||||
{
|
||||
category: 'SQLInsights'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'AutomaticTuning'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'QueryStoreRuntimeStatistics'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'QueryStoreWaitStatistics'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'Errors'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'DatabaseWaitStatistics'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'Timeouts'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'Blocks'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'Deadlocks'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'DevOpsOperationsAudit'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'SQLSecurityAuditEvents'
|
||||
enabled: true
|
||||
}
|
||||
]
|
||||
metrics: [
|
||||
{
|
||||
category: 'Basic'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'InstanceAndAppAdvanced'
|
||||
enabled: true
|
||||
}
|
||||
{
|
||||
category: 'WorkloadManagement'
|
||||
enabled: true
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
output sqlServerAdminLogin string = varfile.sqlServerAdminLogin
|
||||
output sqlServerFqdn string = sqlServer.properties.fullyQualifiedDomainName
|
||||
output sqlDatabaseName string = sqlDatabase.name
|
||||
output sqlServerName string = sqlServer.name
|
||||
output sqlServerId string = sqlServer.id
|
9
iac/bicep/variables.json
Normal file
9
iac/bicep/variables.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"namePrefix": "devopsoh",
|
||||
"baseImageTag": "changeme",
|
||||
"bingMapsKey": "Ar6iuHZYgX1BrfJs6SRJaXWbpU_HKdoe7G-OO9b2kl3rWvcawYx235GGx5FPM76O",
|
||||
"sqlServerAdminLogin": "demousersa",
|
||||
"sqlServerAdminPassword": "demo!P@55w0rd123",
|
||||
"publicTeamRepo": "https://github.com/Microsoft-OpenHack/devops-artifacts",
|
||||
"publicTeamRepoBranch": "main"
|
||||
}
|
35
iac/terraform/appService.Test.ps1
Normal file
35
iac/terraform/appService.Test.ps1
Normal file
@ -0,0 +1,35 @@
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string[]] $HostNames
|
||||
)
|
||||
|
||||
$TestCases = @()
|
||||
|
||||
$HostNames.ForEach{ $TestCases += @{HostName = $_ } }
|
||||
Describe 'Testing connection to Websites' {
|
||||
|
||||
It ' <HostName> over HTTPS' -ForEach $TestCases {
|
||||
try {
|
||||
$request = [System.Net.WebRequest]::Create("https://$HostName")
|
||||
$request.AllowAutoRedirect = $false
|
||||
$statusCode = [int]$request.GetResponse().StatusCode
|
||||
}
|
||||
catch [System.Net.WebException] {
|
||||
$statusCode = [int]$_.Exception.Response.StatusCode
|
||||
}
|
||||
$statusCode | Should -BeIn @(200, 404) -Because "the website requires HTTPS"
|
||||
}
|
||||
|
||||
It ' <HostName> over HTTP' -ForEach $TestCases {
|
||||
try {
|
||||
$request = [System.Net.WebRequest]::Create("http://$HostName")
|
||||
$request.AllowAutoRedirect = $false
|
||||
$statusCode = [int]$request.GetResponse().StatusCode
|
||||
}
|
||||
catch [System.Net.WebException] {
|
||||
$statusCode = [int]$_.Exception.Response.StatusCode
|
||||
}
|
||||
$statusCode | Should -BeIn (300..399) -Because "HTTP is not secure"
|
||||
}
|
||||
}
|
73
iac/terraform/apps.tf
Normal file
73
iac/terraform/apps.tf
Normal file
@ -0,0 +1,73 @@
|
||||
############################################
|
||||
## DATABASE ##
|
||||
############################################
|
||||
|
||||
resource "null_resource" "db_schema" {
|
||||
depends_on = [
|
||||
azurerm_mssql_database.mssql_database
|
||||
]
|
||||
provisioner "local-exec" {
|
||||
command = "sqlcmd -U ${local.mssql_server_administrator_login} -P ${local.mssql_server_administrator_login_password} -S ${azurerm_mssql_server.mssql_server.fully_qualified_domain_name} -d ${local.mssql_database_name} -i ../../support/datainit/MYDrivingDB.sql -e"
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "db_datainit" {
|
||||
depends_on = [
|
||||
null_resource.db_schema
|
||||
]
|
||||
provisioner "local-exec" {
|
||||
command = "cd ../../support/datainit; bash ./sql_data_init.sh -s ${azurerm_mssql_server.mssql_server.fully_qualified_domain_name} -u ${local.mssql_server_administrator_login} -p ${local.mssql_server_administrator_login_password} -d ${local.mssql_database_name}; cd ../../iac/terraform"
|
||||
}
|
||||
}
|
||||
|
||||
############################################
|
||||
## DOCKER for test ##
|
||||
############################################
|
||||
|
||||
resource "null_resource" "docker_simulator" {
|
||||
depends_on = [
|
||||
azurerm_container_registry.container_registry
|
||||
]
|
||||
provisioner "local-exec" {
|
||||
command = "az acr build --image devopsoh/simulator:latest --registry ${azurerm_container_registry.container_registry.login_server} --file ../../support/simulator/Dockerfile ../../support/simulator"
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "docker_tripviewer" {
|
||||
provisioner "local-exec" {
|
||||
command = "az acr build --image devopsoh/tripviewer:latest --registry ${azurerm_container_registry.container_registry.login_server} --file ../../support/tripviewer/Dockerfile ../../support/tripviewer"
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "docker_api-poi" {
|
||||
provisioner "local-exec" {
|
||||
command = "az acr build --image devopsoh/api-poi:${local.apipoi_base_image_tag} --registry ${azurerm_container_registry.container_registry.login_server} --build-arg build_version=${local.apipoi_base_image_tag} --file ../../apis/poi/web/Dockerfile ../../apis/poi/web"
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "docker_api-trips" {
|
||||
provisioner "local-exec" {
|
||||
command = "az acr build --image devopsoh/api-trips:${local.apitrips_base_image_tag} --registry ${azurerm_container_registry.container_registry.login_server} --build-arg build_version=${local.apitrips_base_image_tag} --file ../../apis/trips/Dockerfile ../../apis/trips"
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "docker_api-user-java" {
|
||||
provisioner "local-exec" {
|
||||
command = "az acr build --image devopsoh/api-user-java:${local.apiuserjava_base_image_tag} --registry ${azurerm_container_registry.container_registry.login_server} --build-arg build_version=${local.apiuserjava_base_image_tag} --file ../../apis/user-java/Dockerfile ../../apis/user-java"
|
||||
}
|
||||
}
|
||||
|
||||
resource "null_resource" "docker_api-userprofile" {
|
||||
provisioner "local-exec" {
|
||||
command = "az acr build --image devopsoh/api-userprofile:${local.apiuserprofile_base_image_tag} --registry ${azurerm_container_registry.container_registry.login_server} --build-arg build_version=${local.apiuserprofile_base_image_tag} --file ../../apis/userprofile/Dockerfile ../../apis/userprofile"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
143
iac/terraform/appservice_poi.tf
Normal file
143
iac/terraform/appservice_poi.tf
Normal file
@ -0,0 +1,143 @@
|
||||
############################################
|
||||
## APP SERVICE - API-POI ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_app_service" "app_service_api-poi" {
|
||||
depends_on = [
|
||||
null_resource.db_datainit,
|
||||
null_resource.docker_api-poi
|
||||
]
|
||||
name = local.app_service_api-poi_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
https_only = true
|
||||
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
app_settings = {
|
||||
"SQL_USER" = local.mssql_server_administrator_login
|
||||
"SQL_PASSWORD" = local.mssql_server_administrator_login_password
|
||||
# "SQL_PASSWORD" = "@Microsoft.KeyVault(VaultName=${azurerm_key_vault.key_vault.name};SecretName=${azurerm_key_vault_secret.key_vault_secret_sqlpassword.name})"
|
||||
"SQL_SERVER" = azurerm_mssql_server.mssql_server.fully_qualified_domain_name
|
||||
"SQL_DBNAME" = local.mssql_database_name
|
||||
"WEBSITES_PORT" = "8080"
|
||||
"DOCKER_REGISTRY_SERVER_URL" = local.docker_registry_server_url
|
||||
"DOCKER_REGISTRY_SERVER_USERNAME" = local.docker_registry_server_username
|
||||
"DOCKER_REGISTRY_SERVER_PASSWORD" = local.docker_registry_server_password
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights.instrumentation_key
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.application_insights.connection_string
|
||||
}
|
||||
|
||||
site_config {
|
||||
always_on = true
|
||||
http2_enabled = true
|
||||
ftps_state = "Disabled"
|
||||
health_check_path = "/api/healthcheck/poi"
|
||||
# acr_use_managed_identity_credentials = true
|
||||
linux_fx_version = "DOCKER|${azurerm_container_registry.container_registry.login_server}/devopsoh/api-poi:${local.apipoi_base_image_tag}"
|
||||
}
|
||||
|
||||
logs {
|
||||
http_logs {
|
||||
file_system {
|
||||
retention_in_days = 7
|
||||
retention_in_mb = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"],
|
||||
site_config[0].linux_fx_version
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_key_vault_access_policy" "key_vault_access_policy_api-poi" {
|
||||
# key_vault_id = azurerm_key_vault.key_vault.id
|
||||
# tenant_id = azurerm_app_service.app_service_api-poi.identity[0].tenant_id
|
||||
# object_id = azurerm_app_service.app_service_api-poi.identity[0].principal_id
|
||||
#
|
||||
# secret_permissions = [
|
||||
# "Get"
|
||||
# ]
|
||||
# }
|
||||
|
||||
# resource "azurerm_role_assignment" "cr_role_assignment_api-poi" {
|
||||
# scope = azurerm_container_registry.container_registry.id
|
||||
# role_definition_name = "AcrPull"
|
||||
# principal_id = azurerm_app_service.app_service_api-poi.identity[0].principal_id
|
||||
# }
|
||||
|
||||
resource "azurerm_app_service_slot" "app_service_api-poi_staging" {
|
||||
name = "staging"
|
||||
app_service_name = azurerm_app_service.app_service_api-poi.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
https_only = true
|
||||
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
app_settings = {
|
||||
"SQL_USER" = local.mssql_server_administrator_login
|
||||
"SQL_PASSWORD" = local.mssql_server_administrator_login_password
|
||||
"SQL_SERVER" = azurerm_mssql_server.mssql_server.fully_qualified_domain_name
|
||||
"SQL_DBNAME" = local.mssql_database_name
|
||||
"WEBSITES_PORT" = "8080"
|
||||
"DOCKER_REGISTRY_SERVER_URL" = local.docker_registry_server_url
|
||||
"DOCKER_REGISTRY_SERVER_USERNAME" = local.docker_registry_server_username
|
||||
"DOCKER_REGISTRY_SERVER_PASSWORD" = local.docker_registry_server_password
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights_staging.instrumentation_key
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.application_insights_staging.connection_string
|
||||
}
|
||||
|
||||
site_config {
|
||||
always_on = true
|
||||
http2_enabled = true
|
||||
ftps_state = "Disabled"
|
||||
health_check_path = "/api/healthcheck/poi"
|
||||
# acr_use_managed_identity_credentials = true
|
||||
linux_fx_version = "DOCKER|${azurerm_container_registry.container_registry.login_server}/devopsoh/api-poi:${local.apipoi_base_image_tag}"
|
||||
}
|
||||
|
||||
logs {
|
||||
http_logs {
|
||||
file_system {
|
||||
retention_in_days = 7
|
||||
retention_in_mb = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"],
|
||||
site_config[0].linux_fx_version
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_key_vault_access_policy" "key_vault_access_policy_api-poi_staging" {
|
||||
# key_vault_id = azurerm_key_vault.key_vault.id
|
||||
# tenant_id = azurerm_app_service_slot.app_service_api-poi_staging.identity[0].tenant_id
|
||||
# object_id = azurerm_app_service_slot.app_service_api-poi_staging.identity[0].principal_id
|
||||
#
|
||||
# secret_permissions = [
|
||||
# "Get"
|
||||
# ]
|
||||
# }
|
||||
|
||||
# resource "azurerm_role_assignment" "cr_role_assignment_api-poi_staging" {
|
||||
# scope = azurerm_container_registry.container_registry.id
|
||||
# role_definition_name = "AcrPull"
|
||||
# principal_id = azurerm_app_service_slot.app_service_api-poi_staging.identity[0].principal_id
|
||||
# }
|
140
iac/terraform/appservice_trips.tf
Normal file
140
iac/terraform/appservice_trips.tf
Normal file
@ -0,0 +1,140 @@
|
||||
############################################
|
||||
## APP SERVICE - API-TRIPS ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_app_service" "app_service_api-trips" {
|
||||
depends_on = [
|
||||
null_resource.db_datainit,
|
||||
null_resource.docker_api-trips
|
||||
]
|
||||
name = local.app_service_api-trips_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
https_only = true
|
||||
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
app_settings = {
|
||||
"SQL_USER" = local.mssql_server_administrator_login
|
||||
"SQL_PASSWORD" = local.mssql_server_administrator_login_password
|
||||
"SQL_SERVER" = azurerm_mssql_server.mssql_server.fully_qualified_domain_name
|
||||
"SQL_DBNAME" = local.mssql_database_name
|
||||
"DOCKER_REGISTRY_SERVER_URL" = local.docker_registry_server_url
|
||||
"DOCKER_REGISTRY_SERVER_USERNAME" = local.docker_registry_server_username
|
||||
"DOCKER_REGISTRY_SERVER_PASSWORD" = local.docker_registry_server_password
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights.instrumentation_key
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.application_insights.connection_string
|
||||
}
|
||||
|
||||
site_config {
|
||||
always_on = true
|
||||
http2_enabled = true
|
||||
ftps_state = "Disabled"
|
||||
health_check_path = "/api/healthcheck/trips"
|
||||
# acr_use_managed_identity_credentials = true
|
||||
linux_fx_version = "DOCKER|${azurerm_container_registry.container_registry.login_server}/devopsoh/api-trips:${local.apitrips_base_image_tag}"
|
||||
}
|
||||
|
||||
logs {
|
||||
http_logs {
|
||||
file_system {
|
||||
retention_in_days = 7
|
||||
retention_in_mb = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"],
|
||||
site_config[0].linux_fx_version
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_key_vault_access_policy" "key_vault_access_policy_api-trips" {
|
||||
# key_vault_id = azurerm_key_vault.key_vault.id
|
||||
# tenant_id = azurerm_app_service.app_service_api-trips.identity[0].tenant_id
|
||||
# object_id = azurerm_app_service.app_service_api-trips.identity[0].principal_id
|
||||
#
|
||||
# secret_permissions = [
|
||||
# "Get"
|
||||
# ]
|
||||
# }
|
||||
|
||||
# resource "azurerm_role_assignment" "cr_role_assignment_api-trips" {
|
||||
# scope = azurerm_container_registry.container_registry.id
|
||||
# role_definition_name = "AcrPull"
|
||||
# principal_id = azurerm_app_service.app_service_api-trips.identity[0].principal_id
|
||||
# }
|
||||
|
||||
resource "azurerm_app_service_slot" "app_service_api-trips_staging" {
|
||||
name = "staging"
|
||||
app_service_name = azurerm_app_service.app_service_api-trips.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
https_only = true
|
||||
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
app_settings = {
|
||||
"SQL_USER" = local.mssql_server_administrator_login
|
||||
"SQL_PASSWORD" = local.mssql_server_administrator_login_password
|
||||
"SQL_SERVER" = azurerm_mssql_server.mssql_server.fully_qualified_domain_name
|
||||
"SQL_DBNAME" = local.mssql_database_name
|
||||
"DOCKER_REGISTRY_SERVER_URL" = local.docker_registry_server_url
|
||||
"DOCKER_REGISTRY_SERVER_USERNAME" = local.docker_registry_server_username
|
||||
"DOCKER_REGISTRY_SERVER_PASSWORD" = local.docker_registry_server_password
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights_staging.instrumentation_key
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.application_insights_staging.connection_string
|
||||
}
|
||||
|
||||
site_config {
|
||||
always_on = true
|
||||
http2_enabled = true
|
||||
ftps_state = "Disabled"
|
||||
health_check_path = "/api/healthcheck/trips"
|
||||
# acr_use_managed_identity_credentials = true
|
||||
linux_fx_version = "DOCKER|${azurerm_container_registry.container_registry.login_server}/devopsoh/api-trips:${local.apitrips_base_image_tag}"
|
||||
}
|
||||
|
||||
logs {
|
||||
http_logs {
|
||||
file_system {
|
||||
retention_in_days = 7
|
||||
retention_in_mb = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"],
|
||||
site_config[0].linux_fx_version
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_key_vault_access_policy" "key_vault_access_policy_api-trips_staging" {
|
||||
# key_vault_id = azurerm_key_vault.key_vault.id
|
||||
# tenant_id = azurerm_app_service_slot.app_service_api-trips_staging.identity[0].tenant_id
|
||||
# object_id = azurerm_app_service_slot.app_service_api-trips_staging.identity[0].principal_id
|
||||
#
|
||||
# secret_permissions = [
|
||||
# "Get"
|
||||
# ]
|
||||
# }
|
||||
|
||||
# resource "azurerm_role_assignment" "cr_role_assignment_api-trips_staging" {
|
||||
# scope = azurerm_container_registry.container_registry.id
|
||||
# role_definition_name = "AcrPull"
|
||||
# principal_id = azurerm_app_service_slot.app_service_api-trips_staging.identity[0].principal_id
|
||||
# }
|
140
iac/terraform/appservice_userjava.tf
Normal file
140
iac/terraform/appservice_userjava.tf
Normal file
@ -0,0 +1,140 @@
|
||||
############################################
|
||||
## APP SERVICE - API-USER-JAVA ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_app_service" "app_service_api-userjava" {
|
||||
depends_on = [
|
||||
null_resource.db_datainit,
|
||||
null_resource.docker_api-user-java
|
||||
]
|
||||
name = local.app_service_api-userjava_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
https_only = true
|
||||
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
app_settings = {
|
||||
"SQL_USER" = local.mssql_server_administrator_login
|
||||
"SQL_PASSWORD" = local.mssql_server_administrator_login_password
|
||||
"SQL_SERVER" = azurerm_mssql_server.mssql_server.fully_qualified_domain_name
|
||||
"SQL_DBNAME" = local.mssql_database_name
|
||||
"DOCKER_REGISTRY_SERVER_URL" = local.docker_registry_server_url
|
||||
"DOCKER_REGISTRY_SERVER_USERNAME" = local.docker_registry_server_username
|
||||
"DOCKER_REGISTRY_SERVER_PASSWORD" = local.docker_registry_server_password
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights.instrumentation_key
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.application_insights.connection_string
|
||||
}
|
||||
|
||||
site_config {
|
||||
always_on = true
|
||||
http2_enabled = true
|
||||
ftps_state = "Disabled"
|
||||
health_check_path = "/api/healthcheck/user-java"
|
||||
# acr_use_managed_identity_credentials = true
|
||||
linux_fx_version = "DOCKER|${azurerm_container_registry.container_registry.login_server}/devopsoh/api-user-java:${local.apiuserjava_base_image_tag}"
|
||||
}
|
||||
|
||||
logs {
|
||||
http_logs {
|
||||
file_system {
|
||||
retention_in_days = 7
|
||||
retention_in_mb = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"],
|
||||
site_config[0].linux_fx_version
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_key_vault_access_policy" "key_vault_access_policy_api-userjava" {
|
||||
# key_vault_id = azurerm_key_vault.key_vault.id
|
||||
# tenant_id = azurerm_app_service.app_service_api-userjava.identity[0].tenant_id
|
||||
# object_id = azurerm_app_service.app_service_api-userjava.identity[0].principal_id
|
||||
#
|
||||
# secret_permissions = [
|
||||
# "Get"
|
||||
# ]
|
||||
# }
|
||||
|
||||
# resource "azurerm_role_assignment" "cr_role_assignment_api-userjava" {
|
||||
# scope = azurerm_container_registry.container_registry.id
|
||||
# role_definition_name = "AcrPull"
|
||||
# principal_id = azurerm_app_service.app_service_api-userjava.identity[0].principal_id
|
||||
# }
|
||||
|
||||
resource "azurerm_app_service_slot" "app_service_api-userjava_staging" {
|
||||
name = "staging"
|
||||
app_service_name = azurerm_app_service.app_service_api-userjava.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
https_only = true
|
||||
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
app_settings = {
|
||||
"SQL_USER" = local.mssql_server_administrator_login
|
||||
"SQL_PASSWORD" = local.mssql_server_administrator_login_password
|
||||
"SQL_SERVER" = azurerm_mssql_server.mssql_server.fully_qualified_domain_name
|
||||
"SQL_DBNAME" = local.mssql_database_name
|
||||
"DOCKER_REGISTRY_SERVER_URL" = local.docker_registry_server_url
|
||||
"DOCKER_REGISTRY_SERVER_USERNAME" = local.docker_registry_server_username
|
||||
"DOCKER_REGISTRY_SERVER_PASSWORD" = local.docker_registry_server_password
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights_staging.instrumentation_key
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.application_insights_staging.connection_string
|
||||
}
|
||||
|
||||
site_config {
|
||||
always_on = true
|
||||
http2_enabled = true
|
||||
health_check_path = "/api/healthcheck/user-java"
|
||||
ftps_state = "Disabled"
|
||||
# acr_use_managed_identity_credentials = true
|
||||
linux_fx_version = "DOCKER|${azurerm_container_registry.container_registry.login_server}/devopsoh/api-user-java:${local.apiuserjava_base_image_tag}"
|
||||
}
|
||||
|
||||
logs {
|
||||
http_logs {
|
||||
file_system {
|
||||
retention_in_days = 7
|
||||
retention_in_mb = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"],
|
||||
site_config[0].linux_fx_version
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_key_vault_access_policy" "key_vault_access_policy_api-userjava_staging" {
|
||||
# key_vault_id = azurerm_key_vault.key_vault.id
|
||||
# tenant_id = azurerm_app_service_slot.app_service_api-userjava_staging.identity[0].tenant_id
|
||||
# object_id = azurerm_app_service_slot.app_service_api-userjava_staging.identity[0].principal_id
|
||||
#
|
||||
# secret_permissions = [
|
||||
# "Get"
|
||||
# ]
|
||||
# }
|
||||
|
||||
# resource "azurerm_role_assignment" "cr_role_assignment_api-userjava_staging" {
|
||||
# scope = azurerm_container_registry.container_registry.id
|
||||
# role_definition_name = "AcrPull"
|
||||
# principal_id = azurerm_app_service_slot.app_service_api-userjava_staging.identity[0].principal_id
|
||||
# }
|
140
iac/terraform/appservice_userprofile.tf
Normal file
140
iac/terraform/appservice_userprofile.tf
Normal file
@ -0,0 +1,140 @@
|
||||
############################################
|
||||
## APP SERVICE - API-USERPROFILE ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_app_service" "app_service_api-userprofile" {
|
||||
depends_on = [
|
||||
null_resource.db_datainit,
|
||||
null_resource.docker_api-userprofile
|
||||
]
|
||||
name = local.app_service_api-userprofile_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
https_only = true
|
||||
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
app_settings = {
|
||||
"SQL_USER" = local.mssql_server_administrator_login
|
||||
"SQL_PASSWORD" = local.mssql_server_administrator_login_password
|
||||
"SQL_SERVER" = azurerm_mssql_server.mssql_server.fully_qualified_domain_name
|
||||
"SQL_DBNAME" = local.mssql_database_name
|
||||
"DOCKER_REGISTRY_SERVER_URL" = local.docker_registry_server_url
|
||||
"DOCKER_REGISTRY_SERVER_USERNAME" = local.docker_registry_server_username
|
||||
"DOCKER_REGISTRY_SERVER_PASSWORD" = local.docker_registry_server_password
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights.instrumentation_key
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.application_insights.connection_string
|
||||
}
|
||||
|
||||
site_config {
|
||||
always_on = true
|
||||
http2_enabled = true
|
||||
health_check_path = "/api/healthcheck/user"
|
||||
ftps_state = "Disabled"
|
||||
# acr_use_managed_identity_credentials = true
|
||||
linux_fx_version = "DOCKER|${azurerm_container_registry.container_registry.login_server}/devopsoh/api-userprofile:${local.apiuserprofile_base_image_tag}"
|
||||
}
|
||||
|
||||
logs {
|
||||
http_logs {
|
||||
file_system {
|
||||
retention_in_days = 7
|
||||
retention_in_mb = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"],
|
||||
site_config[0].linux_fx_version
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_key_vault_access_policy" "key_vault_access_policy_api-userprofile" {
|
||||
# key_vault_id = azurerm_key_vault.key_vault.id
|
||||
# tenant_id = azurerm_app_service.app_service_api-userprofile.identity[0].tenant_id
|
||||
# object_id = azurerm_app_service.app_service_api-userprofile.identity[0].principal_id
|
||||
#
|
||||
# secret_permissions = [
|
||||
# "Get"
|
||||
# ]
|
||||
# }
|
||||
|
||||
# resource "azurerm_role_assignment" "cr_role_assignment_api-userprofile" {
|
||||
# scope = azurerm_container_registry.container_registry.id
|
||||
# role_definition_name = "AcrPull"
|
||||
# principal_id = azurerm_app_service.app_service_api-userprofile.identity[0].principal_id
|
||||
# }
|
||||
|
||||
resource "azurerm_app_service_slot" "app_service_api-userprofile_staging" {
|
||||
name = "staging"
|
||||
app_service_name = azurerm_app_service.app_service_api-userprofile.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
https_only = true
|
||||
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
app_settings = {
|
||||
"SQL_USER" = local.mssql_server_administrator_login
|
||||
"SQL_PASSWORD" = local.mssql_server_administrator_login_password
|
||||
"SQL_SERVER" = azurerm_mssql_server.mssql_server.fully_qualified_domain_name
|
||||
"SQL_DBNAME" = local.mssql_database_name
|
||||
"DOCKER_REGISTRY_SERVER_URL" = local.docker_registry_server_url
|
||||
"DOCKER_REGISTRY_SERVER_USERNAME" = local.docker_registry_server_username
|
||||
"DOCKER_REGISTRY_SERVER_PASSWORD" = local.docker_registry_server_password
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights_staging.instrumentation_key
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.application_insights_staging.connection_string
|
||||
}
|
||||
|
||||
site_config {
|
||||
always_on = true
|
||||
http2_enabled = true
|
||||
health_check_path = "/api/healthcheck/user"
|
||||
ftps_state = "Disabled"
|
||||
# acr_use_managed_identity_credentials = true
|
||||
linux_fx_version = "DOCKER|${azurerm_container_registry.container_registry.login_server}/devopsoh/api-userprofile:${local.apiuserprofile_base_image_tag}"
|
||||
}
|
||||
|
||||
logs {
|
||||
http_logs {
|
||||
file_system {
|
||||
retention_in_days = 7
|
||||
retention_in_mb = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags,
|
||||
app_settings["DOCKER_CUSTOM_IMAGE_NAME"],
|
||||
site_config[0].linux_fx_version
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_key_vault_access_policy" "key_vault_access_policy_api-userprofile_staging" {
|
||||
# key_vault_id = azurerm_key_vault.key_vault.id
|
||||
# tenant_id = azurerm_app_service_slot.app_service_api-userprofile_staging.identity[0].tenant_id
|
||||
# object_id = azurerm_app_service_slot.app_service_api-userprofile_staging.identity[0].principal_id
|
||||
#
|
||||
# secret_permissions = [
|
||||
# "Get"
|
||||
# ]
|
||||
# }
|
||||
|
||||
# resource "azurerm_role_assignment" "cr_role_assignment_api-userprofile_staging" {
|
||||
# scope = azurerm_container_registry.container_registry.id
|
||||
# role_definition_name = "AcrPull"
|
||||
# principal_id = azurerm_app_service_slot.app_service_api-userprofile_staging.identity[0].principal_id
|
||||
# }
|
145
iac/terraform/deploy.sh
Normal file
145
iac/terraform/deploy.sh
Normal file
@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
|
||||
declare UNIQUER=""
|
||||
declare LOCATION=""
|
||||
declare RESOURCES_PREFIX=""
|
||||
declare -r USAGE_HELP="Usage: ./deploy.sh -l <LOCATION> [-u <UNIQUER> -r <RESOURCES_PREFIX>]"
|
||||
|
||||
_error() {
|
||||
echo "##[error] $@" 2>&1
|
||||
}
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
_error "${USAGE_HELP}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Initialize parameters specified from command line
|
||||
while getopts ":l:u:r:" arg; do
|
||||
case "${arg}" in
|
||||
l) # Process -l (LOCATION)
|
||||
LOCATION="${OPTARG}"
|
||||
;;
|
||||
u) # Process -u (UNIQUER)
|
||||
UNIQUER="${OPTARG}"
|
||||
;;
|
||||
r) # Process -r (RESOURCES_PREFIX)
|
||||
RESOURCES_PREFIX="${OPTARG}"
|
||||
;;
|
||||
\?)
|
||||
_error "Invalid options found: -${OPTARG}."
|
||||
_error "${USAGE_HELP}" 2>&1
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
shift $((OPTIND - 1))
|
||||
|
||||
if [ ${#LOCATION} -eq 0 ]; then
|
||||
_error "Required LOCATION parameter is not set!"
|
||||
_error "${USAGE_HELP}" 2>&1
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check for programs
|
||||
if ! [ -x "$(command -v az)" ]; then
|
||||
_error "az is not installed!"
|
||||
exit 1
|
||||
elif ! [ -x "$(command -v jq)" ]; then
|
||||
_error "jq is not installed!"
|
||||
exit 1
|
||||
elif ! [ -x "$(command -v terraform)" ]; then
|
||||
_error "terraform is not installed!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -f "devvars.sh" ]; then
|
||||
. devvars.sh
|
||||
fi
|
||||
|
||||
azure_login() {
|
||||
_azuresp_json=$(cat azuresp.json)
|
||||
export ARM_CLIENT_ID=$(echo "${_azuresp_json}" | jq -r ".clientId")
|
||||
export ARM_CLIENT_SECRET=$(echo "${_azuresp_json}" | jq -r ".clientSecret")
|
||||
export ARM_SUBSCRIPTION_ID=$(echo "${_azuresp_json}" | jq -r ".subscriptionId")
|
||||
export ARM_TENANT_ID=$(echo "${_azuresp_json}" | jq -r ".tenantId")
|
||||
az login --service-principal --username "${ARM_CLIENT_ID}" --password "${ARM_CLIENT_SECRET}" --tenant "${ARM_TENANT_ID}"
|
||||
az account set --subscription "${ARM_SUBSCRIPTION_ID}"
|
||||
}
|
||||
|
||||
lint_terraform() {
|
||||
terraform fmt -check
|
||||
if [ $? -ne 0 ]; then
|
||||
_error "Terraform files are not properly formatted!"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
init_terrafrom() {
|
||||
terraform init -backend-config=storage_account_name="${TFSTATE_STORAGE_ACCOUNT_NAME}" -backend-config=container_name="${TFSTATE_STORAGE_CONTAINER_NAME}" -backend-config=key="${TFSTATE_KEY}" -backend-config=resource_group_name="${TFSTATE_RESOURCES_GROUP_NAME}"
|
||||
}
|
||||
|
||||
init_terrafrom_local() {
|
||||
terraform init -backend=false
|
||||
}
|
||||
|
||||
validate_terraform() {
|
||||
terraform validate
|
||||
}
|
||||
|
||||
preview_terraform() {
|
||||
if [ ${#RESOURCES_PREFIX} -gt 0 ]; then
|
||||
terraform plan --detailed-exitcode -var="location=${LOCATION}" -var="resources_prefix=${RESOURCES_PREFIX}"
|
||||
elif [[ ${#RESOURCES_PREFIX} -eq 0 && ${#UNIQUER} -gt 0 ]]; then
|
||||
terraform plan --detailed-exitcode -var="location=${LOCATION}" -var="uniquer=${UNIQUER}"
|
||||
else
|
||||
terraform plan --detailed-exitcode -var="location=${LOCATION}"
|
||||
fi
|
||||
|
||||
return $?
|
||||
}
|
||||
|
||||
deploy_terraform() {
|
||||
local _tfplan_exit_code=${1}
|
||||
|
||||
if [ "${_tfplan_exit_code}" -eq 2 ]; then
|
||||
if [ ${#RESOURCES_PREFIX} -gt 0 ]; then
|
||||
terraform apply --auto-approve -var="location=${LOCATION}" -var="resources_prefix=${RESOURCES_PREFIX}"
|
||||
elif [[ ${#RESOURCES_PREFIX} -eq 0 && ${#UNIQUER} -gt 0 ]]; then
|
||||
terraform apply --auto-approve -var="location=${LOCATION}" -var="uniquer=${UNIQUER}"
|
||||
else
|
||||
terraform apply --auto-approve -var="location=${LOCATION}"
|
||||
fi
|
||||
fi
|
||||
# rm -rf .terraform && rm -rf .terraform.lock.hcl && rm -rf terraform.tfstate && rm -rf terraform.tfstate.backup
|
||||
}
|
||||
|
||||
destroy_terraform() {
|
||||
if [ ${#RESOURCES_PREFIX} -gt 0 ]; then
|
||||
terraform destroy --auto-approve -var="location=${LOCATION}" -var="resources_prefix=${RESOURCES_PREFIX}"
|
||||
elif [[ ${#RESOURCES_PREFIX} -eq 0 && ${#UNIQUER} -gt 0 ]]; then
|
||||
terraform destroy --auto-approve -var="location=${LOCATION}" -var="uniquer=${UNIQUER}"
|
||||
else
|
||||
terraform destroy --auto-approve -var="location=${LOCATION}"
|
||||
fi
|
||||
}
|
||||
|
||||
test_deploy() {
|
||||
local _hostnames="${1}"
|
||||
|
||||
sleep 30
|
||||
pwsh -Command ./smokeTest.ps1 -HostNames "${_hostnames}"
|
||||
}
|
||||
|
||||
azure_login
|
||||
|
||||
lint_terraform
|
||||
init_terrafrom
|
||||
# init_terrafrom_local
|
||||
validate_terraform
|
||||
preview_terraform
|
||||
deploy_terraform $?
|
||||
# destroy_terraform
|
||||
# deployment_output=$(terraform output -json)
|
||||
# hostnames=$(echo "${deployment_output}" | jq -r -c 'map(.value) | join(",")')
|
||||
# test_deploy "${hostnames}"
|
12
iac/terraform/locals.defaults.tf
Normal file
12
iac/terraform/locals.defaults.tf
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
locals {
|
||||
_default = {
|
||||
base_image_tag = "changeme"
|
||||
name_prefix = "devopsoh"
|
||||
}
|
||||
_secrets = {
|
||||
bing_maps_key = "Ar6iuHZYgX1BrfJs6SRJaXWbpU_HKdoe7G-OO9b2kl3rWvcawYx235GGx5FPM76O"
|
||||
mssql_server_administrator_login = "demousersa"
|
||||
mssql_server_administrator_login_password = "demo!P@55w0rd123"
|
||||
}
|
||||
}
|
45
iac/terraform/locals.tf
Normal file
45
iac/terraform/locals.tf
Normal file
@ -0,0 +1,45 @@
|
||||
resource "random_string" "uniquer" {
|
||||
length = 5
|
||||
special = false
|
||||
number = true
|
||||
lower = false
|
||||
upper = false
|
||||
}
|
||||
|
||||
data "external" "my_ip" {
|
||||
program = ["/bin/bash", "${path.module}/myip.sh"]
|
||||
}
|
||||
|
||||
locals {
|
||||
uniquer = var.uniquer != null ? var.uniquer : "${random_string.uniquer.id}"
|
||||
resources_prefix = var.resources_prefix != null ? var.resources_prefix : "${local._default.name_prefix}${local.uniquer}"
|
||||
team_name = local.resources_prefix
|
||||
location = var.location
|
||||
resource_group_name = "${local.resources_prefix}rg"
|
||||
|
||||
key_vault_name = "${local.resources_prefix}kv"
|
||||
container_registry_name = "${local.resources_prefix}cr"
|
||||
application_insights_name = "${local.resources_prefix}appi"
|
||||
mssql_server_name = "${local.resources_prefix}sql"
|
||||
mssql_server_administrator_login = var.mssql_server_administrator_login != null ? var.mssql_server_administrator_login : local._secrets.mssql_server_administrator_login
|
||||
mssql_server_administrator_login_password = var.mssql_server_administrator_login_password != null ? var.mssql_server_administrator_login_password : local._secrets.mssql_server_administrator_login_password
|
||||
mssql_firewall_rule_myip = data.external.my_ip.result["my_ip"]
|
||||
mssql_database_name = "mydrivingDB"
|
||||
bing_maps_key = local._secrets.bing_maps_key
|
||||
app_service_plan_name = "${local.resources_prefix}plan"
|
||||
app_service_tripviewer_name = "${local.resources_prefix}tripviewer"
|
||||
app_service_api-poi_name = "${local.resources_prefix}poi"
|
||||
app_service_api-trips_name = "${local.resources_prefix}trips"
|
||||
app_service_api-userjava_name = "${local.resources_prefix}userjava"
|
||||
app_service_api-userprofile_name = "${local.resources_prefix}userprofile"
|
||||
user_assigned_identity_name = "${local.resources_prefix}uami"
|
||||
container_group_simulator_name = "${local.resources_prefix}simulator"
|
||||
log_analytics_name = "${local.resources_prefix}log"
|
||||
apipoi_base_image_tag = var.apipoi_base_image_tag != null ? var.apipoi_base_image_tag : local._default.base_image_tag
|
||||
apitrips_base_image_tag = var.apitrips_base_image_tag != null ? var.apitrips_base_image_tag : local._default.base_image_tag
|
||||
apiuserjava_base_image_tag = var.apiuserjava_base_image_tag != null ? var.apiuserjava_base_image_tag : local._default.base_image_tag
|
||||
apiuserprofile_base_image_tag = var.apiuserprofile_base_image_tag != null ? var.apiuserprofile_base_image_tag : local._default.base_image_tag
|
||||
docker_registry_server_url = var.docker_registry_server_url != null ? var.docker_registry_server_url : "https://${azurerm_container_registry.container_registry.login_server}"
|
||||
docker_registry_server_username = var.docker_registry_server_username != null ? var.docker_registry_server_username : azurerm_container_registry.container_registry.admin_username
|
||||
docker_registry_server_password = var.docker_registry_server_password != null ? var.docker_registry_server_password : azurerm_container_registry.container_registry.admin_password
|
||||
}
|
511
iac/terraform/main.tf
Normal file
511
iac/terraform/main.tf
Normal file
@ -0,0 +1,511 @@
|
||||
############################################
|
||||
## RESOURCE GROUP ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_resource_group" "resource_group" {
|
||||
name = local.resource_group_name
|
||||
location = local.location
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
############################################
|
||||
## CONTAINER REGISTRY ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_container_registry" "container_registry" {
|
||||
name = local.container_registry_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
sku = "Standard"
|
||||
admin_enabled = true
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
############################################
|
||||
## SQL SERVER ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_mssql_server" "mssql_server" {
|
||||
name = local.mssql_server_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
version = "12.0"
|
||||
administrator_login = local.mssql_server_administrator_login
|
||||
administrator_login_password = local.mssql_server_administrator_login_password
|
||||
minimum_tls_version = "1.2"
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_mssql_firewall_rule" "mssql_firewall_rule_myip" {
|
||||
name = "SetupAccount"
|
||||
server_id = azurerm_mssql_server.mssql_server.id
|
||||
start_ip_address = local.mssql_firewall_rule_myip
|
||||
end_ip_address = local.mssql_firewall_rule_myip
|
||||
}
|
||||
|
||||
resource "azurerm_mssql_firewall_rule" "mssql_firewall_rule_azure" {
|
||||
name = "AzureAccess"
|
||||
server_id = azurerm_mssql_server.mssql_server.id
|
||||
start_ip_address = "0.0.0.0"
|
||||
end_ip_address = "0.0.0.0"
|
||||
}
|
||||
|
||||
############################################
|
||||
## SQL DATABASE ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_mssql_database" "mssql_database" {
|
||||
name = local.mssql_database_name
|
||||
server_id = azurerm_mssql_server.mssql_server.id
|
||||
collation = "SQL_Latin1_General_CP1_CI_AS"
|
||||
sku_name = "S0"
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
############################################
|
||||
## SQL DATABASE DIAGNOSTIC ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_monitor_diagnostic_setting" "monitor_diagnostic_setting_mssql_database" {
|
||||
name = "sqlDbDiag"
|
||||
target_resource_id = azurerm_mssql_database.mssql_database.id
|
||||
log_analytics_workspace_id = azurerm_log_analytics_workspace.log_analytics_workspace.id
|
||||
|
||||
log {
|
||||
category = "SQLInsights"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "AutomaticTuning"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "QueryStoreRuntimeStatistics"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "QueryStoreWaitStatistics"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "Errors"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "DatabaseWaitStatistics"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "Timeouts"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "Blocks"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "Deadlocks"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "DevOpsOperationsAudit"
|
||||
enabled = true
|
||||
}
|
||||
log {
|
||||
category = "SQLSecurityAuditEvents"
|
||||
enabled = true
|
||||
}
|
||||
|
||||
metric {
|
||||
category = "Basic"
|
||||
enabled = true
|
||||
}
|
||||
metric {
|
||||
category = "InstanceAndAppAdvanced"
|
||||
enabled = true
|
||||
}
|
||||
metric {
|
||||
category = "WorkloadManagement"
|
||||
enabled = true
|
||||
}
|
||||
}
|
||||
|
||||
############################################
|
||||
## APP SERVICE PLAN ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_app_service_plan" "app_service_plan" {
|
||||
name = local.app_service_plan_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
kind = "linux"
|
||||
reserved = true
|
||||
|
||||
sku {
|
||||
tier = "PremiumV2"
|
||||
size = "P1v2"
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
############################################
|
||||
## APP SERVICE - TRIPVIEWER ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_app_service" "app_service_tripviewer" {
|
||||
depends_on = [
|
||||
null_resource.docker_tripviewer
|
||||
]
|
||||
name = local.app_service_tripviewer_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
app_service_plan_id = azurerm_app_service_plan.app_service_plan.id
|
||||
https_only = true
|
||||
identity {
|
||||
type = "SystemAssigned"
|
||||
}
|
||||
|
||||
app_settings = {
|
||||
"BING_MAPS_KEY" = local.bing_maps_key
|
||||
"USER_ROOT_URL" = "https://${azurerm_app_service.app_service_api-userprofile.default_site_hostname}"
|
||||
"USER_JAVA_ROOT_URL" = "https://${azurerm_app_service.app_service_api-userjava.default_site_hostname}"
|
||||
"TRIPS_ROOT_URL" = "https://${azurerm_app_service.app_service_api-trips.default_site_hostname}"
|
||||
"POI_ROOT_URL" = "https://${azurerm_app_service.app_service_api-poi.default_site_hostname}"
|
||||
"STAGING_USER_ROOT_URL" = "https://${azurerm_app_service_slot.app_service_api-userprofile_staging.default_site_hostname}"
|
||||
"STAGING_USER_JAVA_ROOT_URL" = "https://${azurerm_app_service_slot.app_service_api-userjava_staging.default_site_hostname}"
|
||||
"STAGING_TRIPS_ROOT_URL" = "https://${azurerm_app_service_slot.app_service_api-trips_staging.default_site_hostname}"
|
||||
"STAGING_POI_ROOT_URL" = "https://${azurerm_app_service_slot.app_service_api-poi_staging.default_site_hostname}"
|
||||
"DOCKER_REGISTRY_SERVER_URL" = "https://${azurerm_container_registry.container_registry.login_server}"
|
||||
"APPINSIGHTS_INSTRUMENTATIONKEY" = azurerm_application_insights.application_insights.instrumentation_key
|
||||
"APPLICATIONINSIGHTS_CONNECTION_STRING" = azurerm_application_insights.application_insights.connection_string
|
||||
}
|
||||
|
||||
site_config {
|
||||
always_on = true
|
||||
http2_enabled = true
|
||||
ftps_state = "Disabled"
|
||||
acr_use_managed_identity_credentials = true
|
||||
linux_fx_version = "DOCKER|${azurerm_container_registry.container_registry.login_server}/devopsoh/tripviewer:latest"
|
||||
}
|
||||
|
||||
logs {
|
||||
http_logs {
|
||||
file_system {
|
||||
retention_in_days = 7
|
||||
retention_in_mb = 50
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_role_assignment" "cr_role_assignment_tripviewer" {
|
||||
scope = azurerm_container_registry.container_registry.id
|
||||
role_definition_name = "AcrPull"
|
||||
principal_id = azurerm_app_service.app_service_tripviewer.identity[0].principal_id
|
||||
}
|
||||
|
||||
resource "azurerm_key_vault_access_policy" "key_vault_access_policy_tripviewer" {
|
||||
key_vault_id = azurerm_key_vault.key_vault.id
|
||||
tenant_id = azurerm_app_service.app_service_tripviewer.identity[0].tenant_id
|
||||
object_id = azurerm_app_service.app_service_tripviewer.identity[0].principal_id
|
||||
|
||||
secret_permissions = [
|
||||
"Get"
|
||||
]
|
||||
}
|
||||
|
||||
############################################
|
||||
## APPLICATION INSIGHTS ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_application_insights" "application_insights" {
|
||||
name = local.application_insights_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
application_type = "web"
|
||||
}
|
||||
|
||||
resource "azurerm_application_insights" "application_insights_staging" {
|
||||
name = "${local.application_insights_name}staging"
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
application_type = "web"
|
||||
}
|
||||
|
||||
############################################
|
||||
## UAMI ##
|
||||
############################################
|
||||
|
||||
# resource "azurerm_user_assigned_identity" "user_assigned_identity" {
|
||||
# name = local.user_assigned_identity_name
|
||||
# resource_group_name = azurerm_resource_group.resource_group.name
|
||||
# location = azurerm_resource_group.resource_group.location
|
||||
# }
|
||||
|
||||
############################################
|
||||
## LOG ANALYTICS ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_log_analytics_workspace" "log_analytics_workspace" {
|
||||
name = local.log_analytics_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
sku = "PerGB2018"
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_log_analytics_solution" "log_analytics_solution_containerinsights" {
|
||||
# solution_name = "ContainerInsights"
|
||||
# location = azurerm_resource_group.resource_group.location
|
||||
# resource_group_name = azurerm_resource_group.resource_group.name
|
||||
# workspace_resource_id = azurerm_log_analytics_workspace.log_analytics_workspace.id
|
||||
# workspace_name = azurerm_log_analytics_workspace.log_analytics_workspace.name
|
||||
|
||||
# plan {
|
||||
# publisher = "Microsoft"
|
||||
# product = "OMSGallery/ContainerInsights"
|
||||
# }
|
||||
|
||||
# lifecycle {
|
||||
# ignore_changes = [
|
||||
# tags
|
||||
# ]
|
||||
# }
|
||||
# }
|
||||
|
||||
resource "azurerm_log_analytics_solution" "log_analytics_solution_containers" {
|
||||
solution_name = "Containers"
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
workspace_resource_id = azurerm_log_analytics_workspace.log_analytics_workspace.id
|
||||
workspace_name = azurerm_log_analytics_workspace.log_analytics_workspace.name
|
||||
|
||||
plan {
|
||||
publisher = "Microsoft"
|
||||
product = "OMSGallery/Containers"
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_log_analytics_solution" "log_analytics_solution_sqlassessment" {
|
||||
solution_name = "SQLAssessment"
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
workspace_resource_id = azurerm_log_analytics_workspace.log_analytics_workspace.id
|
||||
workspace_name = azurerm_log_analytics_workspace.log_analytics_workspace.name
|
||||
|
||||
plan {
|
||||
publisher = "Microsoft"
|
||||
product = "OMSGallery/SQLAssessment"
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_log_analytics_solution" "log_analytics_solution_azuresqlanalytics" {
|
||||
solution_name = "AzureSQLAnalytics"
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
workspace_resource_id = azurerm_log_analytics_workspace.log_analytics_workspace.id
|
||||
workspace_name = azurerm_log_analytics_workspace.log_analytics_workspace.name
|
||||
|
||||
plan {
|
||||
publisher = "Microsoft"
|
||||
product = "OMSGallery/AzureSQLAnalytics"
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
############################################
|
||||
## CONTAINER GROUP - SIMULATOR ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_container_group" "container_group_simulator" {
|
||||
depends_on = [
|
||||
null_resource.docker_simulator
|
||||
# azurerm_role_assignment.cr_role_assignment_simulator
|
||||
]
|
||||
name = local.container_group_simulator_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
ip_address_type = "public"
|
||||
dns_name_label = local.container_group_simulator_name
|
||||
os_type = "Linux"
|
||||
|
||||
# identity {
|
||||
# type = "UserAssigned"
|
||||
# identity_ids = [
|
||||
# azurerm_user_assigned_identity.user_assigned_identity.id
|
||||
# ]
|
||||
# }
|
||||
|
||||
image_registry_credential {
|
||||
username = azurerm_container_registry.container_registry.admin_username
|
||||
password = azurerm_container_registry.container_registry.admin_password
|
||||
server = azurerm_container_registry.container_registry.login_server
|
||||
}
|
||||
|
||||
container {
|
||||
name = "simulator"
|
||||
image = "${azurerm_container_registry.container_registry.login_server}/devopsoh/simulator:latest"
|
||||
cpu = "1"
|
||||
memory = "2"
|
||||
|
||||
ports {
|
||||
port = 8080
|
||||
protocol = "TCP"
|
||||
}
|
||||
|
||||
environment_variables = {
|
||||
"SQL_USER" = local.mssql_server_administrator_login
|
||||
"SQL_SERVER" = azurerm_mssql_server.mssql_server.fully_qualified_domain_name
|
||||
"SQL_DBNAME" = local.mssql_database_name
|
||||
"TEAM_NAME" = local.team_name
|
||||
"USER_ROOT_URL" = "https://${azurerm_app_service.app_service_api-userprofile.default_site_hostname}"
|
||||
"USER_JAVA_ROOT_URL" = "https://${azurerm_app_service.app_service_api-userjava.default_site_hostname}"
|
||||
"TRIPS_ROOT_URL" = "https://${azurerm_app_service.app_service_api-trips.default_site_hostname}"
|
||||
"POI_ROOT_URL" = "https://${azurerm_app_service.app_service_api-poi.default_site_hostname}"
|
||||
}
|
||||
|
||||
secure_environment_variables = {
|
||||
"SQL_PASSWORD" = local.mssql_server_administrator_login_password
|
||||
}
|
||||
}
|
||||
|
||||
diagnostics {
|
||||
log_analytics {
|
||||
log_type = "ContainerInsights"
|
||||
workspace_id = azurerm_log_analytics_workspace.log_analytics_workspace.workspace_id
|
||||
workspace_key = azurerm_log_analytics_workspace.log_analytics_workspace.primary_shared_key
|
||||
}
|
||||
}
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
# resource "azurerm_role_assignment" "cr_role_assignment_simulator" {
|
||||
# scope = azurerm_container_registry.container_registry.id
|
||||
# role_definition_name = "AcrPull"
|
||||
# principal_id = azurerm_user_assigned_identity.user_assigned_identity.principal_id
|
||||
# }
|
||||
|
||||
############################################
|
||||
## KEY VAULT ##
|
||||
############################################
|
||||
|
||||
resource "azurerm_key_vault" "key_vault" {
|
||||
name = local.key_vault_name
|
||||
location = azurerm_resource_group.resource_group.location
|
||||
resource_group_name = azurerm_resource_group.resource_group.name
|
||||
tenant_id = data.azurerm_client_config.current.tenant_id
|
||||
sku_name = "standard"
|
||||
soft_delete_retention_days = 7
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
tags
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
resource "azurerm_key_vault_access_policy" "key_vault_access_policy_sp" {
|
||||
key_vault_id = azurerm_key_vault.key_vault.id
|
||||
tenant_id = data.azurerm_client_config.current.tenant_id
|
||||
object_id = data.azurerm_client_config.current.object_id
|
||||
|
||||
certificate_permissions = [
|
||||
"Backup", "Create", "Delete", "DeleteIssuers", "Get", "GetIssuers", "Import", "List", "ListIssuers", "ManageContacts", "ManageIssuers", "Purge", "Recover", "Restore", "SetIssuers", "Update"
|
||||
]
|
||||
|
||||
key_permissions = [
|
||||
"Backup", "Create", "Decrypt", "Delete", "Encrypt", "Get", "Import", "List", "Purge", "Recover", "Restore", "Sign", "UnwrapKey", "Update", "Verify", "WrapKey"
|
||||
]
|
||||
|
||||
secret_permissions = [
|
||||
"Backup", "Delete", "Get", "List", "Purge", "Recover", "Restore", "Set"
|
||||
]
|
||||
|
||||
storage_permissions = [
|
||||
"Backup", "Delete", "DeleteSAS", "Get", "GetSAS", "List", "ListSAS", "Purge", "Recover", "RegenerateKey", "Restore", "Set", "SetSAS", "Update"
|
||||
]
|
||||
}
|
||||
|
||||
resource "azurerm_key_vault_secret" "key_vault_secret_sqlpassword" {
|
||||
name = "SQL-PASSWORD"
|
||||
value = local.mssql_server_administrator_login_password
|
||||
key_vault_id = azurerm_key_vault.key_vault.id
|
||||
|
||||
# tags = {
|
||||
# "CredentialId" = local.mssql_server_administrator_login,
|
||||
# "ProviderAddress" = azurerm_mssql_server.mssql_server.id,
|
||||
# "ValidityPeriodDays" = 30
|
||||
# }
|
||||
|
||||
# expiration_date = timeadd(timestamp(), "30m")
|
||||
|
||||
lifecycle {
|
||||
ignore_changes = [
|
||||
value,
|
||||
expiration_date
|
||||
]
|
||||
}
|
||||
|
||||
# prevents race condition when the secret is getting created before the access policy, causing 401
|
||||
depends_on = [
|
||||
azurerm_key_vault_access_policy.key_vault_access_policy_sp
|
||||
]
|
||||
}
|
4
iac/terraform/myip.sh
Normal file
4
iac/terraform/myip.sh
Normal file
@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
MYIP="$(dig +short myip.opendns.com @resolver1.opendns.com -4)"
|
||||
echo $(jq -n --arg MYIP "$MYIP" '{"my_ip":$MYIP}')
|
16
iac/terraform/outputs.tf
Normal file
16
iac/terraform/outputs.tf
Normal file
@ -0,0 +1,16 @@
|
||||
output "appServiceApiPoiHealthcheck" {
|
||||
description = "Hostname of API-POI"
|
||||
value = "${azurerm_app_service.app_service_api-poi.default_site_hostname}/api/healthcheck/poi"
|
||||
}
|
||||
output "appServiceApiTripsHealthcheck" {
|
||||
description = "Hostname of API-TRIPS"
|
||||
value = "${azurerm_app_service.app_service_api-trips.default_site_hostname}/api/healthcheck/trips"
|
||||
}
|
||||
output "appServiceApiUserJavaHealthcheck" {
|
||||
description = "Hostname of API-USER-JAVA"
|
||||
value = "${azurerm_app_service.app_service_api-userjava.default_site_hostname}/api/healthcheck/user-java"
|
||||
}
|
||||
output "appServiceApiUserprofileHealthcheck" {
|
||||
description = "Hostname of API-USERPROFILE"
|
||||
value = "${azurerm_app_service.app_service_api-userprofile.default_site_hostname}/api/healthcheck/user"
|
||||
}
|
20
iac/terraform/providers.tf
Normal file
20
iac/terraform/providers.tf
Normal file
@ -0,0 +1,20 @@
|
||||
terraform {
|
||||
required_providers {
|
||||
azurerm = {
|
||||
source = "hashicorp/azurerm"
|
||||
version = "2.96.0"
|
||||
}
|
||||
}
|
||||
backend "azurerm" {
|
||||
}
|
||||
}
|
||||
|
||||
provider "azurerm" {
|
||||
features {
|
||||
key_vault {
|
||||
purge_soft_delete_on_destroy = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data "azurerm_client_config" "current" {}
|
34
iac/terraform/smokeTest.ps1
Normal file
34
iac/terraform/smokeTest.ps1
Normal file
@ -0,0 +1,34 @@
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[ValidateNotNullOrEmpty()]
|
||||
[string[]] $HostNames = @()
|
||||
)
|
||||
|
||||
if (!(Get-Module -Name Pester)) {
|
||||
Write-Host "Pester module does not exist. Installing ..."
|
||||
try {
|
||||
Install-Module Pester -AllowClobber -Force -Confirm:$False -SkipPublisherCheck
|
||||
}
|
||||
catch [Exception] {
|
||||
$_.message
|
||||
exit
|
||||
}
|
||||
}
|
||||
Import-Module Pester
|
||||
|
||||
$container = New-PesterContainer `
|
||||
-Path 'appService.Test.ps1' `
|
||||
-Data @{ HostNames = $HostNames }
|
||||
|
||||
$config = New-PesterConfiguration
|
||||
$config.Run.PassThru = $true
|
||||
$config.Run.Container = $container
|
||||
$config.TestResult.Enabled = $true
|
||||
$config.TestResult.OutputFormat = 'NUnitXml'
|
||||
$config.TestResult.OutputPath = 'testResultsNunit.xml'
|
||||
|
||||
$p = Invoke-Pester -Configuration $config
|
||||
$p | Export-JUnitReport -Path 'testResultsJunit.xml'
|
||||
|
||||
|
||||
|
1
iac/terraform/test.txt
Normal file
1
iac/terraform/test.txt
Normal file
@ -0,0 +1 @@
|
||||
test
|
72
iac/terraform/variables.tf
Normal file
72
iac/terraform/variables.tf
Normal file
@ -0,0 +1,72 @@
|
||||
variable "location" {
|
||||
description = ""
|
||||
type = string
|
||||
}
|
||||
|
||||
variable "uniquer" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "resources_prefix" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "docker_registry_server_url" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "docker_registry_server_username" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "docker_registry_server_password" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "mssql_server_administrator_login" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "mssql_server_administrator_login_password" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "apipoi_base_image_tag" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "apitrips_base_image_tag" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "apiuserjava_base_image_tag" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
}
|
||||
|
||||
variable "apiuserprofile_base_image_tag" {
|
||||
description = ""
|
||||
type = string
|
||||
default = null
|
||||
}
|
1
iac/test.txt
Normal file
1
iac/test.txt
Normal file
@ -0,0 +1 @@
|
||||
test
|
Reference in New Issue
Block a user