############################################ ## 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 ] }