From 3fc4f6f8079dc426a57bc2bc3cb225ed7537a0c9 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Fri, 16 Aug 2024 15:05:17 +0800 Subject: [PATCH 01/21] azd init --- azure.yaml | 5 ++ infra/abbreviations.json | 135 ++++++++++++++++++++++++++++++++++ infra/main.bicep | 41 +++++++++++ infra/main.parameters.json | 15 ++++ infra/shared/monitoring.bicep | 34 +++++++++ 5 files changed, 230 insertions(+) create mode 100644 azure.yaml create mode 100644 infra/abbreviations.json create mode 100644 infra/main.bicep create mode 100644 infra/main.parameters.json create mode 100644 infra/shared/monitoring.bicep diff --git a/azure.yaml b/azure.yaml new file mode 100644 index 0000000..bb58b19 --- /dev/null +++ b/azure.yaml @@ -0,0 +1,5 @@ +# yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json + +name: cargotracker-liberty-aks +metadata: + template: azd-init@1.9.5 diff --git a/infra/abbreviations.json b/infra/abbreviations.json new file mode 100644 index 0000000..dc62141 --- /dev/null +++ b/infra/abbreviations.json @@ -0,0 +1,135 @@ +{ + "analysisServicesServers": "as", + "apiManagementService": "apim-", + "appConfigurationStores": "appcs-", + "appManagedEnvironments": "cae-", + "appContainerApps": "ca-", + "authorizationPolicyDefinitions": "policy-", + "automationAutomationAccounts": "aa-", + "blueprintBlueprints": "bp-", + "blueprintBlueprintsArtifacts": "bpa-", + "cacheRedis": "redis-", + "cdnProfiles": "cdnp-", + "cdnProfilesEndpoints": "cdne-", + "cognitiveServicesAccounts": "cog-", + "cognitiveServicesFormRecognizer": "cog-fr-", + "cognitiveServicesTextAnalytics": "cog-ta-", + "computeAvailabilitySets": "avail-", + "computeCloudServices": "cld-", + "computeDiskEncryptionSets": "des", + "computeDisks": "disk", + "computeDisksOs": "osdisk", + "computeGalleries": "gal", + "computeSnapshots": "snap-", + "computeVirtualMachines": "vm", + "computeVirtualMachineScaleSets": "vmss-", + "containerInstanceContainerGroups": "ci", + "containerRegistryRegistries": "cr", + "containerServiceManagedClusters": "aks-", + "databricksWorkspaces": "dbw-", + "dataFactoryFactories": "adf-", + "dataLakeAnalyticsAccounts": "dla", + "dataLakeStoreAccounts": "dls", + "dataMigrationServices": "dms-", + "dBforMySQLServers": "mysql-", + "dBforPostgreSQLServers": "psql-", + "devicesIotHubs": "iot-", + "devicesProvisioningServices": "provs-", + "devicesProvisioningServicesCertificates": "pcert-", + "documentDBDatabaseAccounts": "cosmos-", + "eventGridDomains": "evgd-", + "eventGridDomainsTopics": "evgt-", + "eventGridEventSubscriptions": "evgs-", + "eventHubNamespaces": "evhns-", + "eventHubNamespacesEventHubs": "evh-", + "hdInsightClustersHadoop": "hadoop-", + "hdInsightClustersHbase": "hbase-", + "hdInsightClustersKafka": "kafka-", + "hdInsightClustersMl": "mls-", + "hdInsightClustersSpark": "spark-", + "hdInsightClustersStorm": "storm-", + "hybridComputeMachines": "arcs-", + "insightsActionGroups": "ag-", + "insightsComponents": "appi-", + "keyVaultVaults": "kv-", + "kubernetesConnectedClusters": "arck", + "kustoClusters": "dec", + "kustoClustersDatabases": "dedb", + "logicIntegrationAccounts": "ia-", + "logicWorkflows": "logic-", + "machineLearningServicesWorkspaces": "mlw-", + "managedIdentityUserAssignedIdentities": "id-", + "managementManagementGroups": "mg-", + "migrateAssessmentProjects": "migr-", + "networkApplicationGateways": "agw-", + "networkApplicationSecurityGroups": "asg-", + "networkAzureFirewalls": "afw-", + "networkBastionHosts": "bas-", + "networkConnections": "con-", + "networkDnsZones": "dnsz-", + "networkExpressRouteCircuits": "erc-", + "networkFirewallPolicies": "afwp-", + "networkFirewallPoliciesWebApplication": "waf", + "networkFirewallPoliciesRuleGroups": "wafrg", + "networkFrontDoors": "fd-", + "networkFrontdoorWebApplicationFirewallPolicies": "fdfp-", + "networkLoadBalancersExternal": "lbe-", + "networkLoadBalancersInternal": "lbi-", + "networkLoadBalancersInboundNatRules": "rule-", + "networkLocalNetworkGateways": "lgw-", + "networkNatGateways": "ng-", + "networkNetworkInterfaces": "nic-", + "networkNetworkSecurityGroups": "nsg-", + "networkNetworkSecurityGroupsSecurityRules": "nsgsr-", + "networkNetworkWatchers": "nw-", + "networkPrivateDnsZones": "pdnsz-", + "networkPrivateLinkServices": "pl-", + "networkPublicIPAddresses": "pip-", + "networkPublicIPPrefixes": "ippre-", + "networkRouteFilters": "rf-", + "networkRouteTables": "rt-", + "networkRouteTablesRoutes": "udr-", + "networkTrafficManagerProfiles": "traf-", + "networkVirtualNetworkGateways": "vgw-", + "networkVirtualNetworks": "vnet-", + "networkVirtualNetworksSubnets": "snet-", + "networkVirtualNetworksVirtualNetworkPeerings": "peer-", + "networkVirtualWans": "vwan-", + "networkVpnGateways": "vpng-", + "networkVpnGatewaysVpnConnections": "vcn-", + "networkVpnGatewaysVpnSites": "vst-", + "notificationHubsNamespaces": "ntfns-", + "notificationHubsNamespacesNotificationHubs": "ntf-", + "operationalInsightsWorkspaces": "log-", + "portalDashboards": "dash-", + "powerBIDedicatedCapacities": "pbi-", + "purviewAccounts": "pview-", + "recoveryServicesVaults": "rsv-", + "resourcesResourceGroups": "rg-", + "searchSearchServices": "srch-", + "serviceBusNamespaces": "sb-", + "serviceBusNamespacesQueues": "sbq-", + "serviceBusNamespacesTopics": "sbt-", + "serviceEndPointPolicies": "se-", + "serviceFabricClusters": "sf-", + "signalRServiceSignalR": "sigr", + "sqlManagedInstances": "sqlmi-", + "sqlServers": "sql-", + "sqlServersDataWarehouse": "sqldw-", + "sqlServersDatabases": "sqldb-", + "sqlServersDatabasesStretch": "sqlstrdb-", + "storageStorageAccounts": "st", + "storageStorageAccountsVm": "stvm", + "storSimpleManagers": "ssimp", + "streamAnalyticsCluster": "asa-", + "synapseWorkspaces": "syn", + "synapseWorkspacesAnalyticsWorkspaces": "synw", + "synapseWorkspacesSqlPoolsDedicated": "syndp", + "synapseWorkspacesSqlPoolsSpark": "synsp", + "timeSeriesInsightsEnvironments": "tsi-", + "webServerFarms": "plan-", + "webSitesAppService": "app-", + "webSitesAppServiceEnvironment": "ase-", + "webSitesFunctions": "func-", + "webStaticSites": "stapp-" +} diff --git a/infra/main.bicep b/infra/main.bicep new file mode 100644 index 0000000..47f19c8 --- /dev/null +++ b/infra/main.bicep @@ -0,0 +1,41 @@ +targetScope = 'subscription' + +@minLength(1) +@maxLength(64) +@description('Name of the environment that can be used as part of naming resource convention') +param environmentName string + +@minLength(1) +@description('Primary location for all resources') +param location string + + +// Tags that should be applied to all resources. +// +// Note that 'azd-service-name' tags should be applied separately to service host resources. +// Example usage: +// tags: union(tags, { 'azd-service-name': }) +var tags = { + 'azd-env-name': environmentName +} + +var abbrs = loadJsonContent('./abbreviations.json') +var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) + +resource rg 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: 'rg-${environmentName}-${take(resourceToken, 5)}' + location: location + tags: tags +} + +module monitoring './shared/monitoring.bicep' = { + name: 'monitoring' + params: { + location: location + tags: tags + logAnalyticsName: '${abbrs.operationalInsightsWorkspaces}${resourceToken}' + applicationInsightsName: '${abbrs.insightsComponents}${resourceToken}' + } + scope: rg +} + diff --git a/infra/main.parameters.json b/infra/main.parameters.json new file mode 100644 index 0000000..c8d3453 --- /dev/null +++ b/infra/main.parameters.json @@ -0,0 +1,15 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "environmentName": { + "value": "${AZURE_ENV_NAME}" + }, + "location": { + "value": "${AZURE_LOCATION}" + }, + "principalId": { + "value": "${AZURE_PRINCIPAL_ID}" + } + } +} diff --git a/infra/shared/monitoring.bicep b/infra/shared/monitoring.bicep new file mode 100644 index 0000000..4ae9796 --- /dev/null +++ b/infra/shared/monitoring.bicep @@ -0,0 +1,34 @@ +param logAnalyticsName string +param applicationInsightsName string +param location string = resourceGroup().location +param tags object = {} + +resource logAnalytics 'Microsoft.OperationalInsights/workspaces@2021-12-01-preview' = { + name: logAnalyticsName + location: location + tags: tags + properties: any({ + retentionInDays: 30 + features: { + searchVersion: 1 + } + sku: { + name: 'PerGB2018' + } + }) +} + +resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { + name: applicationInsightsName + location: location + tags: tags + kind: 'web' + properties: { + Application_Type: 'web' + WorkspaceResourceId: logAnalytics.id + } +} + +output applicationInsightsName string = applicationInsights.name +output logAnalyticsWorkspaceId string = logAnalytics.id +output logAnalyticsWorkspaceName string = logAnalytics.name From 7cdf232aab7e06637cc15c1bd4836b83123b1f21 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Fri, 16 Aug 2024 17:04:39 +0800 Subject: [PATCH 02/21] add azure.liberty.aks module --- infra/azure.liberty.aks/mainTemplate.bicep | 541 ++++++++++++++++++ .../_azure-resoruces/_appgateway.bicep | 183 ++++++ .../_keyvault/_keyvaultWithExistingCert.bicep | 84 +++ .../_keyvault/_keyvaultWithNewCert.bicep | 96 ++++ .../_keyvaultForGateway.bicep | 85 +++ .../_azure-resoruces/_vnetAppGateway.bicep | 112 ++++ .../_deployment-scripts/_ds-networking.bicep | 101 ++++ .../_deployment-scripts/_ds-preflight.bicep | 130 +++++ .../_deployment-scripts/_ds-primary.bicep | 129 +++++ .../_deployment-scripts/_ds_enable_agic.bicep | 63 ++ ...ery_available_private_ip_from_subnet.bicep | 60 ++ .../modules/_pids/_empty.bicep | 21 + .../_acrPullRoleAssignment.bicep | 53 ++ .../_agicRoleAssignment.bicep | 42 ++ .../_roleAssignmentinSubscription.bicep | 53 ++ .../modules/_uamiAndRoles.bicep | 43 ++ infra/azure.liberty.aks/parameters.json | 36 ++ infra/main.bicep | 48 ++ 18 files changed, 1880 insertions(+) create mode 100644 infra/azure.liberty.aks/mainTemplate.bicep create mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep create mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep create mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep create mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_keyvaultForGateway.bicep create mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep create mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds-networking.bicep create mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds-preflight.bicep create mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds-primary.bicep create mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds_enable_agic.bicep create mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep create mode 100644 infra/azure.liberty.aks/modules/_pids/_empty.bicep create mode 100644 infra/azure.liberty.aks/modules/_rolesAssignment/_acrPullRoleAssignment.bicep create mode 100644 infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep create mode 100644 infra/azure.liberty.aks/modules/_rolesAssignment/_roleAssignmentinSubscription.bicep create mode 100644 infra/azure.liberty.aks/modules/_uamiAndRoles.bicep create mode 100644 infra/azure.liberty.aks/parameters.json diff --git a/infra/azure.liberty.aks/mainTemplate.bicep b/infra/azure.liberty.aks/mainTemplate.bicep new file mode 100644 index 0000000..9929aa5 --- /dev/null +++ b/infra/azure.liberty.aks/mainTemplate.bicep @@ -0,0 +1,541 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +@description('The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated.') +param _artifactsLocation string = deployment().properties.templateLink.uri + +@description('The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured.') +@secure() +param _artifactsLocationSasToken string = '' + +@description('Location for all resources.') +param location string = resourceGroup().location + +@description('Flag indicating whether to create a new cluster or not') +param createCluster bool = true + +@description('The VM size of the cluster') +param vmSize string = 'Standard_DS2_v2' + +@description('The minimum node count of the cluster') +param minCount int = 1 + +@description('The maximum node count of the cluster') +param maxCount int = 5 + +@description('Name for the existing cluster') +param clusterName string = '' + +@description('Name for the resource group of the existing cluster') +param clusterRGName string = '' + +@description('Flag indicating whether to create a new ACR or not') +param createACR bool = true + +@description('Name for the existing ACR') +param acrName string = '' + +@description('Name for the resource group of the existing ACR') +param acrRGName string = '' + +@description('true to set up Application Gateway ingress.') +param enableAppGWIngress bool = false + +@description('VNET for Application Gateway.') +param vnetForApplicationGateway object = { + name: 'olaks-app-gateway-vnet' + resourceGroup: resourceGroup().name + addressPrefixes: [ + '172.16.0.0/24' + ] + addressPrefix: '172.16.0.0/24' + newOrExisting: 'new' + subnets: { + gatewaySubnet: { + name: 'olaks-gateway-subnet' + addressPrefix: '172.16.0.0/24' + startAddress: '172.16.0.4' + } + } +} +@description('To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the newOrExisting property when hideExisting is false') +param newOrExistingVnetForApplicationGateway string = 'new' +@description('To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the resourceGroup property when hideExisting is false') +param vnetRGNameForApplicationGateway string = 'vnet-contoso-rg-name' +@description('If true, configure Azure Application Gateway frontend IP with private IP.') +param appgwUsePrivateIP bool = false + +@description('DNS prefix for ApplicationGateway') +param dnsNameforApplicationGateway string = 'olgw' + +@allowed([ + 'haveCert' + 'haveKeyVault' + 'generateCert' +]) +@description('Three scenarios we support for deploying app gateway') +param appGatewayCertificateOption string = 'haveCert' + +@description('Public IP Name for the Application Gateway') +param appGatewayPublicIPAddressName string = 'gwip' + +@secure() +@description('The one-line, base64 string of the SSL certificate data.') +param appGatewaySSLCertData string = newGuid() + +@secure() +@description('The value of the password for the SSL Certificate') +param appGatewaySSLCertPassword string = newGuid() + +@description('Resource group name in current subscription containing the KeyVault') +param keyVaultResourceGroup string = 'kv-contoso-rg' + +@description('Existing Key Vault Name') +param keyVaultName string = 'kv-contoso' + +@description('Price tier for Key Vault.') +param keyVaultSku string = 'Standard' + +@description('The name of the secret in the specified KeyVault whose value is the SSL Certificate Data for Appliation Gateway frontend TLS/SSL.') +param keyVaultSSLCertDataSecretName string = 'kv-ssl-data' + +@description('The name of the secret in the specified KeyVault whose value is the password for the SSL Certificate of Appliation Gateway frontend TLS/SSL') +param keyVaultSSLCertPasswordSecretName string = 'kv-ssl-psw' + +@description('true to enable cookie based affinity.') +param enableCookieBasedAffinity bool = false + +@description('Flag indicating whether to deploy WebSphere Liberty Operator.') +param deployWLO bool = false + +@allowed([ + 'IBM WebSphere Application Server' + 'IBM WebSphere Application Server Liberty Core' + 'IBM WebSphere Application Server Network Deployment' +]) +@description('Product edition') +param edition string = 'IBM WebSphere Application Server' + +@allowed([ + 'Standalone' + 'IBM WebSphere Hybrid Edition' + 'IBM Cloud Pak for Applications' + 'IBM WebSphere Application Server Family Edition' +]) +@description('Entitlement source for the product') +param productEntitlementSource string = 'Standalone' + +@description('Flag indicating whether to deploy an application') +param deployApplication bool = false + +@description('The image path of the application') +param appImagePath string = '' + +@description('The number of application replicas to deploy') +param appReplicas int = 2 + +@description('Flag indicating whether to enable autoscaling for app deployment') +param autoScaling bool = false + +@description('The target average CPU utilization percentage for autoscaling') +param cpuUtilizationPercentage int = 80 + +@description('The minimum application replicas for autoscaling') +param minReplicas int = 1 + +@description('The maximum application replicas for autoscaling') +param maxReplicas int = 100 + +@description('The minimum required CPU core (millicore) over all the replicas for autoscaling') +param requestCPUMillicore int = 300 + +// TODo Updated +// param guidValue string = take(uniqueString(subscription().id, environmentName, location), 6) +param guidValue string = newGuid() + +var const_acrRGName = (createACR ? resourceGroup().name : acrRGName) +var const_appGatewaySSLCertOptionHaveCert = 'haveCert' +var const_appGatewaySSLCertOptionHaveKeyVault = 'haveKeyVault' +var const_appFrontendTlsSecretName = format('secret{0}', guidValue) +var const_appImage = format('{0}:{1}', const_appImageName, const_appImageTag) +var const_appImageName = format('image{0}', guidValue) +var const_appImagePath = (empty(appImagePath) ? 'NA' : ((const_appImagePathLen == 1) ? format('docker.io/library/{0}', appImagePath) : ((const_appImagePathLen == 2) ? format('docker.io/{0}', appImagePath) : appImagePath))) +var const_appImagePathLen = length(split(appImagePath, '/')) +var const_appImageTag = '1.0.0' +var const_appName = format('app{0}', guidValue) +var const_appProjName = 'default' +var const_arguments = format('{0} {1} {2} {3} {4} {5} {6} {7} {8}', const_clusterRGName, name_clusterName, name_acrName, deployApplication, const_appImagePath, const_appName, const_appProjName, const_appImage, appReplicas) +var const_azureSubjectName = format('{0}.{1}.{2}', name_dnsNameforApplicationGateway, location, 'cloudapp.azure.com') +var const_clusterRGName = (createCluster ? resourceGroup().name : clusterRGName) +var const_cmdToGetAcrLoginServer = format('az acr show -n {0} --query loginServer -o tsv', name_acrName) +var const_metric = productEntitlementSource == 'Standalone' || productEntitlementSource == 'IBM WebSphere Application Server Family Edition' ? 'Processor Value Unit (PVU)' : 'Virtual Processor Core (VPC)' +var const_newVnet = (vnetForApplicationGateway.newOrExisting == 'new') ? true : false +var name_acrName = createACR ? format('acr{0}', guidValue) : acrName +var name_appGatewayPublicIPAddressName = format('{0}{1}', appGatewayPublicIPAddressName, guidValue) +var name_clusterName = createCluster ? format('cluster{0}', guidValue) : clusterName +var name_dnsNameforApplicationGateway = format('{0}{1}', dnsNameforApplicationGateway, guidValue) +var name_keyVaultName = format('keyvault{0}', guidValue) +var name_prefilghtDsName = format('preflightds{0}', guidValue) +var name_primaryDsName = format('primaryds{0}', guidValue) +var name_subnet = vnetForApplicationGateway.subnets.gatewaySubnet.name +var name_vnet = vnetForApplicationGateway.name +var ref_subId = const_newVnet ? resourceId('Microsoft.Network/virtualNetworks/subnets', name_vnet, name_subnet) : existingSubnet.id + +var obj_uamiForDeploymentScript = { + type: 'UserAssigned' + userAssignedIdentities: { + '${uamiDeployment.outputs.uamiIdForDeploymentScript}': {} + } +} + +// Workaround arm-ttk test "Parameter Types Should Be Consistent" +var _appgwUsePrivateIP = appgwUsePrivateIP +var _appGatewaySubnetStartAddress = vnetForApplicationGateway.subnets.gatewaySubnet.startAddress +var _enableAppGWIngress = enableAppGWIngress +var _useExistingAppGatewaySSLCertificate = appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveCert + +module partnerCenterPid './modules/_pids/_empty.bicep' = { + name: 'pid-68a0b448-a573-4012-ab25-d5dc9842063e-partnercenter' + params: {} +} + +module uamiDeployment 'modules/_uamiAndRoles.bicep' = { + name: 'uami-deployment' + params: { + location: location + } +} + +module aksStartPid './modules/_pids/_empty.bicep' = { + name: '628cae16-c133-5a2e-ae93-2b44748012fe' + params: {} +} + +module preflightDsDeployment 'modules/_deployment-scripts/_ds-preflight.bicep' = { + name: name_prefilghtDsName + params: { + name: name_prefilghtDsName + location: location + _artifactsLocation: _artifactsLocation + _artifactsLocationSasToken: _artifactsLocationSasToken + identity: obj_uamiForDeploymentScript + createCluster: createCluster + aksClusterName: name_clusterName + aksClusterRGName: const_clusterRGName + enableAppGWIngress: enableAppGWIngress + vnetForApplicationGateway: vnetForApplicationGateway + appGatewayCertificateOption: appGatewayCertificateOption + keyVaultName: keyVaultName + keyVaultResourceGroup: keyVaultResourceGroup + keyVaultSSLCertDataSecretName: keyVaultSSLCertDataSecretName + keyVaultSSLCertPasswordSecretName: keyVaultSSLCertPasswordSecretName + appGatewaySSLCertData: appGatewaySSLCertData + appGatewaySSLCertPassword: appGatewaySSLCertPassword + vmSize: vmSize + deployApplication: deployApplication + sourceImagePath: const_appImagePath + } + dependsOn: [ + uamiDeployment + ] +} + +resource acrDeployment 'Microsoft.ContainerRegistry/registries@2023-07-01' = if (createACR) { + name: name_acrName + location: location + sku: { + name: 'Basic' + } + properties: { + adminUserEnabled: true + } + dependsOn: [ + preflightDsDeployment + ] +} + +// Get existing VNET +resource existingVnet 'Microsoft.Network/virtualNetworks@2023-11-01' existing = if (enableAppGWIngress && !const_newVnet) { + name: name_vnet + scope: resourceGroup(vnetForApplicationGateway.resourceGroup) +} + +// Get existing subnet +resource existingSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-11-01' existing = if (enableAppGWIngress && !const_newVnet) { + name: name_subnet + parent: existingVnet +} + +// To void space overlap with AKS Vnet, must deploy the Applciation Gateway VNet before AKS deployment +module vnetForAppgatewayDeployment 'modules/_azure-resoruces/_vnetAppGateway.bicep' = if (enableAppGWIngress) { + name: 'vnet-application-gateway' + params: { + location: location + nameSuffix: guidValue + newOrExistingVnetForApplicationGateway: newOrExistingVnetForApplicationGateway + vnetForApplicationGateway: vnetForApplicationGateway + vnetRGNameForApplicationGateway: vnetRGNameForApplicationGateway + } + dependsOn: [ + preflightDsDeployment + ] +} + +resource clusterDeployment 'Microsoft.ContainerService/managedClusters@2023-08-01' = if (createCluster) { + name: name_clusterName + location: location + properties: { + enableRBAC: true + dnsPrefix: format('{0}-dns', name_clusterName) + agentPoolProfiles: [ + { + name: 'agentpool' + osDiskSizeGB: 0 + enableAutoScaling: true + minCount: minCount + maxCount: maxCount + count: minCount + vmSize: vmSize + osType: 'Linux' + type: 'VirtualMachineScaleSets' + mode: 'System' + availabilityZones: preflightDsDeployment.outputs.aksAgentAvailabilityZones + } + ] + networkProfile: { + loadBalancerSku: 'standard' + networkPlugin: 'kubenet' + } + } + identity: { + type: 'SystemAssigned' + } + dependsOn: [ + acrDeployment + vnetForAppgatewayDeployment + ] +} + +module acrPullRoleAssignment 'modules/_rolesAssignment/_acrPullRoleAssignment.bicep' = { + name: 'assign-acrpull-role-to-kubelet-identity' + scope: resourceGroup(const_acrRGName) + params: { + aksClusterName: name_clusterName + aksClusterRGName: const_clusterRGName + acrName: name_acrName + acrRGName: const_acrRGName + } + dependsOn: [ + clusterDeployment + ] +} + +module appgwStartPid './modules/_pids/_empty.bicep' = if (enableAppGWIngress) { + name: '43c417c4-4f5a-555e-a9ba-b2d01d88de1f' + params: {} + dependsOn: [ + acrPullRoleAssignment + ] +} + +module appgwSecretDeployment 'modules/_azure-resoruces/_keyvaultForGateway.bicep' = if (enableAppGWIngress && (appGatewayCertificateOption != const_appGatewaySSLCertOptionHaveKeyVault)) { + name: 'appgateway-certificates-secrets-deployment' + params: { + certificateDataValue: appGatewaySSLCertData + certificatePasswordValue: appGatewaySSLCertPassword + identity: obj_uamiForDeploymentScript + location: location + sku: keyVaultSku + subjectName: format('CN={0}', const_azureSubjectName) + useExistingAppGatewaySSLCertificate: _useExistingAppGatewaySSLCertificate + keyVaultName: name_keyVaultName + } + dependsOn: [ + appgwStartPid + ] +} + +// get key vault object in a resource group +resource existingKeyvault 'Microsoft.KeyVault/vaults@2023-07-01' existing = if (enableAppGWIngress) { + name: (!enableAppGWIngress || appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault) ? keyVaultName : appgwSecretDeployment.outputs.keyVaultName + scope: resourceGroup(appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault ? keyVaultResourceGroup : resourceGroup().name) +} + +module queryPrivateIPFromSubnet 'modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep' = if (enableAppGWIngress && appgwUsePrivateIP) { + name: 'query-available-private-ip-for-app-gateway' + params: { + _artifactsLocation: _artifactsLocation + _artifactsLocationSasToken: _artifactsLocationSasToken + identity: obj_uamiForDeploymentScript + location: location + subnetId: ref_subId + + knownIP: _appGatewaySubnetStartAddress + } + dependsOn: [ + vnetForAppgatewayDeployment + ] +} + +module appgwDeployment 'modules/_azure-resoruces/_appgateway.bicep' = if (enableAppGWIngress) { + name: 'app-gateway-deployment' + params: { + dnsNameforApplicationGateway: name_dnsNameforApplicationGateway + gatewayPublicIPAddressName: name_appGatewayPublicIPAddressName + nameSuffix: guidValue + location: location + gatewaySubnetId: ref_subId + staticPrivateFrontentIP: _appgwUsePrivateIP ? queryPrivateIPFromSubnet.outputs.privateIP : '' + usePrivateIP: appgwUsePrivateIP + } + dependsOn: [ + appgwStartPid + queryPrivateIPFromSubnet + ] +} + +module enableAgic 'modules/_deployment-scripts/_ds_enable_agic.bicep' = if (enableAppGWIngress) { + name: 'enable-agic' + params: { + _artifactsLocation: _artifactsLocation + _artifactsLocationSasToken: _artifactsLocationSasToken + location: location + + identity: obj_uamiForDeploymentScript + + aksClusterName: name_clusterName + aksClusterRGName: const_clusterRGName + appgwName: _enableAppGWIngress ? appgwDeployment.outputs.appGatewayName : '' + } + dependsOn: [ + appgwDeployment + ] +} + +module agicRoleAssignment 'modules/_rolesAssignment/_agicRoleAssignment.bicep' = if (enableAppGWIngress) { + name: 'allow-agic-access-current-resource-group' + params: { + aksClusterName: name_clusterName + aksClusterRGName: const_clusterRGName + } + dependsOn: [ + enableAgic + ] +} + +module networkingDeployment 'modules/_deployment-scripts/_ds-networking.bicep' = if (enableAppGWIngress) { + name: 'networking-deployment' + params: { + _artifactsLocation: _artifactsLocation + _artifactsLocationSasToken: _artifactsLocationSasToken + location: location + + identity: obj_uamiForDeploymentScript + + appgwCertificateOption: appGatewayCertificateOption + appgwFrontendSSLCertData: existingKeyvault.getSecret((!enableAppGWIngress || appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault) ? keyVaultSSLCertDataSecretName : appgwSecretDeployment.outputs.sslCertDataSecretName) + appgwFrontendSSLCertPsw: existingKeyvault.getSecret((!enableAppGWIngress || appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault) ? keyVaultSSLCertPasswordSecretName : appgwSecretDeployment.outputs.sslCertPwdSecretName) + + appgwName: _enableAppGWIngress ? appgwDeployment.outputs.appGatewayName : '' + + aksClusterRGName: const_clusterRGName + aksClusterName: name_clusterName + appFrontendTlsSecretName: const_appFrontendTlsSecretName + appProjName: const_appProjName + } + dependsOn: [ + appgwSecretDeployment + agicRoleAssignment + ] +} + +module appgwEndPid './modules/_pids/_empty.bicep' = if (enableAppGWIngress) { + name: 'dfa75d32-05de-5635-9833-b004cabcd378' + params: {} + dependsOn: [ + networkingDeployment + ] +} + +module primaryDsDeployment 'modules/_deployment-scripts/_ds-primary.bicep' = { + name: name_primaryDsName + params: { + name: name_primaryDsName + location: location + _artifactsLocation: _artifactsLocation + _artifactsLocationSasToken: _artifactsLocationSasToken + identity: obj_uamiForDeploymentScript + arguments: const_arguments + acrRGName: const_acrRGName + deployWLO: deployWLO + edition: edition + productEntitlementSource: productEntitlementSource + metric: const_metric + deployApplication: deployApplication + enableAppGWIngress: enableAppGWIngress + appFrontendTlsSecretName: const_appFrontendTlsSecretName + enableCookieBasedAffinity: enableCookieBasedAffinity + appgwUsePrivateIP: appgwUsePrivateIP + autoScaling: autoScaling + cpuUtilizationPercentage: cpuUtilizationPercentage + minReplicas: minReplicas + maxReplicas: maxReplicas + requestCPUMillicore: requestCPUMillicore + } + dependsOn: [ + acrPullRoleAssignment + appgwEndPid + ] +} + +module aksEndPid './modules/_pids/_empty.bicep' = { + name: '59f5f6da-0a6d-587d-b23c-177108cd8bbf' + params: {} + dependsOn: [ + primaryDsDeployment + ] +} + +module autoscalingPid './modules/_pids/_empty.bicep' = if (deployApplication && autoScaling) { + name: '7a4e4f27-dcea-5207-86ed-e7c7de1ccd34' + params: {} + dependsOn: [ + aksEndPid + ] +} + +output appHttpEndpoint string = deployApplication ? (enableAppGWIngress ? appgwDeployment.outputs.appGatewayURL : primaryDsDeployment.outputs.appEndpoint ) : '' +output appHttpsEndpoint string = deployApplication && enableAppGWIngress ? appgwDeployment.outputs.appGatewaySecuredURL : '' +output clusterName string = name_clusterName +output clusterRGName string = const_clusterRGName +output acrName string = name_acrName +output cmdToGetAcrLoginServer string = const_cmdToGetAcrLoginServer +output appNamespaceName string = const_appProjName +output appName string = deployApplication ? const_appName : '' +output appImage string = deployApplication ? const_appImage : '' +output cmdToConnectToCluster string = format('az aks get-credentials -g {0} -n {1} --admin', const_clusterRGName, name_clusterName) +output cmdToGetAppInstance string = deployApplication ? format('kubectl get openlibertyapplication {0}', const_appName) : '' +output cmdToGetAppDeployment string = deployApplication ? format('kubectl get deployment {0}', const_appName) : '' +output cmdToGetAppPods string = deployApplication ? 'kubectl get pod' : '' +output cmdToGetAppService string = deployApplication ? format('kubectl get service {0}', const_appName) : '' +output cmdToLoginInRegistry string = format('az acr login -n {0}', name_acrName) +output cmdToPullImageFromRegistry string = deployApplication ? format('docker pull $({0})/{1}', const_cmdToGetAcrLoginServer, const_appImage) : '' +output cmdToTagImageWithRegistry string = format('docker tag $({0})/', const_cmdToGetAcrLoginServer) +output cmdToPushImageToRegistry string = format('docker push $({0})/', const_cmdToGetAcrLoginServer) +output appDeploymentYaml string = deployApplication? format('echo "{0}" | base64 -d', primaryDsDeployment.outputs.appDeploymentYaml) : '' +output appDeploymentTemplateYaml string = !deployApplication ? format('echo "{0}" | base64 -d', primaryDsDeployment.outputs.appDeploymentYaml) : '' +output cmdToUpdateOrCreateApplication string = 'kubectl apply -f ' diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep new file mode 100644 index 0000000..43c6c78 --- /dev/null +++ b/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep @@ -0,0 +1,183 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +@description('DNS for ApplicationGateway') +param dnsNameforApplicationGateway string = format('olgw{0}', guidValue) +@description('Public IP Name for the Application Gateway') +param gatewayPublicIPAddressName string = format('gwip{0}', guidValue) +param nameSuffix string = '' +param location string +param gatewaySubnetId string = '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/resourcegroupname/providers/Microsoft.Network/virtualNetworks/vnetname/subnets/subnetname' +param staticPrivateFrontentIP string = '10.0.0.1' +param usePrivateIP bool = false +param guidValue string = newGuid() + +var const_nameSuffix = empty(nameSuffix) ? guidValue : nameSuffix +var name_appGateway = format('appgw{0}', const_nameSuffix) +var name_backendAddressPool = 'myGatewayBackendPool' +var name_frontEndIPConfig = 'appGwPublicFrontendIp' +var name_frontEndPrivateIPConfig = 'appGwPrivateFrontendIp' +var name_httpListener = 'HTTPListener' +var name_httpPort = 'httpport' +var name_httpSetting = 'myHTTPSetting' +var ref_backendAddressPool = resourceId('Microsoft.Network/applicationGateways/backendAddressPools', name_appGateway, name_backendAddressPool) +var ref_backendHttpSettings = resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', name_appGateway, name_httpSetting) +var ref_frontendHTTPPort = resourceId('Microsoft.Network/applicationGateways/frontendPorts', name_appGateway, name_httpPort) +var ref_frontendIPConfiguration = resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', name_appGateway, name_frontEndIPConfig) +var ref_httpListener = resourceId('Microsoft.Network/applicationGateways/httpListeners', name_appGateway, name_httpListener) +var ref_publicIPAddress = resourceId('Microsoft.Network/publicIPAddresses', gatewayPublicIPAddressName) +var obj_frontendIPConfigurations1 = [ + { + name: name_frontEndIPConfig + properties: { + publicIPAddress: { + id: ref_publicIPAddress + } + } + } +] +var obj_frontendIPConfigurations2 = [ + { + name: name_frontEndIPConfig + properties: { + publicIPAddress: { + id: ref_publicIPAddress + } + } + } + { + name: name_frontEndPrivateIPConfig + properties: { + privateIPAllocationMethod: 'Static' + privateIPAddress: staticPrivateFrontentIP + subnet: { + id: gatewaySubnetId + } + } + } +] + +resource gatewayPublicIP 'Microsoft.Network/publicIPAddresses@2023-11-01' = { + name: gatewayPublicIPAddressName + sku: { + name: 'Standard' + } + location: location + properties: { + publicIPAllocationMethod: 'Static' + dnsSettings: { + domainNameLabel: dnsNameforApplicationGateway + } + } +} + +resource wafv2AppGateway 'Microsoft.Network/applicationGateways@2023-11-01' = { + name: name_appGateway + location: location + tags: { + 'managed-by-k8s-ingress': 'true' + } + properties: { + sku: { + name: 'WAF_v2' + tier: 'WAF_v2' + } + gatewayIPConfigurations: [ + { + name: 'appGatewayIpConfig' + properties: { + subnet: { + id: gatewaySubnetId + } + } + } + ] + frontendIPConfigurations: usePrivateIP ? obj_frontendIPConfigurations2 : obj_frontendIPConfigurations1 + frontendPorts: [ + { + name: name_httpPort + properties: { + port: 80 + } + } + ] + backendAddressPools: [ + { + name: 'myGatewayBackendPool' + } + ] + httpListeners: [ + { + name: name_httpListener + properties: { + protocol: 'Http' + frontendIPConfiguration: { + id: ref_frontendIPConfiguration + } + frontendPort: { + id: ref_frontendHTTPPort + } + } + } + ] + backendHttpSettingsCollection: [ + { + name: name_httpSetting + properties: { + port: 80 + protocol: 'Http' + } + } + ] + requestRoutingRules: [ + { + name: 'HTTPRoutingRule' + properties: { + priority: 3 + httpListener: { + id: ref_httpListener + } + backendAddressPool: { + id: ref_backendAddressPool + } + backendHttpSettings: { + id: ref_backendHttpSettings + } + } + } + ] + webApplicationFirewallConfiguration: { + enabled: true + firewallMode: 'Prevention' + ruleSetType: 'OWASP' + ruleSetVersion: '3.0' + } + enableHttp2: false + autoscaleConfiguration: { + minCapacity: 2 + maxCapacity: 3 + } + } + dependsOn: [ + gatewayPublicIP + ] +} + +output appGatewayAlias string = usePrivateIP ? staticPrivateFrontentIP : reference(gatewayPublicIP.id).dnsSettings.fqdn +output appGatewayName string = name_appGateway +output appGatewayURL string = uri(format('http://{0}/', usePrivateIP ? staticPrivateFrontentIP : reference(gatewayPublicIP.id).dnsSettings.fqdn), '') +output appGatewaySecuredURL string = uri(format('https://{0}/', usePrivateIP ? staticPrivateFrontentIP : reference(gatewayPublicIP.id).dnsSettings.fqdn), '') diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep new file mode 100644 index 0000000..223d4f3 --- /dev/null +++ b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep @@ -0,0 +1,84 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +@description('Secret name of certificate data.') +param certificateDataName string = 'myIdentityKeyStoreData' + +@secure() +@description('Certificate data to store in the secret') +param certificateDataValue string = newGuid() + +@description('Secret name of certificate password.') +param certificatePswSecretName string = 'myIdentityKeyStorePsw' + +@secure() +@description('Certificate password to store in the secret') +param certificatePasswordValue string = newGuid() + +@description('Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') +param enabledForTemplateDeployment bool = true + +@description('Name of the vault') +param keyVaultName string = 'kv-${uniqueString('utcValue')}' + +param location string + +@description('Price tier for Key Vault.') +param sku string = 'Standard' + +param utcValue string = utcNow() + +resource keyvault 'Microsoft.KeyVault/vaults@2023-07-01' = { + name: keyVaultName + location: location + properties: { + accessPolicies: [] + enabledForTemplateDeployment: enabledForTemplateDeployment + sku: { + name: sku + family: 'A' + } + tenantId: subscription().tenantId + } + tags:{ + 'managed-by-azure-liberty-aks': utcValue + } +} + +resource secretForCertificate 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = { + name: format('{0}/{1}', keyVaultName, certificateDataName) + properties: { + value: certificateDataValue + } + dependsOn: [ + keyvault + ] +} + +resource secretForCertPassword 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = { + name: format('{0}/{1}', keyVaultName, certificatePswSecretName) + properties: { + value: certificatePasswordValue + } + dependsOn: [ + keyvault + ] +} + +output keyVaultName string = keyVaultName +output sslCertDataSecretName string = certificateDataName +output sslCertPwdSecretName string = certificatePswSecretName diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep new file mode 100644 index 0000000..1c67b9a --- /dev/null +++ b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep @@ -0,0 +1,96 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +@description('Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported.') +param identity object = {} + +@description('Used to name the new Azure Key Vault resoure.') +param keyVaultName string = 'kv-${uniqueString('utcValue')}' + +param location string + +@description('Access permission of the key vault, will applied to all access policies.') +param permission object = { + certificates: [ + 'get' + 'list' + 'update' + 'create' + ] +} + +@description('Used to name the new certificate resource.') +param secretName string = 'mySelfSignedCertificate' + +@description('Price tier for Key Vault.') +param sku string = 'Standard' + +@description('Subject name to create a new certificate, example: \'CN=contoso.com\'.') +param subjectName string = 'contoso.xyz' +param utcValue string = utcNow() + +var const_identityId = substring(string(identity.userAssignedIdentities), indexOf(string(identity.userAssignedIdentities), '"') + 1, lastIndexOf(string(identity.userAssignedIdentities), '"') - (indexOf(string(identity.userAssignedIdentities), '"') + 1)) + +resource keyvault 'Microsoft.KeyVault/vaults@2023-07-01' = { + name: keyVaultName + location: location + properties: { + sku: { + family: 'A' + name: sku + } + tenantId: subscription().tenantId + accessPolicies: [ + { + // Must specify API version of identity. + objectId: reference(const_identityId, '2023-01-31').principalId + tenantId: subscription().tenantId + permissions: permission + } + ] + enabledForDeployment: false + enabledForDiskEncryption: false + enabledForTemplateDeployment: true + enableSoftDelete: true + } + tags:{ + 'managed-by-azure-liberty-aks': utcValue + } +} + +resource createAddCertificate 'Microsoft.Resources/deploymentScripts@2023-08-01' = { + name: 'ds-create-add-appgw-certificate' + location: location + identity: identity + kind: 'AzurePowerShell' + properties: { + forceUpdateTag: utcValue + azPowerShellVersion: '11.5' + timeout: 'PT30M' + arguments: format(' -vaultName {0} -certificateName {1} -subjectName {2}', keyVaultName, secretName, subjectName) + scriptContent: '\n param(\n [string] [Parameter(Mandatory=$true)] $vaultName,\n [string] [Parameter(Mandatory=$true)] $certificateName,\n [string] [Parameter(Mandatory=$true)] $subjectName\n )\n\n $ErrorActionPreference = \'Stop\'\n $DeploymentScriptOutputs = @{}\n\n $existingCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName\n\n if ($existingCert -and $existingCert.Certificate.Subject -eq $subjectName) {\n\n Write-Host \'Certificate $certificateName in vault $vaultName is already present.\'\n\n $DeploymentScriptOutputs[\'certThumbprint\'] = $existingCert.Thumbprint\n $existingCert | Out-String\n }\n else {\n $policy = New-AzKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths 12 -Verbose\n\n # private key is added as a secret that can be retrieved in the ARM template\n Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy -Verbose\n\n $newCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName\n\n # it takes a few seconds for KeyVault to finish\n $tries = 0\n do {\n Write-Host \'Waiting for certificate creation completion...\'\n Start-Sleep -Seconds 10\n $operation = Get-AzKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName\n $tries++\n\n if ($operation.Status -eq \'failed\')\n {\n throw \'Creating certificate $certificateName in vault $vaultName failed with error $($operation.ErrorMessage)\'\n }\n\n if ($tries -gt 120)\n {\n throw \'Timed out waiting for creation of certificate $certificateName in vault $vaultName\'\n }\n } while ($operation.Status -ne \'completed\')\n\n $DeploymentScriptOutputs[\'certThumbprint\'] = $newCert.Thumbprint\n $newCert | Out-String\n }\n ' + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + } + dependsOn: [ + keyvault + ] +} + +output keyVaultName string = keyVaultName +output secretName string = secretName +output identityId string = const_identityId diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvaultForGateway.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvaultForGateway.bicep new file mode 100644 index 0000000..67eb68f --- /dev/null +++ b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvaultForGateway.bicep @@ -0,0 +1,85 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +@secure() +@description('Certificate data to store in the secret') +param certificateDataValue string = newGuid() + +@secure() +@description('Certificate password to store in the secret') +param certificatePasswordValue string = newGuid() + +@description('Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') +param enabledForTemplateDeployment bool = true + +param identity object = {} +param location string +param permission object = { + certificates: [ + 'get' + 'list' + 'update' + 'create' + ] +} + +@description('Price tier for Key Vault.') +param sku string = 'Standard' + +@description('Subject name to create a certificate.') +param subjectName string = '' + +@description('If false, will create a certificate.') +param useExistingAppGatewaySSLCertificate bool = false + +@description('Current deployment time. Used as a tag in deployment script.') +param keyVaultName string = 'GEN_UNIQUE' + +var name_sslCertSecretName = 'myAppGatewaySSLCert' +var name_sslCertPasswordSecretName = 'myAppGatewaySSLCertPassword' + +module keyVaultwithSelfSignedAppGatewaySSLCert '_keyvault/_keyvaultWithNewCert.bicep' = if (!useExistingAppGatewaySSLCertificate) { + name: 'kv-appgw-selfsigned-certificate-deployment' + params: { + identity: identity + keyVaultName: keyVaultName + location: location + permission: permission + subjectName: subjectName + sku: sku + } +} + +module keyVaultwithExistingAppGatewaySSLCert '_keyvault/_keyvaultWithExistingCert.bicep' = if (useExistingAppGatewaySSLCertificate) { + name: 'kv-appgw-existing-certificate-deployment' + params: { + certificateDataName: name_sslCertSecretName + certificateDataValue: certificateDataValue + certificatePswSecretName: name_sslCertPasswordSecretName + certificatePasswordValue: certificatePasswordValue + enabledForTemplateDeployment: enabledForTemplateDeployment + keyVaultName: keyVaultName + location: location + sku: sku + } +} + +output keyVaultName string = (useExistingAppGatewaySSLCertificate ? keyVaultwithExistingAppGatewaySSLCert.outputs.keyVaultName : keyVaultwithSelfSignedAppGatewaySSLCert.outputs.keyVaultName) +output sslCertDataSecretName string = (useExistingAppGatewaySSLCertificate ? keyVaultwithExistingAppGatewaySSLCert.outputs.sslCertDataSecretName : keyVaultwithSelfSignedAppGatewaySSLCert.outputs.secretName) +output sslCertPwdSecretName string = (useExistingAppGatewaySSLCertificate ? keyVaultwithExistingAppGatewaySSLCert.outputs.sslCertPwdSecretName: keyVaultwithSelfSignedAppGatewaySSLCert.outputs.secretName) +output sslBackendCertDataSecretName string = '' + diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep new file mode 100644 index 0000000..0588f27 --- /dev/null +++ b/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep @@ -0,0 +1,112 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +param location string +param newOrExistingVnetForApplicationGateway string +param vnetForApplicationGateway object = { + name: 'olaks-app-gateway-vnet' + resourceGroup: resourceGroup().name + addressPrefixes: [ + '172.16.0.0/24' + ] + addressPrefix: '172.16.0.0/24' + newOrExisting: 'new' + subnets: { + gatewaySubnet: { + name: 'olaks-gateway-subnet' + addressPrefix: '172.16.0.0/24' + startAddress: '172.16.0.4' + } + } +} +param vnetRGNameForApplicationGateway string +param nameSuffix string = '' +param guidValue string = 'vgateway' + +var const_nameSuffix = empty(nameSuffix) ? guidValue : nameSuffix +var const_subnetAddressPrefixes = vnetForApplicationGateway.subnets.gatewaySubnet.addressPrefix +var const_vnetAddressPrefixes = vnetForApplicationGateway.addressPrefixes +var const_newVnet = (vnetForApplicationGateway.newOrExisting == 'new') ? true : false +var name_nsg = format('olaks-nsg{0}', const_nameSuffix) +var name_subnet = vnetForApplicationGateway.subnets.gatewaySubnet.name +var name_vnet = vnetForApplicationGateway.name + +// Create new network security group. +resource nsg 'Microsoft.Network/networkSecurityGroups@2023-11-01' = if (const_newVnet) { + name: name_nsg + location: location + properties: { + securityRules: [ + { + properties: { + protocol: 'Tcp' + sourcePortRange: '*' + destinationPortRange: '65200-65535' + sourceAddressPrefix: 'GatewayManager' + destinationAddressPrefix: '*' + access: 'Allow' + priority: 500 + direction: 'Inbound' + } + name: 'ALLOW_APPGW' + } + { + properties: { + protocol: 'Tcp' + sourcePortRange: '*' + sourceAddressPrefix: 'Internet' + destinationAddressPrefix: '*' + access: 'Allow' + priority: 510 + direction: 'Inbound' + destinationPortRanges: [ + '80' + '443' + ] + } + name: 'ALLOW_HTTP_ACCESS' + } + ] + } +} + +// Create new VNET and subnet. +resource newVnet 'Microsoft.Network/virtualNetworks@2023-11-01' = if (const_newVnet) { + name: name_vnet + location: location + properties: { + addressSpace: { + addressPrefixes: const_vnetAddressPrefixes + } + subnets: [ + { + name: name_subnet + properties: { + addressPrefix: const_subnetAddressPrefixes + networkSecurityGroup: { + id: nsg.id + } + } + } + ] + } +} + +// To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the resourceGroup property when hideExisting is false +output vnetResourceGroupName string = vnetRGNameForApplicationGateway +// To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the newOrExisting property when hideExisting is false +output newOrExisting string = newOrExistingVnetForApplicationGateway diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-networking.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-networking.bicep new file mode 100644 index 0000000..e004f2e --- /dev/null +++ b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-networking.bicep @@ -0,0 +1,101 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +param _artifactsLocation string = deployment().properties.templateLink.uri +@secure() +param _artifactsLocationSasToken string = '' +param location string + +param identity object = {} + +@allowed([ + 'haveCert' + 'haveKeyVault' + 'generateCert' +]) +@description('Three scenarios we support for deploying app gateway') +param appgwCertificateOption string = 'haveCert' +@secure() +param appgwFrontendSSLCertData string = newGuid() +@secure() +param appgwFrontendSSLCertPsw string = newGuid() + +param appgwName string = 'appgw-contoso' + +param aksClusterRGName string = 'aks-contoso-rg' +param aksClusterName string = 'aks-contoso' +param appFrontendTlsSecretName string = 'tls-secret' +param appProjName string = 'default' + +param utcValue string = utcNow() + +var const_scriptLocation = uri(_artifactsLocation, 'scripts/') + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { + name: 'ds-networking-deployment' + location: location + kind: 'AzureCLI' + identity: identity + properties: { + azCliVersion: '2.15.0' + environmentVariables: [ + { + name: 'AKS_CLUSTER_RG_NAME' + value: aksClusterRGName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'CURRENT_RG_NAME' + value: resourceGroup().name + } + { + name: 'APP_GW_NAME' + value: appgwName + } + { + name: 'APP_GW_FRONTEND_SSL_CERT_DATA' + value: appgwFrontendSSLCertData + } + { + name: 'APP_GW_FRONTEND_SSL_CERT_PSW' + secureValue: appgwFrontendSSLCertPsw + } + { + name: 'APP_GW_CERTIFICATE_OPTION' + value: appgwCertificateOption + } + { + name: 'APP_FRONTEND_TLS_SECRET_NAME' + value: appFrontendTlsSecretName + } + { + name: 'APP_PROJ_NAME' + value: appProjName + } + ] + primaryScriptUri: uri(const_scriptLocation, 'createAppGatewayIngress.sh${_artifactsLocationSasToken}') + supportingScriptUris: [ + uri(const_scriptLocation, 'utility.sh${_artifactsLocationSasToken}') + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-preflight.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-preflight.bicep new file mode 100644 index 0000000..0b813db --- /dev/null +++ b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-preflight.bicep @@ -0,0 +1,130 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +param _artifactsLocation string = deployment().properties.templateLink.uri +@secure() +param _artifactsLocationSasToken string = '' +param location string +param name string = '' +param identity object = {} +param createCluster bool = true +param aksClusterName string = '' +param aksClusterRGName string = '' +param enableAppGWIngress bool = false +param vnetForApplicationGateway object = {} +param appGatewayCertificateOption string = '' +param keyVaultName string = '' +param keyVaultResourceGroup string = '' +param keyVaultSSLCertDataSecretName string = '' +param keyVaultSSLCertPasswordSecretName string = '' +@secure() +param appGatewaySSLCertData string = '' +@secure() +param appGatewaySSLCertPassword string = '' +param vmSize string +param deployApplication bool +param sourceImagePath string + +param utcValue string = utcNow() + +var const_scriptLocation = uri(_artifactsLocation, 'scripts/') + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { + name: name + location: location + kind: 'AzureCLI' + identity: identity + properties: { + azCliVersion: '2.53.0' + environmentVariables: [ + { + name: 'CREATE_CLUSTER' + value: string(createCluster) + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'AKS_CLUSTER_RG_NAME' + value: aksClusterRGName + } + { + name: 'ENABLE_APPLICATION_GATEWAY_INGRESS_CONTROLLER' + value: string(enableAppGWIngress) + } + { + name: 'VNET_FOR_APPLICATIONGATEWAY' + value: string(vnetForApplicationGateway) + } + { + name: 'APPLICATION_GATEWAY_CERTIFICATE_OPTION' + value: appGatewayCertificateOption + } + { + name: 'APPLICATION_GATEWAY_SSL_KEYVAULT_NAME' + value: keyVaultName + } + { + name: 'APPLICATION_GATEWAY_SSL_KEYVAULT_RESOURCEGROUP' + value: keyVaultResourceGroup + } + { + name: 'APPLICATION_GATEWAY_SSL_KEYVAULT_FRONTEND_CERT_DATA_SECRET_NAME' + value: keyVaultSSLCertDataSecretName + } + { + name: 'APPLICATION_GATEWAY_SSL_KEYVAULT_FRONTEND_CERT_PASSWORD_SECRET_NAME' + value: keyVaultSSLCertPasswordSecretName + } + { + name: 'APPLICATION_GATEWAY_SSL_FRONTEND_CERT_DATA' + secureValue: appGatewaySSLCertData + } + { + name: 'APPLICATION_GATEWAY_SSL_FRONTEND_CERT_PASSWORD' + secureValue: appGatewaySSLCertPassword + } + { + name: 'LOCATION' + value: location + } + { + name: 'VM_SIZE' + value: vmSize + } + { + name: 'DEPLOY_APPLICATION' + value: string(deployApplication) + } + { + name: 'SOURCE_IMAGE_PATH' + value: sourceImagePath + } + ] + primaryScriptUri: uri(const_scriptLocation, 'preflight.sh${_artifactsLocationSasToken}') + supportingScriptUris: [ + uri(const_scriptLocation, 'utility.sh${_artifactsLocationSasToken}') + ] + + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} + +output aksAgentAvailabilityZones array = json(deploymentScript.properties.outputs.agentAvailabilityZones) diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-primary.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-primary.bicep new file mode 100644 index 0000000..1d754ab --- /dev/null +++ b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-primary.bicep @@ -0,0 +1,129 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +param _artifactsLocation string = deployment().properties.templateLink.uri +@secure() +param _artifactsLocationSasToken string = '' +param location string +param name string = '' +param identity object = {} +param arguments string = '' +param acrRGName string = '' +param deployWLO bool = false +param edition string = 'IBM WebSphere Application Server' +param productEntitlementSource string = 'Standalone' +param metric string = 'Processor Value Unit (PVU)' +param deployApplication bool = false +param enableAppGWIngress bool = false +param appFrontendTlsSecretName string ='' +param enableCookieBasedAffinity bool = false +param appgwUsePrivateIP bool = false +param autoScaling bool = false +param cpuUtilizationPercentage int = 80 +param minReplicas int = 1 +param maxReplicas int = 100 +param requestCPUMillicore int = 300 + +param utcValue string = utcNow() + +var const_scriptLocation = uri(_artifactsLocation, 'scripts/') + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { + name: name + location: location + kind: 'AzureCLI' + identity: identity + properties: { + azCliVersion: '2.15.0' + environmentVariables: [ + { + name: 'ACR_RG_NAME' + value: string(acrRGName) + } + { + name: 'ENABLE_APP_GW_INGRESS' + value: string(enableAppGWIngress) + } + { + name: 'APP_FRONTEND_TLS_SECRET_NAME' + value: string(appFrontendTlsSecretName) + } + { + name: 'ENABLE_COOKIE_BASED_AFFINITY' + value: string(enableCookieBasedAffinity) + } + { + name: 'APP_GW_USE_PRIVATE_IP' + value: string(appgwUsePrivateIP) + } + { + name: 'DEPLOY_WLO' + value: string(deployWLO) + } + { + name: 'WLA_EDITION' + value: string(edition) + } + { + name: 'WLA_PRODUCT_ENTITLEMENT_SOURCE' + value: string(productEntitlementSource) + } + { + name: 'WLA_METRIC' + value: string(metric) + } + { + name: 'AUTO_SCALING' + value: string(autoScaling) + } + { + name: 'CPU_UTILIZATION_PERCENTAGE' + value: string(cpuUtilizationPercentage) + } + { + name: 'MIN_REPLICAS' + value: string(minReplicas) + } + { + name: 'MAX_REPLICAS' + value: string(maxReplicas) + } + { + name: 'REQUEST_CPU_MILLICORE' + value: string(requestCPUMillicore) + } + ] + arguments: arguments + primaryScriptUri: uri(const_scriptLocation, 'install.sh${_artifactsLocationSasToken}') + supportingScriptUris: [ + uri(const_scriptLocation, 'open-liberty-application.yaml.template${_artifactsLocationSasToken}') + uri(const_scriptLocation, 'open-liberty-application-agic.yaml.template${_artifactsLocationSasToken}') + uri(const_scriptLocation, 'websphere-liberty-application.yaml.template${_artifactsLocationSasToken}') + uri(const_scriptLocation, 'websphere-liberty-application-agic.yaml.template${_artifactsLocationSasToken}') + uri(const_scriptLocation, 'open-liberty-application-autoscaling.yaml.template${_artifactsLocationSasToken}') + uri(const_scriptLocation, 'open-liberty-application-agic-autoscaling.yaml.template${_artifactsLocationSasToken}') + uri(const_scriptLocation, 'websphere-liberty-application-autoscaling.yaml.template${_artifactsLocationSasToken}') + uri(const_scriptLocation, 'websphere-liberty-application-agic-autoscaling.yaml.template${_artifactsLocationSasToken}') + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} + +output appEndpoint string = (deployApplication && !enableAppGWIngress) ? deploymentScript.properties.outputs.appEndpoint : '' +output appDeploymentYaml string = deploymentScript.properties.outputs.appDeploymentYaml diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_enable_agic.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_enable_agic.bicep new file mode 100644 index 0000000..e7cf2bc --- /dev/null +++ b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_enable_agic.bicep @@ -0,0 +1,63 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +param _artifactsLocation string = deployment().properties.templateLink.uri +@secure() +param _artifactsLocationSasToken string = '' +param aksClusterName string = '' +param aksClusterRGName string = '' +param appgwName string = 'appgw-contoso' +param identity object = {} +param location string +param utcValue string = utcNow() + +var const_scriptLocation = uri(_artifactsLocation, 'scripts/') + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { + name: 'ds-enable-agic' + location: location + kind: 'AzureCLI' + identity: identity + properties: { + azCliVersion: '2.33.1' + primaryScriptUri: uri(const_scriptLocation, 'enableAgic.sh${_artifactsLocationSasToken}') + supportingScriptUris: [ + uri(const_scriptLocation, 'utility.sh${_artifactsLocationSasToken}') + ] + environmentVariables: [ + { + name: 'AKS_CLUSTER_RG_NAME' + value: aksClusterRGName + } + { + name: 'AKS_CLUSTER_NAME' + value: aksClusterName + } + { + name: 'APP_GW_NAME' + value: appgwName + } + { + name: 'CURRENT_RG_NAME' + value: resourceGroup().name + } + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep new file mode 100644 index 0000000..6cf38e7 --- /dev/null +++ b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep @@ -0,0 +1,60 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +param _artifactsLocation string = deployment().properties.templateLink.uri +@secure() +param _artifactsLocationSasToken string = '' + +param subnetId string = '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/resourcegroupname/providers/Microsoft.Network/virtualNetworks/vnetname/subnets/subnetname' +param knownIP string = '10.0.0.1' + +param identity object = {} +param location string +param utcValue string = utcNow() + +var const_azcliVersion='2.15.0' +var const_deploymentName='ds-query-private-ip' +var const_scriptLocation = uri(_artifactsLocation, 'scripts/') + +resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { + name: const_deploymentName + location: location + kind: 'AzureCLI' + identity: identity + properties: { + azCliVersion: const_azcliVersion + environmentVariables: [ + { + name: 'SUBNET_ID' + value: subnetId + } + { + name: 'KNOWN_IP' + value: knownIP + } + ] + primaryScriptUri: uri(const_scriptLocation, 'queryPrivateIPForAppGateway.sh${_artifactsLocationSasToken}') + supportingScriptUris: [ + uri(const_scriptLocation, 'utility.sh${_artifactsLocationSasToken}') + ] + cleanupPreference: 'OnSuccess' + retentionInterval: 'P1D' + forceUpdateTag: utcValue + } +} + +output privateIP string = string(reference(const_deploymentName).outputs.privateIP) diff --git a/infra/azure.liberty.aks/modules/_pids/_empty.bicep b/infra/azure.liberty.aks/modules/_pids/_empty.bicep new file mode 100644 index 0000000..d844be7 --- /dev/null +++ b/infra/azure.liberty.aks/modules/_pids/_empty.bicep @@ -0,0 +1,21 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +// Workaround to arm-ttk complain: Parameters property must exist in the template +param name string = 'This is an empty deployment' + +output name string = name diff --git a/infra/azure.liberty.aks/modules/_rolesAssignment/_acrPullRoleAssignment.bicep b/infra/azure.liberty.aks/modules/_rolesAssignment/_acrPullRoleAssignment.bicep new file mode 100644 index 0000000..81c07ff --- /dev/null +++ b/infra/azure.liberty.aks/modules/_rolesAssignment/_acrPullRoleAssignment.bicep @@ -0,0 +1,53 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +param aksClusterName string = '' +param aksClusterRGName string = '' +param acrName string = '' +param acrRGName string = '' + +var const_APIVersion = '2020-12-01' +// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles +var const_roleDefinitionIdOfAcrPull = '7f951dda-4ed3-4680-a7ca-43fe172d538d' + +resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-08-01' existing = { + name: aksClusterName + scope: resourceGroup(aksClusterRGName) +} + +resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = { + name: acrName + scope: resourceGroup(acrRGName) +} + +// https://github.com/Azure/azure-quickstart-templates/issues/4205 +resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: guid('${aksCluster.id}${acr.id}ForKubeletIdentity') + properties: { + description: 'Assign Resource Group Contributor role to User Assigned Managed Identity ' + principalId: reference(aksCluster.id, const_APIVersion , 'Full').properties.identityProfile.kubeletidentity.objectId + principalType: 'ServicePrincipal' + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', const_roleDefinitionIdOfAcrPull) + } + dependsOn: [ + aksCluster + acr + ] +} + +output aksClusterId string = aksCluster.id +output acrId string = acr.id diff --git a/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep b/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep new file mode 100644 index 0000000..b2058fc --- /dev/null +++ b/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep @@ -0,0 +1,42 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +param aksClusterName string = '' +param aksClusterRGName string = '' + +var const_APIVersion = '2020-12-01' +var name_appGwContributorRoleAssignmentName = guid('${resourceGroup().id}ForApplicationGateway') +// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles +var const_roleDefinitionIdOfContributor = 'b24988ac-6180-42a0-ab88-20f7382dd24c' + +resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-08-01' existing = { + name: aksClusterName + scope: resourceGroup(aksClusterRGName) +} + +resource agicUamiRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: name_appGwContributorRoleAssignmentName + properties: { + description: 'Assign Resource Group Contributor role to User Assigned Managed Identity ' + principalId: reference(aksCluster.id, const_APIVersion , 'Full').properties.addonProfiles.ingressApplicationGateway.identity.objectId + principalType: 'ServicePrincipal' + roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', const_roleDefinitionIdOfContributor) + } + dependsOn: [ + aksCluster + ] +} diff --git a/infra/azure.liberty.aks/modules/_rolesAssignment/_roleAssignmentinSubscription.bicep b/infra/azure.liberty.aks/modules/_rolesAssignment/_roleAssignmentinSubscription.bicep new file mode 100644 index 0000000..4832c98 --- /dev/null +++ b/infra/azure.liberty.aks/modules/_rolesAssignment/_roleAssignmentinSubscription.bicep @@ -0,0 +1,53 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +/* +Description: assign roles cross resource group. +Usage: + module roleAssignment '_roleAssignmentinSubscription.bicep' = { + name: 'assign-role' + scope: subscription() + params: { + roleDefinitionId: roleDefinitionId + principalId: principalId + } + } +*/ + +targetScope = 'subscription' + +// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles +param roleDefinitionId string = '' +param principalId string = '' + +var name_roleAssignmentName = guid('${subscription().id}${principalId}Role assignment in subscription scope') + +// Get role resource id in subscription +resource roleResourceDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { + name: roleDefinitionId +} + +// Assign role +resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { + name: name_roleAssignmentName + properties: { + description: 'Assign subscription scope role to User Assigned Managed Identity ' + principalId: principalId + principalType: 'ServicePrincipal' + roleDefinitionId: roleResourceDefinition.id + } +} diff --git a/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep b/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep new file mode 100644 index 0000000..d4ae08d --- /dev/null +++ b/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep @@ -0,0 +1,43 @@ +/* + Copyright (c) Microsoft Corporation. + Copyright (c) IBM Corporation. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +param location string + +param name_deploymentScriptContributorRoleAssignmentName string = guid('${resourceGroup().id}Deployment Script') + +// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles +var const_roleDefinitionIdOfContributor = 'b24988ac-6180-42a0-ab88-20f7382dd24c' +var name_deploymentScriptUserDefinedManagedIdentity = 'ol-aks-deployment-script-user-defined-managed-itentity-${substring(uniqueString(name_deploymentScriptContributorRoleAssignmentName),0,5)}' + + +// UAMI for deployment script +resource uamiForDeploymentScript 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { + name: name_deploymentScriptUserDefinedManagedIdentity + location: location +} + +// Assign Contributor role in subscription scope, we need the permission to get/update resource cross resource groups. +module deploymentScriptUAMICotibutorRoleAssignment '_rolesAssignment/_roleAssignmentinSubscription.bicep' = { + name: name_deploymentScriptContributorRoleAssignmentName + scope: subscription() + params: { + roleDefinitionId: const_roleDefinitionIdOfContributor + principalId: reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', name_deploymentScriptUserDefinedManagedIdentity)).principalId + } +} + +output uamiIdForDeploymentScript string = uamiForDeploymentScript.id diff --git a/infra/azure.liberty.aks/parameters.json b/infra/azure.liberty.aks/parameters.json new file mode 100644 index 0000000..ffb7d84 --- /dev/null +++ b/infra/azure.liberty.aks/parameters.json @@ -0,0 +1,36 @@ +{ + "$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#", + "contentVersion": "1.0.0.0", + "parameters": { + "_artifactsLocation": { + "value": "https://raw.githubusercontent.com/WASdev/azure.liberty.aks/048e776e9efe2ffed8368812e198c1007ba94b2c/src/main/" + }, + "createCluster": { + "value": true + }, + "vmSize": { + "value": "Standard_DS2_v2" + }, + "minCount": { + "value": 1 + }, + "maxCount": { + "value": 5 + }, + "createACR": { + "value": true + }, + "deployApplication": { + "value": false + }, + "enableAppGWIngress": { + "value": true + }, + "appGatewayCertificateOption": { + "value": "generateCert" + }, + "enableCookieBasedAffinity": { + "value": true + } + } +} \ No newline at end of file diff --git a/infra/main.bicep b/infra/main.bicep index 47f19c8..a11a6f1 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -39,3 +39,51 @@ module monitoring './shared/monitoring.bicep' = { scope: rg } +@description('The base URL for artifacts') +param _artifactsLocation string = 'https://raw.githubusercontent.com/WASdev/azure.liberty.aks/048e776e9efe2ffed8368812e198c1007ba94b2c/src/main/' + +@description('Whether to create a new AKS cluster') +param createCluster bool = true + +@description('The VM size for AKS nodes') +param vmSize string = 'Standard_DS2_v2' + +@description('The minimum node count for AKS cluster') +param minCount int = 1 + +@description('The maximum node count for AKS cluster') +param maxCount int = 5 + +@description('Whether to create Azure Container Registry') +param createACR bool = true + +@description('Whether to deploy the application') +param deployApplication bool = false + +@description('Whether to enable Application Gateway Ingress') +param enableAppGWIngress bool = true + +@description('The certificate option for Application Gateway') +param appGatewayCertificateOption string = 'generateCert' + +@description('Whether to enable cookie-based affinity') +param enableCookieBasedAffinity bool = true + +module openLibertyOnAks './azure.liberty.aks/mainTemplate.bicep' = { + name: 'openliberty-on-aks' + params: { + _artifactsLocation: _artifactsLocation + location: location + createCluster: createCluster + vmSize: vmSize + minCount: minCount + maxCount: maxCount + createACR: createACR + deployApplication: deployApplication + enableAppGWIngress: enableAppGWIngress + appGatewayCertificateOption: appGatewayCertificateOption + enableCookieBasedAffinity: enableCookieBasedAffinity + + } + scope: rg +} \ No newline at end of file From 6f101982044302300f398d545940c69eafcbb996 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Fri, 16 Aug 2024 17:12:43 +0800 Subject: [PATCH 03/21] use maven build bicep values --- infra/azure.liberty.aks/mainTemplate.bicep | 4 +--- .../modules/_azure-resoruces/_appgateway.bicep | 2 +- .../_keyvault/_keyvaultWithExistingCert.bicep | 2 +- .../_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep | 2 +- .../modules/_azure-resoruces/_vnetAppGateway.bicep | 2 +- .../modules/_rolesAssignment/_agicRoleAssignment.bicep | 3 ++- infra/azure.liberty.aks/modules/_uamiAndRoles.bicep | 3 +-- infra/main.bicep | 2 +- 8 files changed, 9 insertions(+), 11 deletions(-) diff --git a/infra/azure.liberty.aks/mainTemplate.bicep b/infra/azure.liberty.aks/mainTemplate.bicep index 9929aa5..6a8f29f 100644 --- a/infra/azure.liberty.aks/mainTemplate.bicep +++ b/infra/azure.liberty.aks/mainTemplate.bicep @@ -163,9 +163,7 @@ param maxReplicas int = 100 @description('The minimum required CPU core (millicore) over all the replicas for autoscaling') param requestCPUMillicore int = 300 -// TODo Updated -// param guidValue string = take(uniqueString(subscription().id, environmentName, location), 6) -param guidValue string = newGuid() +param guidValue string = take(replace(newGuid(), '-', ''), 6) var const_acrRGName = (createACR ? resourceGroup().name : acrRGName) var const_appGatewaySSLCertOptionHaveCert = 'haveCert' diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep index 43c6c78..9cdc4e6 100644 --- a/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep +++ b/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep @@ -24,7 +24,7 @@ param location string param gatewaySubnetId string = '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/resourcegroupname/providers/Microsoft.Network/virtualNetworks/vnetname/subnets/subnetname' param staticPrivateFrontentIP string = '10.0.0.1' param usePrivateIP bool = false -param guidValue string = newGuid() +param guidValue string = take(replace(newGuid(), '-', ''), 6) var const_nameSuffix = empty(nameSuffix) ? guidValue : nameSuffix var name_appGateway = format('appgw{0}', const_nameSuffix) diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep index 223d4f3..c314c97 100644 --- a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep +++ b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep @@ -33,7 +33,7 @@ param certificatePasswordValue string = newGuid() param enabledForTemplateDeployment bool = true @description('Name of the vault') -param keyVaultName string = 'kv-${uniqueString('utcValue')}' +param keyVaultName string = 'kv-${uniqueString(utcValue)}' param location string diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep index 1c67b9a..32b35be 100644 --- a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep +++ b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep @@ -19,7 +19,7 @@ param identity object = {} @description('Used to name the new Azure Key Vault resoure.') -param keyVaultName string = 'kv-${uniqueString('utcValue')}' +param keyVaultName string = 'kv-${uniqueString(utcValue)}' param location string diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep index 0588f27..630094e 100644 --- a/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep +++ b/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep @@ -35,7 +35,7 @@ param vnetForApplicationGateway object = { } param vnetRGNameForApplicationGateway string param nameSuffix string = '' -param guidValue string = 'vgateway' +param guidValue string = take(replace(newGuid(), '-', ''), 6) var const_nameSuffix = empty(nameSuffix) ? guidValue : nameSuffix var const_subnetAddressPrefixes = vnetForApplicationGateway.subnets.gatewaySubnet.addressPrefix diff --git a/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep b/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep index b2058fc..b21184e 100644 --- a/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep +++ b/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep @@ -17,9 +17,10 @@ param aksClusterName string = '' param aksClusterRGName string = '' +param utcValue string = utcNow() var const_APIVersion = '2020-12-01' -var name_appGwContributorRoleAssignmentName = guid('${resourceGroup().id}ForApplicationGateway') +var name_appGwContributorRoleAssignmentName = guid('${resourceGroup().id}${utcValue}ForApplicationGateway') // https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles var const_roleDefinitionIdOfContributor = 'b24988ac-6180-42a0-ab88-20f7382dd24c' diff --git a/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep b/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep index d4ae08d..99bed69 100644 --- a/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep +++ b/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep @@ -16,8 +16,7 @@ */ param location string - -param name_deploymentScriptContributorRoleAssignmentName string = guid('${resourceGroup().id}Deployment Script') +param name_deploymentScriptContributorRoleAssignmentName string = newGuid() // https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles var const_roleDefinitionIdOfContributor = 'b24988ac-6180-42a0-ab88-20f7382dd24c' diff --git a/infra/main.bicep b/infra/main.bicep index a11a6f1..6c17b8e 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -72,7 +72,7 @@ param enableCookieBasedAffinity bool = true module openLibertyOnAks './azure.liberty.aks/mainTemplate.bicep' = { name: 'openliberty-on-aks' params: { - _artifactsLocation: _artifactsLocation + _artifactsLocation: _artifactsLocation location: location createCluster: createCluster vmSize: vmSize From 83344fbdee676743aa752fb11eb262ead54473b3 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Fri, 16 Aug 2024 17:20:03 +0800 Subject: [PATCH 04/21] update scripts --- .github/workflows/package-helm-chart.yaml | 67 +++++++++++++++++++ azd-hooks/postdeploy.sh | 6 ++ azd-hooks/postprovision.sh | 59 ++++++++++++++++ azd-hooks/predeploy.sh | 32 +++++++++ azd-hooks/preprovision.sh | 1 + azure.yaml | 37 +++++++++- charts/cargotracker-liberty-aks/.helmignore | 23 +++++++ charts/cargotracker-liberty-aks/Chart.yaml | 24 +++++++ .../templates/app-insight.yaml | 8 +++ .../templates/db-secret.yaml | 12 ++++ .../templates/openlibertyapplication.yaml | 64 ++++++++++++++++++ charts/cargotracker-liberty-aks/values.yaml | 24 +++++++ infra/azure.liberty.aks/mainTemplate.bicep | 3 + infra/main.bicep | 55 +++++++++++---- infra/shared/monitoring.bicep | 1 + 15 files changed, 400 insertions(+), 16 deletions(-) create mode 100644 .github/workflows/package-helm-chart.yaml create mode 100755 azd-hooks/postdeploy.sh create mode 100755 azd-hooks/postprovision.sh create mode 100755 azd-hooks/predeploy.sh create mode 100755 azd-hooks/preprovision.sh create mode 100644 charts/cargotracker-liberty-aks/.helmignore create mode 100644 charts/cargotracker-liberty-aks/Chart.yaml create mode 100644 charts/cargotracker-liberty-aks/templates/app-insight.yaml create mode 100644 charts/cargotracker-liberty-aks/templates/db-secret.yaml create mode 100644 charts/cargotracker-liberty-aks/templates/openlibertyapplication.yaml create mode 100644 charts/cargotracker-liberty-aks/values.yaml diff --git a/.github/workflows/package-helm-chart.yaml b/.github/workflows/package-helm-chart.yaml new file mode 100644 index 0000000..cb3f1fa --- /dev/null +++ b/.github/workflows/package-helm-chart.yaml @@ -0,0 +1,67 @@ +name: package-helm-chart + +on: + push: + branches: + - main + paths: + - 'charts/**' + + workflow_dispatch: + +jobs: + package-helm-chart: + permissions: + contents: read + packages: write + + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set environment variables + id: set-variables + run: | + echo "REPOSITORY=ghcr.io/$(echo ${{ github.repository }} | tr '[:upper:]' '[:lower:]')" >> "$GITHUB_OUTPUT" + echo "VERSION=$(yq -r .version ./charts/cargotracker-liberty-aks/Chart.yaml)" >> "$GITHUB_OUTPUT" + + - name: Env variable output + id: test-variables + run: | + echo ${{ steps.set-variables.outputs.REPOSITORY }} + echo ${{ steps.set-variables.outputs.VERSION }} + + - name: Login to GitHub Container Registry + uses: docker/login-action@e92390c5fb421da1463c202d546fed0ec5c39f20 # v3.1.0 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ github.token }} + + - name: Package and push helm chart + run: | + helm package ./charts/cargotracker-liberty-aks --version ${{ steps.set-variables.outputs.VERSION }} + helm push ./cargotracker-liberty-aks-chart-${{ steps.set-variables.outputs.VERSION }}.tgz oci://${{ steps.set-variables.outputs.REPOSITORY }}/charts + + publish-helm-chart: + permissions: + id-token: write + packages: write + contents: write + actions: read + deployments: read + pull-requests: read + + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Publish Helm chart to GitHub Pages + uses: stefanprodan/helm-gh-pages@0ad2bb377311d61ac04ad9eb6f252fb68e207260 # v1.7.0 + with: + token: ${{ secrets.GITHUB_TOKEN }} + linting: off \ No newline at end of file diff --git a/azd-hooks/postdeploy.sh b/azd-hooks/postdeploy.sh new file mode 100755 index 0000000..7bc26bf --- /dev/null +++ b/azd-hooks/postdeploy.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +############################################ +# Delete custom-values.yaml +############################################ +rm custom-values.yaml \ No newline at end of file diff --git a/azd-hooks/postprovision.sh b/azd-hooks/postprovision.sh new file mode 100755 index 0000000..afe2f64 --- /dev/null +++ b/azd-hooks/postprovision.sh @@ -0,0 +1,59 @@ +# enable Helm support +azd config set alpha.aks.helm on + +# Build image and upload to ACR +echo "AKS_NAME: $AKS_NAME" +echo "RESOURCE_GROUP_NAME $RESOURCE_GROUP_NAME" +ehco "WORKSPACE_ID: $WORKSPACE_ID" + +export AKS_NAME=$(az aks list -g ${RESOURCE_GROUP_NAME} --query \[0\].name -o tsv) + +az aks enable-addons \ + --addons monitoring \ + --name ${AKS_NAME} \ + --resource-group ${RESOURCE_GROUP_NAME} \ + --workspace-resource-id ${WORKSPACE_ID} + + +echo "get image name and version" + +IMAGE_NAME=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.artifactId}' --non-recursive exec:exec) +IMAGE_VERSION=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec) + +echo "build image and upload" + +mvn clean package -DskipTests +cd target +az acr build --registry ${AZURE_REGISTRY_NAME} --image ${IMAGE_NAME}:${IMAGE_VERSION} . + + +az postgres flexible-server create \ + --resource-group ${RESOURCE_GROUP_NAME} \ + --name ${DB_RESOURCE_NAME} \ + --location ${LOCATION} \ + --admin-user ${DB_USER_NAME} \ + --admin-password ${DB_USER_PASSWORD} \ + --version 15 --public-access 0.0.0.0 + --tier Burstable --sku-name Standard_B1ms --yes + +az postgres flexible-server db create \ + --resource-group ${RESOURCE_GROUP_NAME} \ + --server-name ${DB_RESOURCE_NAME} \ + --database-name ${DB_NAME} + +echo "Allow Access to Azure Services" +az postgres flexible-server firewall-rule create \ + -g ${RESOURCE_GROUP_NAME} \ + -n ${DB_RESOURCE_NAME} \ + -r "AllowAllWindowsAzureIps" \ + --start-ip-address "0.0.0.0" \ + --end-ip-address "0.0.0.0" + +az postgres flexible-server parameter set --name max_prepared_transactions --value 10 -g ${RESOURCE_GROUP_NAME} --server-name ${DB_RESOURCE_NAME} + +az postgres flexible-server restart -g ${RESOURCE_GROUP_NAME} --name ${DB_RESOURCE_NAME} + +## echo +echo RESOURCE_GROUP_NAME: $RESOURCE_GROUP_NAME +echo WORKSPACE_ID: $WORKSPACE_ID +echo AZURE_REGISTRY_NAME: $AZURE_REGISTRY_NAME \ No newline at end of file diff --git a/azd-hooks/predeploy.sh b/azd-hooks/predeploy.sh new file mode 100755 index 0000000..64fcda6 --- /dev/null +++ b/azd-hooks/predeploy.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +########################################################## +# Check kubelogin and install if not exists +########################################################## +if ! command -v kubelogin &> /dev/null; then + echo "kubelogin could not be found. Installing kubelogin..." + az aks install-cli +fi + +########################################################## +# Create the custom-values.yaml file +########################################################## +cat << EOF > custom-values.yaml +appInsightConnectionString: ${AZURE_AKS_NAMESPACE} +loginServer: ${AZURE_REGISTRY_NAME}.azurecr.io +EOF + + +########################################################## +# DB +########################################################## +cat << EOF >> custom-values.yaml +namespace: ${AZURE_AKS_NAMESPACE} +db: + ServerName: ${DB_RESOURCE_NAME} + PortNumber: 5432 + Name: ${DB_NAME} + User: ${DB_USER_NAME} + Password: ${DB_USER_PASSWORD} +EOF + diff --git a/azd-hooks/preprovision.sh b/azd-hooks/preprovision.sh new file mode 100755 index 0000000..81a5c44 --- /dev/null +++ b/azd-hooks/preprovision.sh @@ -0,0 +1 @@ +az extension add --upgrade -n application-insights \ No newline at end of file diff --git a/azure.yaml b/azure.yaml index bb58b19..3b9396b 100644 --- a/azure.yaml +++ b/azure.yaml @@ -1,5 +1,38 @@ # yaml-language-server: $schema=https://raw.githubusercontent.com/Azure/azure-dev/main/schemas/v1.0/azure.yaml.json -name: cargotracker-liberty-aks +name: cargotracker-liberty-aks-demo metadata: - template: azd-init@1.9.5 + template: cargotracker-liberty-aks-demo@1.0.0 +hooks: + postprovision: + posix: + shell: sh + continueOnError: false + interactive: false + run: azd-hooks/postprovision.sh + predeploy: # This hook is executed before the deployment of the application to create the custom-values.yaml file + posix: + shell: sh + continueOnError: false + interactive: false + run: azd-hooks/predeploy.sh + postdeploy: + posix: + shell: sh + continueOnError: false + interactive: false + run: azd-hooks/postdeploy.sh +services: + demo: + host: aks + k8s: + namespace: default + helm: + repositories: + - name: cargotracker-liberty-aks + url: https://backwind1233.github.io/cargotracker-liberty-aks + releases: + - name: demo + chart: cargotracker-liberty-aks/cargotracker-liberty-aks-chart + version: 1.0.4 + values: custom-values.yaml # This file is created by the predeploy hook \ No newline at end of file diff --git a/charts/cargotracker-liberty-aks/.helmignore b/charts/cargotracker-liberty-aks/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/cargotracker-liberty-aks/.helmignore @@ -0,0 +1,23 @@ +# Patterns to ignore when building packages. +# This supports shell glob matching, relative path matching, and +# negation (prefixed with !). Only one pattern per line. +.DS_Store +# Common VCS dirs +.git/ +.gitignore +.bzr/ +.bzrignore +.hg/ +.hgignore +.svn/ +# Common backup files +*.swp +*.bak +*.tmp +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ diff --git a/charts/cargotracker-liberty-aks/Chart.yaml b/charts/cargotracker-liberty-aks/Chart.yaml new file mode 100644 index 0000000..c7a13eb --- /dev/null +++ b/charts/cargotracker-liberty-aks/Chart.yaml @@ -0,0 +1,24 @@ +apiVersion: v2 +name: cargotracker-liberty-aks-chart +description: A Helm chart for deploying the cargotracker application on aks using Liberty. + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 1.0.4 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "1.16.0" diff --git a/charts/cargotracker-liberty-aks/templates/app-insight.yaml b/charts/cargotracker-liberty-aks/templates/app-insight.yaml new file mode 100644 index 0000000..4009a09 --- /dev/null +++ b/charts/cargotracker-liberty-aks/templates/app-insight.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: app-insight-secret + namespace: "{{ .Values.namespace }}" +type: Opaque +stringData: + connection.string: "{{ .Values.appInsightConnectionString }}" \ No newline at end of file diff --git a/charts/cargotracker-liberty-aks/templates/db-secret.yaml b/charts/cargotracker-liberty-aks/templates/db-secret.yaml new file mode 100644 index 0000000..b9426a3 --- /dev/null +++ b/charts/cargotracker-liberty-aks/templates/db-secret.yaml @@ -0,0 +1,12 @@ +apiVersion: v1 +kind: Secret +metadata: + name: db-secret-sql + namespace: "{{ .Values.namespace }}" +type: Opaque +stringData: + db.server.name: "{{ .Values.db.ServerName }}" + db.port.number: "{{ .Values.db.PortNumber }}" + db.name: "{{ .Values.db.Name }}" + db.user: "{{ .Values.db.User }}" + db.password: "{{ .Values.db.Password }}" \ No newline at end of file diff --git a/charts/cargotracker-liberty-aks/templates/openlibertyapplication.yaml b/charts/cargotracker-liberty-aks/templates/openlibertyapplication.yaml new file mode 100644 index 0000000..60ae361 --- /dev/null +++ b/charts/cargotracker-liberty-aks/templates/openlibertyapplication.yaml @@ -0,0 +1,64 @@ +apiVersion: apps.openliberty.io/v1beta2 +kind: OpenLibertyApplication +metadata: + name: cargo-tracker-cluster + namespace: "{{ .Values.namespace }}" +spec: + replicas: {{ .Values.replicaCount }} + applicationImage: "{{ .Values.loginServer }}/cargo-tracker:3.2-SNAPSHOT" + pullPolicy: Always + service: + type: ClusterIP + port: 9080 + env: + - name: DB_SERVER_NAME + valueFrom: + secretKeyRef: + name: db-secret-sql + key: db.server.name + - name: DB_PORT_NUMBER + valueFrom: + secretKeyRef: + name: db-secret-sql + key: db.port.number + - name: DB_NAME + valueFrom: + secretKeyRef: + name: db-secret-sql + key: db.name + - name: DB_USER + valueFrom: + secretKeyRef: + name: db-secret-sql + key: db.user + - name: DB_PASSWORD + valueFrom: + secretKeyRef: + name: db-secret-sql + key: db.password + - name: APPLICATIONINSIGHTS_CONNECTION_STRING + valueFrom: + secretKeyRef: + name: app-insight-secret + key: connection.string +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: cargo-tracker-ingress + namespace: default + annotations: + appgw.ingress.kubernetes.io/cookie-based-affinity: "true" + appgw.ingress.kubernetes.io/use-private-ip: "false" +spec: + ingressClassName: azure-application-gateway + rules: + - http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: cargo-tracker-cluster + port: + number: 9080 diff --git a/charts/cargotracker-liberty-aks/values.yaml b/charts/cargotracker-liberty-aks/values.yaml new file mode 100644 index 0000000..7c07ffe --- /dev/null +++ b/charts/cargotracker-liberty-aks/values.yaml @@ -0,0 +1,24 @@ +# Default values for cargotracker-liberty-aks. +# This is a YAML-formatted file. +# Declare variables to be passed into your templates. + +replicaCount: 3 + +namespace: "default" + +appInsightConnectionString: "" +db: + ServerName: "" + PortNumber: "" + Name: "" + User: "" + Password: "" + +loginServer: {} + +# +nodeSelector: {} + +tolerations: [] + +affinity: {} diff --git a/infra/azure.liberty.aks/mainTemplate.bicep b/infra/azure.liberty.aks/mainTemplate.bicep index 6a8f29f..767490b 100644 --- a/infra/azure.liberty.aks/mainTemplate.bicep +++ b/infra/azure.liberty.aks/mainTemplate.bicep @@ -521,6 +521,9 @@ output appHttpsEndpoint string = deployApplication && enableAppGWIngress ? appgw output clusterName string = name_clusterName output clusterRGName string = const_clusterRGName output acrName string = name_acrName +output acrServerName string = createACR ? acrDeployment.properties.loginServer : '' +output acrUsername string = createACR ? acrDeployment.name : '' +output acrPassword string = createACR ? listCredentials(acrDeployment.id, acrDeployment.apiVersion).passwords[0].value : '' output cmdToGetAcrLoginServer string = const_cmdToGetAcrLoginServer output appNamespaceName string = const_appProjName output appName string = deployApplication ? const_appName : '' diff --git a/infra/main.bicep b/infra/main.bicep index 6c17b8e..d2d24d8 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -23,22 +23,11 @@ var abbrs = loadJsonContent('./abbreviations.json') var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) resource rg 'Microsoft.Resources/resourceGroups@2022-09-01' = { - name: 'rg-${environmentName}-${take(resourceToken, 5)}' + name: 'rg-${environmentName}-${take(resourceToken, 6)}' location: location tags: tags } -module monitoring './shared/monitoring.bicep' = { - name: 'monitoring' - params: { - location: location - tags: tags - logAnalyticsName: '${abbrs.operationalInsightsWorkspaces}${resourceToken}' - applicationInsightsName: '${abbrs.insightsComponents}${resourceToken}' - } - scope: rg -} - @description('The base URL for artifacts') param _artifactsLocation string = 'https://raw.githubusercontent.com/WASdev/azure.liberty.aks/048e776e9efe2ffed8368812e198c1007ba94b2c/src/main/' @@ -83,7 +72,45 @@ module openLibertyOnAks './azure.liberty.aks/mainTemplate.bicep' = { enableAppGWIngress: enableAppGWIngress appGatewayCertificateOption: appGatewayCertificateOption enableCookieBasedAffinity: enableCookieBasedAffinity - } scope: rg -} \ No newline at end of file +} + +module monitoring './shared/monitoring.bicep' = { + name: 'monitoring' + params: { + location: location + tags: tags + logAnalyticsName: '${abbrs.operationalInsightsWorkspaces}${resourceToken}' + applicationInsightsName: '${abbrs.insightsComponents}${resourceToken}' + } + scope: rg +} + + +@description('Name of the PostgreSQL Flexible Server') +param dbResourceName string = 'libertydb1110' + +@description('Server administrator login name') +@secure() +param administratorLogin string = 'azureroot' + +@description('Server administrator password') +@secure() +param administratorLoginPassword string + +@description('Name of the database') +param databaseName string = 'libertydb1110' + +output LOCATION string = location +output RESOURCE_GROUP_NAME string = rg.name +output AZURE_RESOURCE_GROUP string = rg.name +output WORKSPACE_ID string = monitoring.outputs.logAnalyticsWorkspaceId +output AZURE_REGISTRY_NAME string = openLibertyOnAks.outputs.acrServerName +output appInsightConnectionString string = monitoring.outputs.appInsightsConnectionString + +output DB_RESOURCE_NAME string = dbResourceName +output DB_NAME string = databaseName +output DB_USER_NAME string = administratorLogin +output DB_USER_PASSWORD string = administratorLoginPassword +output AZURE_AKS_CLUSTER_NAME string = openLibertyOnAks.outputs.clusterName diff --git a/infra/shared/monitoring.bicep b/infra/shared/monitoring.bicep index 4ae9796..cbcb813 100644 --- a/infra/shared/monitoring.bicep +++ b/infra/shared/monitoring.bicep @@ -32,3 +32,4 @@ resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { output applicationInsightsName string = applicationInsights.name output logAnalyticsWorkspaceId string = logAnalytics.id output logAnalyticsWorkspaceName string = logAnalytics.name +output appInsightsConnectionString string = applicationInsights.properties.ConnectionString \ No newline at end of file From 7ed5915b14665c477b934f13ecfd82750ec68d22 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Mon, 26 Aug 2024 18:21:12 +0800 Subject: [PATCH 05/21] Refactor postprovision.sh to run Maven commands in a function. --- azd-hooks/postprovision.sh | 24 +++++++++++++++--------- azd-hooks/predeploy.sh | 2 +- infra/main.bicep | 7 ++++++- 3 files changed, 22 insertions(+), 11 deletions(-) diff --git a/azd-hooks/postprovision.sh b/azd-hooks/postprovision.sh index afe2f64..5f27783 100755 --- a/azd-hooks/postprovision.sh +++ b/azd-hooks/postprovision.sh @@ -4,7 +4,7 @@ azd config set alpha.aks.helm on # Build image and upload to ACR echo "AKS_NAME: $AKS_NAME" echo "RESOURCE_GROUP_NAME $RESOURCE_GROUP_NAME" -ehco "WORKSPACE_ID: $WORKSPACE_ID" +echo "WORKSPACE_ID: $WORKSPACE_ID" export AKS_NAME=$(az aks list -g ${RESOURCE_GROUP_NAME} --query \[0\].name -o tsv) @@ -17,16 +17,27 @@ az aks enable-addons \ echo "get image name and version" -IMAGE_NAME=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.artifactId}' --non-recursive exec:exec) -IMAGE_VERSION=$(mvn -q -Dexec.executable=echo -Dexec.args='${project.version}' --non-recursive exec:exec) +run_maven_command() { + mvn -q -Dexec.executable=echo -Dexec.args="$1" --non-recursive exec:exec 2>/dev/null | sed -e 's/\x1b\[[0-9;]*m//g' | tr -d '\r\n' +} + +IMAGE_NAME=$(run_maven_command '${project.artifactId}') +IMAGE_VERSION=$(run_maven_command '${project.version}') echo "build image and upload" mvn clean package -DskipTests cd target -az acr build --registry ${AZURE_REGISTRY_NAME} --image ${IMAGE_NAME}:${IMAGE_VERSION} . +echo "docker build" +docker build -t ${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . +docker tag ${IMAGE_NAME}:${IMAGE_VERSION} ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} +docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} + +echo "docker push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" +docker push ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} +echo "provision postgresql" az postgres flexible-server create \ --resource-group ${RESOURCE_GROUP_NAME} \ --name ${DB_RESOURCE_NAME} \ @@ -52,8 +63,3 @@ az postgres flexible-server firewall-rule create \ az postgres flexible-server parameter set --name max_prepared_transactions --value 10 -g ${RESOURCE_GROUP_NAME} --server-name ${DB_RESOURCE_NAME} az postgres flexible-server restart -g ${RESOURCE_GROUP_NAME} --name ${DB_RESOURCE_NAME} - -## echo -echo RESOURCE_GROUP_NAME: $RESOURCE_GROUP_NAME -echo WORKSPACE_ID: $WORKSPACE_ID -echo AZURE_REGISTRY_NAME: $AZURE_REGISTRY_NAME \ No newline at end of file diff --git a/azd-hooks/predeploy.sh b/azd-hooks/predeploy.sh index 64fcda6..1075cef 100755 --- a/azd-hooks/predeploy.sh +++ b/azd-hooks/predeploy.sh @@ -13,7 +13,7 @@ fi ########################################################## cat << EOF > custom-values.yaml appInsightConnectionString: ${AZURE_AKS_NAMESPACE} -loginServer: ${AZURE_REGISTRY_NAME}.azurecr.io +loginServer: ${AZURE_REGISTRY_NAME} EOF diff --git a/infra/main.bicep b/infra/main.bicep index d2d24d8..c78166c 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -106,7 +106,7 @@ output LOCATION string = location output RESOURCE_GROUP_NAME string = rg.name output AZURE_RESOURCE_GROUP string = rg.name output WORKSPACE_ID string = monitoring.outputs.logAnalyticsWorkspaceId -output AZURE_REGISTRY_NAME string = openLibertyOnAks.outputs.acrServerName + output appInsightConnectionString string = monitoring.outputs.appInsightsConnectionString output DB_RESOURCE_NAME string = dbResourceName @@ -114,3 +114,8 @@ output DB_NAME string = databaseName output DB_USER_NAME string = administratorLogin output DB_USER_PASSWORD string = administratorLoginPassword output AZURE_AKS_CLUSTER_NAME string = openLibertyOnAks.outputs.clusterName + +output AZURE_REGISTRY_NAME string = openLibertyOnAks.outputs.acrServerName +output ACRServer string = openLibertyOnAks.outputs.acrServerName +output ACRUserName string = openLibertyOnAks.outputs.acrUsername +output ACRPassword string = openLibertyOnAks.outputs.acrPassword From 80d04542bec255ac8af697bb38f7ee08264cb6dc Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 5 Sep 2024 16:01:40 +0800 Subject: [PATCH 06/21] Refactor Docker image build and push process in predeploy script. --- azd-hooks/postprovision.sh | 55 +++++++++++------------- azd-hooks/predeploy.sh | 44 ++++++++----------- azd-hooks/preprovision.sh | 3 ++ azure.yaml | 6 +-- infra/main.bicep | 87 ++++++++++++++++++-------------------- 5 files changed, 88 insertions(+), 107 deletions(-) diff --git a/azd-hooks/postprovision.sh b/azd-hooks/postprovision.sh index 5f27783..0462837 100755 --- a/azd-hooks/postprovision.sh +++ b/azd-hooks/postprovision.sh @@ -1,11 +1,6 @@ # enable Helm support azd config set alpha.aks.helm on -# Build image and upload to ACR -echo "AKS_NAME: $AKS_NAME" -echo "RESOURCE_GROUP_NAME $RESOURCE_GROUP_NAME" -echo "WORKSPACE_ID: $WORKSPACE_ID" - export AKS_NAME=$(az aks list -g ${RESOURCE_GROUP_NAME} --query \[0\].name -o tsv) az aks enable-addons \ @@ -14,37 +9,14 @@ az aks enable-addons \ --resource-group ${RESOURCE_GROUP_NAME} \ --workspace-resource-id ${WORKSPACE_ID} - -echo "get image name and version" - -run_maven_command() { - mvn -q -Dexec.executable=echo -Dexec.args="$1" --non-recursive exec:exec 2>/dev/null | sed -e 's/\x1b\[[0-9;]*m//g' | tr -d '\r\n' -} - -IMAGE_NAME=$(run_maven_command '${project.artifactId}') -IMAGE_VERSION=$(run_maven_command '${project.version}') - -echo "build image and upload" - -mvn clean package -DskipTests -cd target -echo "docker build" -docker build -t ${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . -docker tag ${IMAGE_NAME}:${IMAGE_VERSION} ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} -docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} - -echo "docker push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" - -docker push ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} - -echo "provision postgresql" +echo "Provision postgresql" az postgres flexible-server create \ --resource-group ${RESOURCE_GROUP_NAME} \ --name ${DB_RESOURCE_NAME} \ --location ${LOCATION} \ --admin-user ${DB_USER_NAME} \ --admin-password ${DB_USER_PASSWORD} \ - --version 15 --public-access 0.0.0.0 + --version 15 --public-access 0.0.0.0 \ --tier Burstable --sku-name Standard_B1ms --yes az postgres flexible-server db create \ @@ -61,5 +33,26 @@ az postgres flexible-server firewall-rule create \ --end-ip-address "0.0.0.0" az postgres flexible-server parameter set --name max_prepared_transactions --value 10 -g ${RESOURCE_GROUP_NAME} --server-name ${DB_RESOURCE_NAME} - az postgres flexible-server restart -g ${RESOURCE_GROUP_NAME} --name ${DB_RESOURCE_NAME} + +########################################################## +# Create the custom-values.yaml file +########################################################## +cat << EOF > custom-values.yaml +appInsightConnectionString: ${AZURE_AKS_NAMESPACE} +loginServer: ${AZURE_REGISTRY_NAME} +EOF + +########################################################## +# DB +########################################################## +cat << EOF >> custom-values.yaml +namespace: ${AZURE_AKS_NAMESPACE} +db: + ServerName: ${DB_RESOURCE_NAME} + PortNumber: 5432 + Name: ${DB_NAME} + User: ${DB_USER_NAME} + Password: ${DB_USER_PASSWORD} +EOF + diff --git a/azd-hooks/predeploy.sh b/azd-hooks/predeploy.sh index 1075cef..f6c039f 100755 --- a/azd-hooks/predeploy.sh +++ b/azd-hooks/predeploy.sh @@ -1,32 +1,24 @@ #!/bin/bash -########################################################## -# Check kubelogin and install if not exists -########################################################## -if ! command -v kubelogin &> /dev/null; then - echo "kubelogin could not be found. Installing kubelogin..." - az aks install-cli -fi +# Build and push docker image to ACR +echo "Get image name and version......" -########################################################## -# Create the custom-values.yaml file -########################################################## -cat << EOF > custom-values.yaml -appInsightConnectionString: ${AZURE_AKS_NAMESPACE} -loginServer: ${AZURE_REGISTRY_NAME} -EOF +run_maven_command() { + mvn -q -Dexec.executable=echo -Dexec.args="$1" --non-recursive exec:exec 2>/dev/null | sed -e 's/\x1b\[[0-9;]*m//g' | tr -d '\r\n' +} +IMAGE_NAME=$(run_maven_command '${project.artifactId}') +IMAGE_VERSION=$(run_maven_command '${project.version}') -########################################################## -# DB -########################################################## -cat << EOF >> custom-values.yaml -namespace: ${AZURE_AKS_NAMESPACE} -db: - ServerName: ${DB_RESOURCE_NAME} - PortNumber: 5432 - Name: ${DB_NAME} - User: ${DB_USER_NAME} - Password: ${DB_USER_PASSWORD} -EOF +echo "Build image and upload" +mvn clean package -DskipTests +cd target +echo "docker build" +docker build -t ${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . +docker tag ${IMAGE_NAME}:${IMAGE_VERSION} ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} +docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} + +echo "Docker push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" + +docker push ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} diff --git a/azd-hooks/preprovision.sh b/azd-hooks/preprovision.sh index 81a5c44..f8c320d 100755 --- a/azd-hooks/preprovision.sh +++ b/azd-hooks/preprovision.sh @@ -1 +1,4 @@ +# check if docker is installed +# check if kubectl is installed + az extension add --upgrade -n application-insights \ No newline at end of file diff --git a/azure.yaml b/azure.yaml index 3b9396b..0be8bb5 100644 --- a/azure.yaml +++ b/azure.yaml @@ -8,19 +8,19 @@ hooks: posix: shell: sh continueOnError: false - interactive: false + interactive: true run: azd-hooks/postprovision.sh predeploy: # This hook is executed before the deployment of the application to create the custom-values.yaml file posix: shell: sh continueOnError: false - interactive: false + interactive: true run: azd-hooks/predeploy.sh postdeploy: posix: shell: sh continueOnError: false - interactive: false + interactive: true run: azd-hooks/postdeploy.sh services: demo: diff --git a/infra/main.bicep b/infra/main.bicep index c78166c..3eedcf8 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -9,25 +9,6 @@ param environmentName string @description('Primary location for all resources') param location string - -// Tags that should be applied to all resources. -// -// Note that 'azd-service-name' tags should be applied separately to service host resources. -// Example usage: -// tags: union(tags, { 'azd-service-name': }) -var tags = { - 'azd-env-name': environmentName -} - -var abbrs = loadJsonContent('./abbreviations.json') -var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) - -resource rg 'Microsoft.Resources/resourceGroups@2022-09-01' = { - name: 'rg-${environmentName}-${take(resourceToken, 6)}' - location: location - tags: tags -} - @description('The base URL for artifacts') param _artifactsLocation string = 'https://raw.githubusercontent.com/WASdev/azure.liberty.aks/048e776e9efe2ffed8368812e198c1007ba94b2c/src/main/' @@ -58,6 +39,36 @@ param appGatewayCertificateOption string = 'generateCert' @description('Whether to enable cookie-based affinity') param enableCookieBasedAffinity bool = true +@description('Name of the PostgreSQL Flexible Server') +param dbResourceName string = 'libertydb1110' + +@description('Server administrator login name') +@secure() +param administratorLogin string = 'azureroot' + +@description('Server administrator password') +@secure() +param administratorLoginPassword string + +// Tags that should be applied to all resources. +// +// Note that 'azd-service-name' tags should be applied separately to service host resources. +// Example usage: +// tags: union(tags, { 'azd-service-name': }) +var tags = { + 'azd-env-name': environmentName +} + +var abbrs = loadJsonContent('./abbreviations.json') +var resourceToken = toLower(uniqueString(subscription().id, environmentName, location)) +var suffix = take(resourceToken, 6) + +resource rg 'Microsoft.Resources/resourceGroups@2022-09-01' = { + name: 'rg-${environmentName}-${take(resourceToken, 6)}' + location: location + tags: tags +} + module openLibertyOnAks './azure.liberty.aks/mainTemplate.bicep' = { name: 'openliberty-on-aks' params: { @@ -87,35 +98,17 @@ module monitoring './shared/monitoring.bicep' = { scope: rg } - -@description('Name of the PostgreSQL Flexible Server') -param dbResourceName string = 'libertydb1110' - -@description('Server administrator login name') -@secure() -param administratorLogin string = 'azureroot' - -@description('Server administrator password') -@secure() -param administratorLoginPassword string - -@description('Name of the database') -param databaseName string = 'libertydb1110' - -output LOCATION string = location -output RESOURCE_GROUP_NAME string = rg.name +output ACRPassword string = openLibertyOnAks.outputs.acrPassword +output ACRServer string = openLibertyOnAks.outputs.acrServerName +output ACRUserName string = openLibertyOnAks.outputs.acrUsername +output AZURE_AKS_CLUSTER_NAME string = openLibertyOnAks.outputs.clusterName +output AZURE_REGISTRY_NAME string = openLibertyOnAks.outputs.acrServerName output AZURE_RESOURCE_GROUP string = rg.name -output WORKSPACE_ID string = monitoring.outputs.logAnalyticsWorkspaceId - -output appInsightConnectionString string = monitoring.outputs.appInsightsConnectionString - +output DB_NAME string = 'libertydb-${suffix}' output DB_RESOURCE_NAME string = dbResourceName -output DB_NAME string = databaseName output DB_USER_NAME string = administratorLogin output DB_USER_PASSWORD string = administratorLoginPassword -output AZURE_AKS_CLUSTER_NAME string = openLibertyOnAks.outputs.clusterName - -output AZURE_REGISTRY_NAME string = openLibertyOnAks.outputs.acrServerName -output ACRServer string = openLibertyOnAks.outputs.acrServerName -output ACRUserName string = openLibertyOnAks.outputs.acrUsername -output ACRPassword string = openLibertyOnAks.outputs.acrPassword +output LOCATION string = location +output RESOURCE_GROUP_NAME string = rg.name +output WORKSPACE_ID string = monitoring.outputs.logAnalyticsWorkspaceId +output appInsightConnectionString string = monitoring.outputs.appInsightsConnectionString From 020ac162cdf073f848c7f72047aa9daf857e6b4c Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 5 Sep 2024 16:23:13 +0800 Subject: [PATCH 07/21] Update Azure repository URL to https://azure-javaee.github.io/cargotracker-liberty-aks. --- azure.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure.yaml b/azure.yaml index 0be8bb5..ee4c564 100644 --- a/azure.yaml +++ b/azure.yaml @@ -30,7 +30,7 @@ services: helm: repositories: - name: cargotracker-liberty-aks - url: https://backwind1233.github.io/cargotracker-liberty-aks + url: https://azure-javaee.github.io/cargotracker-liberty-aks releases: - name: demo chart: cargotracker-liberty-aks/cargotracker-liberty-aks-chart From 83cd6f5e802f6a7866a9330d93ee2141eb692de8 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 5 Sep 2024 16:32:38 +0800 Subject: [PATCH 08/21] Update postprovision script to provide more detailed information during PostgreSQL server and database provisioning. --- azd-hooks/postprovision.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/azd-hooks/postprovision.sh b/azd-hooks/postprovision.sh index 0462837..7703e7f 100755 --- a/azd-hooks/postprovision.sh +++ b/azd-hooks/postprovision.sh @@ -9,7 +9,7 @@ az aks enable-addons \ --resource-group ${RESOURCE_GROUP_NAME} \ --workspace-resource-id ${WORKSPACE_ID} -echo "Provision postgresql" +echo "Provision postgresql server" az postgres flexible-server create \ --resource-group ${RESOURCE_GROUP_NAME} \ --name ${DB_RESOURCE_NAME} \ @@ -17,8 +17,11 @@ az postgres flexible-server create \ --admin-user ${DB_USER_NAME} \ --admin-password ${DB_USER_PASSWORD} \ --version 15 --public-access 0.0.0.0 \ - --tier Burstable --sku-name Standard_B1ms --yes + --tier Burstable \ + --sku-name Standard_B1ms \ + --yes --wait +echo "Provision postgresql database" az postgres flexible-server db create \ --resource-group ${RESOURCE_GROUP_NAME} \ --server-name ${DB_RESOURCE_NAME} \ @@ -55,4 +58,3 @@ db: User: ${DB_USER_NAME} Password: ${DB_USER_PASSWORD} EOF - From d190c71a3d20da8bc10bb1d46226fdd7ff206d5a Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 5 Sep 2024 17:15:12 +0800 Subject: [PATCH 09/21] Update DB_RESOURCE_NAME variable to 'liberty-server-${suffix}' in infra main.bicep. --- azd-hooks/postprovision.sh | 2 +- infra/main.bicep | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/azd-hooks/postprovision.sh b/azd-hooks/postprovision.sh index 7703e7f..860598b 100755 --- a/azd-hooks/postprovision.sh +++ b/azd-hooks/postprovision.sh @@ -19,7 +19,7 @@ az postgres flexible-server create \ --version 15 --public-access 0.0.0.0 \ --tier Burstable \ --sku-name Standard_B1ms \ - --yes --wait + --yes echo "Provision postgresql database" az postgres flexible-server db create \ diff --git a/infra/main.bicep b/infra/main.bicep index 3eedcf8..8c6ec96 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -39,9 +39,6 @@ param appGatewayCertificateOption string = 'generateCert' @description('Whether to enable cookie-based affinity') param enableCookieBasedAffinity bool = true -@description('Name of the PostgreSQL Flexible Server') -param dbResourceName string = 'libertydb1110' - @description('Server administrator login name') @secure() param administratorLogin string = 'azureroot' @@ -104,8 +101,8 @@ output ACRUserName string = openLibertyOnAks.outputs.acrUsername output AZURE_AKS_CLUSTER_NAME string = openLibertyOnAks.outputs.clusterName output AZURE_REGISTRY_NAME string = openLibertyOnAks.outputs.acrServerName output AZURE_RESOURCE_GROUP string = rg.name -output DB_NAME string = 'libertydb-${suffix}' -output DB_RESOURCE_NAME string = dbResourceName +output DB_NAME string = 'liberty-db-${suffix}' +output DB_RESOURCE_NAME string = 'liberty-server-${suffix}' output DB_USER_NAME string = administratorLogin output DB_USER_PASSWORD string = administratorLoginPassword output LOCATION string = location From 90ca0cc000c59a74e9b27603e29bdde35644cbe3 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 12 Sep 2024 17:18:20 +0800 Subject: [PATCH 10/21] Update Azure connection string in postprovision script. --- .gitignore | 1 + azd-hooks/postdeploy.sh | 6 ------ azd-hooks/postprovision.sh | 8 ++++++-- azure.yaml | 12 ++---------- infra/main.bicep | 2 +- 5 files changed, 10 insertions(+), 19 deletions(-) delete mode 100755 azd-hooks/postdeploy.sh diff --git a/.gitignore b/.gitignore index a128935..2952e82 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,4 @@ hs_err_pid* target/* +/custom-values.yaml diff --git a/azd-hooks/postdeploy.sh b/azd-hooks/postdeploy.sh deleted file mode 100755 index 7bc26bf..0000000 --- a/azd-hooks/postdeploy.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -############################################ -# Delete custom-values.yaml -############################################ -rm custom-values.yaml \ No newline at end of file diff --git a/azd-hooks/postprovision.sh b/azd-hooks/postprovision.sh index 860598b..0ce2396 100755 --- a/azd-hooks/postprovision.sh +++ b/azd-hooks/postprovision.sh @@ -1,6 +1,10 @@ # enable Helm support azd config set alpha.aks.helm on +HELM_REPO_URL="https://azure-javaee.github.io/cargotracker-liberty-aks" +HELM_REPO_NAME="cargotracker-liberty-aks" +helm repo add ${HELM_REPO_NAME} ${HELM_REPO_URL} + export AKS_NAME=$(az aks list -g ${RESOURCE_GROUP_NAME} --query \[0\].name -o tsv) az aks enable-addons \ @@ -42,7 +46,7 @@ az postgres flexible-server restart -g ${RESOURCE_GROUP_NAME} --name ${DB_RESOUR # Create the custom-values.yaml file ########################################################## cat << EOF > custom-values.yaml -appInsightConnectionString: ${AZURE_AKS_NAMESPACE} +appInsightConnectionString: ${APP_INSIGHTS_CONNECTION_STRING} loginServer: ${AZURE_REGISTRY_NAME} EOF @@ -52,7 +56,7 @@ EOF cat << EOF >> custom-values.yaml namespace: ${AZURE_AKS_NAMESPACE} db: - ServerName: ${DB_RESOURCE_NAME} + ServerName: ${DB_RESOURCE_NAME}.postgres.database.azure.com PortNumber: 5432 Name: ${DB_NAME} User: ${DB_USER_NAME} diff --git a/azure.yaml b/azure.yaml index ee4c564..8ed7617 100644 --- a/azure.yaml +++ b/azure.yaml @@ -16,23 +16,15 @@ hooks: continueOnError: false interactive: true run: azd-hooks/predeploy.sh - postdeploy: - posix: - shell: sh - continueOnError: false - interactive: true - run: azd-hooks/postdeploy.sh + services: demo: host: aks k8s: namespace: default helm: - repositories: - - name: cargotracker-liberty-aks - url: https://azure-javaee.github.io/cargotracker-liberty-aks releases: - name: demo - chart: cargotracker-liberty-aks/cargotracker-liberty-aks-chart + chart: cargotracker-liberty-aks01/cargotracker-liberty-aks-chart version: 1.0.4 values: custom-values.yaml # This file is created by the predeploy hook \ No newline at end of file diff --git a/infra/main.bicep b/infra/main.bicep index 8c6ec96..241bc6a 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -108,4 +108,4 @@ output DB_USER_PASSWORD string = administratorLoginPassword output LOCATION string = location output RESOURCE_GROUP_NAME string = rg.name output WORKSPACE_ID string = monitoring.outputs.logAnalyticsWorkspaceId -output appInsightConnectionString string = monitoring.outputs.appInsightsConnectionString +output APP_INSIGHTS_CONNECTION_STRING string = monitoring.outputs.appInsightsConnectionString From a42df9277c7269ec05a89985d8bd6de8f2283f71 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 12 Sep 2024 17:56:41 +0800 Subject: [PATCH 11/21] Update applicationImage to use dynamic values for imageName and imageTag. --- azd-hooks/postprovision.sh | 10 ++++++++++ azure.yaml | 2 +- charts/cargotracker-liberty-aks/Chart.yaml | 2 +- .../templates/openlibertyapplication.yaml | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) diff --git a/azd-hooks/postprovision.sh b/azd-hooks/postprovision.sh index 0ce2396..cc3b504 100755 --- a/azd-hooks/postprovision.sh +++ b/azd-hooks/postprovision.sh @@ -1,6 +1,7 @@ # enable Helm support azd config set alpha.aks.helm on +echo "Create Helm repository" HELM_REPO_URL="https://azure-javaee.github.io/cargotracker-liberty-aks" HELM_REPO_NAME="cargotracker-liberty-aks" helm repo add ${HELM_REPO_NAME} ${HELM_REPO_URL} @@ -42,12 +43,21 @@ az postgres flexible-server firewall-rule create \ az postgres flexible-server parameter set --name max_prepared_transactions --value 10 -g ${RESOURCE_GROUP_NAME} --server-name ${DB_RESOURCE_NAME} az postgres flexible-server restart -g ${RESOURCE_GROUP_NAME} --name ${DB_RESOURCE_NAME} +run_maven_command() { + mvn -q -Dexec.executable=echo -Dexec.args="$1" --non-recursive exec:exec 2>/dev/null | sed -e 's/\x1b\[[0-9;]*m//g' | tr -d '\r\n' +} + +IMAGE_NAME=$(run_maven_command '${project.artifactId}') +IMAGE_VERSION=$(run_maven_command '${project.version}') + ########################################################## # Create the custom-values.yaml file ########################################################## cat << EOF > custom-values.yaml appInsightConnectionString: ${APP_INSIGHTS_CONNECTION_STRING} loginServer: ${AZURE_REGISTRY_NAME} +imageName: ${IMAGE_NAME} +imageTag: ${IMAGE_VERSION} EOF ########################################################## diff --git a/azure.yaml b/azure.yaml index 8ed7617..0a8a809 100644 --- a/azure.yaml +++ b/azure.yaml @@ -26,5 +26,5 @@ services: releases: - name: demo chart: cargotracker-liberty-aks01/cargotracker-liberty-aks-chart - version: 1.0.4 + version: 1.0.5 values: custom-values.yaml # This file is created by the predeploy hook \ No newline at end of file diff --git a/charts/cargotracker-liberty-aks/Chart.yaml b/charts/cargotracker-liberty-aks/Chart.yaml index c7a13eb..d075755 100644 --- a/charts/cargotracker-liberty-aks/Chart.yaml +++ b/charts/cargotracker-liberty-aks/Chart.yaml @@ -15,7 +15,7 @@ type: application # This is the chart version. This version number should be incremented each time you make changes # to the chart and its templates, including the app version. # Versions are expected to follow Semantic Versioning (https://semver.org/) -version: 1.0.4 +version: 1.0.5 # This is the version number of the application being deployed. This version number should be # incremented each time you make changes to the application. Versions are not expected to diff --git a/charts/cargotracker-liberty-aks/templates/openlibertyapplication.yaml b/charts/cargotracker-liberty-aks/templates/openlibertyapplication.yaml index 60ae361..abe712a 100644 --- a/charts/cargotracker-liberty-aks/templates/openlibertyapplication.yaml +++ b/charts/cargotracker-liberty-aks/templates/openlibertyapplication.yaml @@ -5,7 +5,7 @@ metadata: namespace: "{{ .Values.namespace }}" spec: replicas: {{ .Values.replicaCount }} - applicationImage: "{{ .Values.loginServer }}/cargo-tracker:3.2-SNAPSHOT" + applicationImage: "{{ .Values.loginServer }}/{{ .Values.imageName }}:{{ .Values.imageTag }}" pullPolicy: Always service: type: ClusterIP From e34946dd4791585df3b2531648b29d453baaa3ca Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 12 Sep 2024 20:08:31 +0800 Subject: [PATCH 12/21] Update Azure chart reference to match project structure. --- azure.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure.yaml b/azure.yaml index 0a8a809..9fc6045 100644 --- a/azure.yaml +++ b/azure.yaml @@ -25,6 +25,6 @@ services: helm: releases: - name: demo - chart: cargotracker-liberty-aks01/cargotracker-liberty-aks-chart + chart: cargotracker-liberty-aks/cargotracker-liberty-aks-chart version: 1.0.5 values: custom-values.yaml # This file is created by the predeploy hook \ No newline at end of file From b361e43def8e99bcc1d3ada07d2455e3b48389fe Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 12 Sep 2024 20:23:08 +0800 Subject: [PATCH 13/21] Remove existing Helm repository if it exists before adding a new one. --- azd-hooks/postprovision.sh | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/azd-hooks/postprovision.sh b/azd-hooks/postprovision.sh index cc3b504..319c025 100755 --- a/azd-hooks/postprovision.sh +++ b/azd-hooks/postprovision.sh @@ -4,8 +4,18 @@ azd config set alpha.aks.helm on echo "Create Helm repository" HELM_REPO_URL="https://azure-javaee.github.io/cargotracker-liberty-aks" HELM_REPO_NAME="cargotracker-liberty-aks" + +# Check if the repo exists before removing +if helm repo list | grep -q "${HELM_REPO_NAME}"; then + helm repo remove ${HELM_REPO_NAME} + echo "Repo '${HELM_REPO_NAME}' removed." +else + echo "Repo '${HELM_REPO_NAME}' not found in the list." +fi + helm repo add ${HELM_REPO_NAME} ${HELM_REPO_URL} + export AKS_NAME=$(az aks list -g ${RESOURCE_GROUP_NAME} --query \[0\].name -o tsv) az aks enable-addons \ From 771ea7d5248941b3c13b92d662cdd4b9dcb85456 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 12 Sep 2024 20:44:13 +0800 Subject: [PATCH 14/21] Add postdeploy hook to create custom-values.yaml after application deployment. --- azd-hooks/postdeploy.sh | 8 ++++++++ azd-hooks/predeploy.sh | 38 +++++++++++++++++++------------------- azure.yaml | 6 ++++++ 3 files changed, 33 insertions(+), 19 deletions(-) create mode 100755 azd-hooks/postdeploy.sh diff --git a/azd-hooks/postdeploy.sh b/azd-hooks/postdeploy.sh new file mode 100755 index 0000000..d9b8c27 --- /dev/null +++ b/azd-hooks/postdeploy.sh @@ -0,0 +1,8 @@ +export GATEWAY_PUBLICIP_ID=$(az network application-gateway list \ + --resource-group ${RESOURCE_GROUP_NAME} \ + --query '[0].frontendIPConfigurations[0].publicIPAddress.id' -o tsv) +export GATEWAY_HOSTNAME=$(az network public-ip show --ids ${GATEWAY_PUBLICIP_ID} --query 'dnsSettings.fqdn' -o tsv) +export CARGO_TRACKER_URL="http://${GATEWAY_HOSTNAME}/cargo-tracker/" +echo "Cargo Tracker URL: ${CARGO_TRACKER_URL}" + +kubectl rollout restart deployment/cargo-tracker-cluster \ No newline at end of file diff --git a/azd-hooks/predeploy.sh b/azd-hooks/predeploy.sh index f6c039f..73b2dfc 100755 --- a/azd-hooks/predeploy.sh +++ b/azd-hooks/predeploy.sh @@ -3,22 +3,22 @@ # Build and push docker image to ACR echo "Get image name and version......" -run_maven_command() { - mvn -q -Dexec.executable=echo -Dexec.args="$1" --non-recursive exec:exec 2>/dev/null | sed -e 's/\x1b\[[0-9;]*m//g' | tr -d '\r\n' -} - -IMAGE_NAME=$(run_maven_command '${project.artifactId}') -IMAGE_VERSION=$(run_maven_command '${project.version}') - -echo "Build image and upload" - -mvn clean package -DskipTests -cd target -echo "docker build" -docker build -t ${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . -docker tag ${IMAGE_NAME}:${IMAGE_VERSION} ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} -docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} - -echo "Docker push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" - -docker push ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} +#run_maven_command() { +# mvn -q -Dexec.executable=echo -Dexec.args="$1" --non-recursive exec:exec 2>/dev/null | sed -e 's/\x1b\[[0-9;]*m//g' | tr -d '\r\n' +#} +# +#IMAGE_NAME=$(run_maven_command '${project.artifactId}') +#IMAGE_VERSION=$(run_maven_command '${project.version}') +# +#echo "Build image and upload" +# +#mvn clean package -DskipTests +#cd target +#echo "docker build" +#docker build -t ${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . +#docker tag ${IMAGE_NAME}:${IMAGE_VERSION} ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} +#docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} +# +#echo "Docker push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" +# +#docker push ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} diff --git a/azure.yaml b/azure.yaml index 9fc6045..7317cee 100644 --- a/azure.yaml +++ b/azure.yaml @@ -16,6 +16,12 @@ hooks: continueOnError: false interactive: true run: azd-hooks/predeploy.sh + postdeploy: # This hook is executed after the deployment of the application to create the custom-values.yaml file + posix: + shell: sh + continueOnError: false + interactive: true + run: azd-hooks/postdeploy.sh services: demo: From 5bbf23f9ebc0019c7f943fa008e10af9e789609c Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Thu, 12 Sep 2024 20:45:13 +0800 Subject: [PATCH 15/21] Refactor predeploy script for improved readability and maintainability. --- azd-hooks/predeploy.sh | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/azd-hooks/predeploy.sh b/azd-hooks/predeploy.sh index 73b2dfc..f6c039f 100755 --- a/azd-hooks/predeploy.sh +++ b/azd-hooks/predeploy.sh @@ -3,22 +3,22 @@ # Build and push docker image to ACR echo "Get image name and version......" -#run_maven_command() { -# mvn -q -Dexec.executable=echo -Dexec.args="$1" --non-recursive exec:exec 2>/dev/null | sed -e 's/\x1b\[[0-9;]*m//g' | tr -d '\r\n' -#} -# -#IMAGE_NAME=$(run_maven_command '${project.artifactId}') -#IMAGE_VERSION=$(run_maven_command '${project.version}') -# -#echo "Build image and upload" -# -#mvn clean package -DskipTests -#cd target -#echo "docker build" -#docker build -t ${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . -#docker tag ${IMAGE_NAME}:${IMAGE_VERSION} ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} -#docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} -# -#echo "Docker push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" -# -#docker push ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} +run_maven_command() { + mvn -q -Dexec.executable=echo -Dexec.args="$1" --non-recursive exec:exec 2>/dev/null | sed -e 's/\x1b\[[0-9;]*m//g' | tr -d '\r\n' +} + +IMAGE_NAME=$(run_maven_command '${project.artifactId}') +IMAGE_VERSION=$(run_maven_command '${project.version}') + +echo "Build image and upload" + +mvn clean package -DskipTests +cd target +echo "docker build" +docker build -t ${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . +docker tag ${IMAGE_NAME}:${IMAGE_VERSION} ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} +docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} + +echo "Docker push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" + +docker push ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} From ec8fb8c48cab47265f1ddbed0291a0a2a6ccc505 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Fri, 13 Sep 2024 16:41:39 +0800 Subject: [PATCH 16/21] make is compatible with Mac Chip OS --- azd-hooks/predeploy.sh | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/azd-hooks/predeploy.sh b/azd-hooks/predeploy.sh index f6c039f..f9c8a89 100755 --- a/azd-hooks/predeploy.sh +++ b/azd-hooks/predeploy.sh @@ -10,15 +10,14 @@ run_maven_command() { IMAGE_NAME=$(run_maven_command '${project.artifactId}') IMAGE_VERSION=$(run_maven_command '${project.version}') -echo "Build image and upload" +echo "Docker build and push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" mvn clean package -DskipTests cd target -echo "docker build" -docker build -t ${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . -docker tag ${IMAGE_NAME}:${IMAGE_VERSION} ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} -docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} -echo "Docker push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" +docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} +export DOCKER_BUILDKIT=1 +docker buildx create --use +docker buildx build --platform linux/amd64 -t ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . --load docker push ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} From fcd4ff861003a43acb72b36f63c6ce2e244c1330 Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Sat, 14 Sep 2024 10:06:15 +0800 Subject: [PATCH 17/21] Update artifact upload/download version to v4 in GitHub Actions workflow --- .github/workflows/setupOpenLibertyAks.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/setupOpenLibertyAks.yml b/.github/workflows/setupOpenLibertyAks.yml index bcef5ee..a4f1580 100644 --- a/.github/workflows/setupOpenLibertyAks.yml +++ b/.github/workflows/setupOpenLibertyAks.yml @@ -109,7 +109,7 @@ jobs: echo "artifactPath=azure.liberty.aks/target/$artifactName" >> $GITHUB_OUTPUT # Make the contents of the zip file available for use later in the workflow. - name: Archive azure.liberty.aks template - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 if: success() with: name: ${{steps.artifact_file.outputs.artifactName}} @@ -210,7 +210,7 @@ jobs: echo "artifactName=${artifactName}" >> $GITHUB_ENV echo "artifactName=${artifactName}" >> $GITHUB_OUTPUT - name: Download artifact for deployment - uses: actions/download-artifact@v1 + uses: actions/download-artifact@v4 with: name: ${{steps.artifact_file.outputs.artifactName}} - uses: azure/login@v1 @@ -236,7 +236,7 @@ jobs: s/#gitUserName#/${aksRepoUserName}/g" \ cargotracker/src/test/aks/parameters.json - name: Archive parameters.json - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v4 with: name: archivefiles path: cargotracker/src/test/aks/parameters.json From d72ddd227dfe1b766677d9c5173e3e6e567b4e2d Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Sat, 14 Sep 2024 16:07:16 +0800 Subject: [PATCH 18/21] Add Unit-3 section to automate deployments using AZD. --- README.md | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/README.md b/README.md index fabc442..027656f 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ Cargo Tracker is a Domain-Driven Design Jakarta EE application. The application * [Start monitoring Liberty logs in Azure Log Analytics](#start-monitoring-liberty-logs-in-azure-log-analytics) * [Start monitoring Cargo Tracker logs in Azure Log Analytics](#start-monitoring-cargo-tracker-logs-in-azure-log-analytics) * [Unit-2 - Automate deployments using GitHub Actions](#unit-2---automate-deployments-using-github-actions) + * [Unit-3 - Automate deployments using AZD](#unit-3---automate-deployments-using-AZD) * [Appendix 1 - Exercise Cargo Tracker Functionality](#appendix-1---exercise-cargo-tracker-functionality) * [Appendix 2 - Learn more about Cargo Tracker](#appendix-2---learn-more-about-cargo-tracker) @@ -717,6 +718,51 @@ This job is to build app, push it to ACR and apply it to Open Liberty server run * Print app URL. Print the cargo tracker URL to pipeline summary page. Now you'are able to access cargo tracker with the URL from your browser. +## Unit-3 - Automate deployments using AZD +Use following steps to automate deployments using the Azure Developer CLI (azd). + +### Prerequisites +1. [Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd) (azd) installed. +2. Docker installed. You can install Docker by following the instructions [here](https://docs.docker.com/get-docker/). +3. Azure CLI installed. You can install the Azure CLI by following the instructions [here](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). +4. Maven installed. You can install Maven by following the instructions [here](https://maven.apache.org/install.html). +5. Git installed. You can install Git by following the instructions [here](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). +6. Kubernetes CLI installed. You can install the Kubernetes CLI by following the instructions [here](https://kubernetes.io/docs/tasks/tools/install-kubectl/). + + +### How to Run + +1. Run the following command to authenticate with Azure using the Azure CLI. + ```bash + az login + ``` + +1. Run the following command to authenticate with Azure using the Azure Developer CLI (azd). + ```bash + azd auth login + ``` + +1. Run the following command to create a new environment using the Azure Developer CLI (azd). + + ```bash + azd env new --name cargotracker-liberty-aks-0914 + ``` + +1. Run the following command to provision the required Azure resources. Input the required parameters when prompted. + + ```bash + azd provision + ``` + +2. Run the following command to deploy the Cargo Tracker application to Azure Kubernetes Service (AKS) using the Azure Developer CLI (azd). + + ```bash + azd deploy + ``` + +3. Wait for the deployment to complete. Once the deployment is complete, you can access the Cargo Tracker application using the URL provided in the output. + + ## Appendix 1 - Exercise Cargo Tracker Functionality 1. On the main page, inspect the date timestamp, it should reflect today's date. For example, **3.2 2024-08-06 17:48:08**. From 29de04d987a638422dd6f07f8f3fc84c7da5ac17 Mon Sep 17 00:00:00 2001 From: Ed Burns Date: Fri, 20 Sep 2024 15:52:38 -0700 Subject: [PATCH 19/21] On branch 240814_azd_enable_gzh Tested. It works! modified: README.md Signed-off-by: Ed Burns --- README.md | 32 ++++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 027656f..76ab916 100644 --- a/README.md +++ b/README.md @@ -725,13 +725,17 @@ Use following steps to automate deployments using the Azure Developer CLI (azd). 1. [Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd) (azd) installed. 2. Docker installed. You can install Docker by following the instructions [here](https://docs.docker.com/get-docker/). 3. Azure CLI installed. You can install the Azure CLI by following the instructions [here](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). -4. Maven installed. You can install Maven by following the instructions [here](https://maven.apache.org/install.html). -5. Git installed. You can install Git by following the instructions [here](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git). -6. Kubernetes CLI installed. You can install the Kubernetes CLI by following the instructions [here](https://kubernetes.io/docs/tasks/tools/install-kubectl/). ### How to Run +1. Change into the directory that has cargo tracker checked out, and ensure the tag is checked out. + + ```bash + cd ${DIR}/cargotracker + git checkout 20240919 + ``` + 1. Run the following command to authenticate with Azure using the Azure CLI. ```bash az login @@ -742,10 +746,10 @@ Use following steps to automate deployments using the Azure Developer CLI (azd). azd auth login ``` -1. Run the following command to create a new environment using the Azure Developer CLI (azd). +1. Run the following command to create a new environment using the Azure Developer CLI (azd). It's a good idea to use a disambiguation prefix for your environment name, such as your initials and todays date. ```bash - azd env new --name cargotracker-liberty-aks-0914 + azd env new gzh0919-cargotracker-liberty-aks ``` 1. Run the following command to provision the required Azure resources. Input the required parameters when prompted. @@ -753,8 +757,16 @@ Use following steps to automate deployments using the Azure Developer CLI (azd). ```bash azd provision ``` + + For `administratorLoginPassword` enter `Secret123456`. + + When the provisioning completes, you'll see a message similar to the following: + + ```bash + SUCCESS: Your application was provisioned in Azure in 27 minutes 59 seconds. + ``` -2. Run the following command to deploy the Cargo Tracker application to Azure Kubernetes Service (AKS) using the Azure Developer CLI (azd). +2. Ensure Docker is running locally. Run the following command to deploy the Cargo Tracker application to Azure Kubernetes Service (AKS) using the Azure Developer CLI (azd). ```bash azd deploy @@ -762,6 +774,14 @@ Use following steps to automate deployments using the Azure Developer CLI (azd). 3. Wait for the deployment to complete. Once the deployment is complete, you can access the Cargo Tracker application using the URL provided in the output. +You can now exercise the Cargo Tracker functionality as shown in Appendix 1. + +### Clean up + +The steps in this section show you how to clean up and deallocte the resources deployed in the previous section. + +1. `azd down` + ## Appendix 1 - Exercise Cargo Tracker Functionality From 80fda3d683082f149353754e40ade9d44af9f07b Mon Sep 17 00:00:00 2001 From: zhihaoguo Date: Mon, 23 Sep 2024 14:00:06 +0800 Subject: [PATCH 20/21] Refactor ACR variable names for consistency and clarity. --- .github/workflows/package-helm-chart.yaml | 2 +- .gitignore | 1 + azd-hooks/postdeploy.sh | 2 +- azd-hooks/predeploy.sh | 8 ++++---- azd-hooks/preprovision.sh | 5 +---- azure.yaml | 2 +- .../cargotracker-liberty-aks/templates/app-insight.yaml | 2 +- charts/cargotracker-liberty-aks/templates/db-secret.yaml | 2 +- infra/main.bicep | 6 +++--- infra/shared/monitoring.bicep | 2 +- 10 files changed, 15 insertions(+), 17 deletions(-) diff --git a/.github/workflows/package-helm-chart.yaml b/.github/workflows/package-helm-chart.yaml index cb3f1fa..76a4203 100644 --- a/.github/workflows/package-helm-chart.yaml +++ b/.github/workflows/package-helm-chart.yaml @@ -64,4 +64,4 @@ jobs: uses: stefanprodan/helm-gh-pages@0ad2bb377311d61ac04ad9eb6f252fb68e207260 # v1.7.0 with: token: ${{ secrets.GITHUB_TOKEN }} - linting: off \ No newline at end of file + linting: off diff --git a/.gitignore b/.gitignore index 2952e82..e88986d 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,4 @@ hs_err_pid* target/* /custom-values.yaml +/.idea/ diff --git a/azd-hooks/postdeploy.sh b/azd-hooks/postdeploy.sh index d9b8c27..4fc9d1a 100755 --- a/azd-hooks/postdeploy.sh +++ b/azd-hooks/postdeploy.sh @@ -5,4 +5,4 @@ export GATEWAY_HOSTNAME=$(az network public-ip show --ids ${GATEWAY_PUBLICIP_ID} export CARGO_TRACKER_URL="http://${GATEWAY_HOSTNAME}/cargo-tracker/" echo "Cargo Tracker URL: ${CARGO_TRACKER_URL}" -kubectl rollout restart deployment/cargo-tracker-cluster \ No newline at end of file +kubectl rollout restart deployment/cargo-tracker-cluster diff --git a/azd-hooks/predeploy.sh b/azd-hooks/predeploy.sh index f9c8a89..ca580d4 100755 --- a/azd-hooks/predeploy.sh +++ b/azd-hooks/predeploy.sh @@ -10,14 +10,14 @@ run_maven_command() { IMAGE_NAME=$(run_maven_command '${project.artifactId}') IMAGE_VERSION=$(run_maven_command '${project.version}') -echo "Docker build and push to ACR Server ${ACRServer} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" +echo "Docker build and push to ACR Server ${ACR_SERVER} with image name ${IMAGE_NAME} and version ${IMAGE_VERSION}" mvn clean package -DskipTests cd target -docker login -u ${ACRUserName} -p ${ACRPassword} ${ACRServer} +docker login -u ${ACR_PASSWORD} -p ${ACR_PASSWORD} ${ACR_SERVER} export DOCKER_BUILDKIT=1 docker buildx create --use -docker buildx build --platform linux/amd64 -t ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . --load -docker push ${ACRServer}/${IMAGE_NAME}:${IMAGE_VERSION} +docker buildx build --platform linux/amd64 -t ${ACR_SERVER}/${IMAGE_NAME}:${IMAGE_VERSION} --pull --file=Dockerfile . --load +docker push ${ACR_SERVER}/${IMAGE_NAME}:${IMAGE_VERSION} diff --git a/azd-hooks/preprovision.sh b/azd-hooks/preprovision.sh index f8c320d..84f8c94 100755 --- a/azd-hooks/preprovision.sh +++ b/azd-hooks/preprovision.sh @@ -1,4 +1 @@ -# check if docker is installed -# check if kubectl is installed - -az extension add --upgrade -n application-insights \ No newline at end of file +az extension add --upgrade -n application-insights diff --git a/azure.yaml b/azure.yaml index 7317cee..df34fa0 100644 --- a/azure.yaml +++ b/azure.yaml @@ -33,4 +33,4 @@ services: - name: demo chart: cargotracker-liberty-aks/cargotracker-liberty-aks-chart version: 1.0.5 - values: custom-values.yaml # This file is created by the predeploy hook \ No newline at end of file + values: custom-values.yaml # This file is created by the predeploy hook diff --git a/charts/cargotracker-liberty-aks/templates/app-insight.yaml b/charts/cargotracker-liberty-aks/templates/app-insight.yaml index 4009a09..4ad0a46 100644 --- a/charts/cargotracker-liberty-aks/templates/app-insight.yaml +++ b/charts/cargotracker-liberty-aks/templates/app-insight.yaml @@ -5,4 +5,4 @@ metadata: namespace: "{{ .Values.namespace }}" type: Opaque stringData: - connection.string: "{{ .Values.appInsightConnectionString }}" \ No newline at end of file + connection.string: "{{ .Values.appInsightConnectionString }}" diff --git a/charts/cargotracker-liberty-aks/templates/db-secret.yaml b/charts/cargotracker-liberty-aks/templates/db-secret.yaml index b9426a3..dd507d5 100644 --- a/charts/cargotracker-liberty-aks/templates/db-secret.yaml +++ b/charts/cargotracker-liberty-aks/templates/db-secret.yaml @@ -9,4 +9,4 @@ stringData: db.port.number: "{{ .Values.db.PortNumber }}" db.name: "{{ .Values.db.Name }}" db.user: "{{ .Values.db.User }}" - db.password: "{{ .Values.db.Password }}" \ No newline at end of file + db.password: "{{ .Values.db.Password }}" diff --git a/infra/main.bicep b/infra/main.bicep index 241bc6a..bc6b8e4 100644 --- a/infra/main.bicep +++ b/infra/main.bicep @@ -95,9 +95,9 @@ module monitoring './shared/monitoring.bicep' = { scope: rg } -output ACRPassword string = openLibertyOnAks.outputs.acrPassword -output ACRServer string = openLibertyOnAks.outputs.acrServerName -output ACRUserName string = openLibertyOnAks.outputs.acrUsername +output ACR_PASSWORD string = openLibertyOnAks.outputs.acrPassword +output ACR_SERVER string = openLibertyOnAks.outputs.acrServerName +output ACR_USER_NAME string = openLibertyOnAks.outputs.acrUsername output AZURE_AKS_CLUSTER_NAME string = openLibertyOnAks.outputs.clusterName output AZURE_REGISTRY_NAME string = openLibertyOnAks.outputs.acrServerName output AZURE_RESOURCE_GROUP string = rg.name diff --git a/infra/shared/monitoring.bicep b/infra/shared/monitoring.bicep index cbcb813..4a77f84 100644 --- a/infra/shared/monitoring.bicep +++ b/infra/shared/monitoring.bicep @@ -32,4 +32,4 @@ resource applicationInsights 'Microsoft.Insights/components@2020-02-02' = { output applicationInsightsName string = applicationInsights.name output logAnalyticsWorkspaceId string = logAnalytics.id output logAnalyticsWorkspaceName string = logAnalytics.name -output appInsightsConnectionString string = applicationInsights.properties.ConnectionString \ No newline at end of file +output appInsightsConnectionString string = applicationInsights.properties.ConnectionString From ee1db280d39b7cad66a9c45f40ddbad9169799f0 Mon Sep 17 00:00:00 2001 From: Ed Burns Date: Tue, 24 Sep 2024 14:31:52 -0700 Subject: [PATCH 21/21] On branch 240814_azd_enable_gzh Address https://dev.azure.com/edburns-msft/Open%20Standard%20Enterprise%20Java%20(Java%20EE)%20on%20Azure/_workitems/edit/6183 > For these reasons, I need the copy-pasted code to be removed from the PR and replaced with a solution that causes the formerly copy-pasted code to be dynamically checked out, ideally using the same git commit ref in .scripts/setup-env-variables-template.sh deleted: infra/azure.liberty.aks/mainTemplate.bicep deleted: infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep deleted: infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep deleted: infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep deleted: infra/azure.liberty.aks/modules/_azure-resoruces/_keyvaultForGateway.bicep deleted: infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep deleted: infra/azure.liberty.aks/modules/_deployment-scripts/_ds-networking.bicep deleted: infra/azure.liberty.aks/modules/_deployment-scripts/_ds-preflight.bicep deleted: infra/azure.liberty.aks/modules/_deployment-scripts/_ds-primary.bicep deleted: infra/azure.liberty.aks/modules/_deployment-scripts/_ds_enable_agic.bicep deleted: infra/azure.liberty.aks/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep deleted: infra/azure.liberty.aks/modules/_pids/_empty.bicep deleted: infra/azure.liberty.aks/modules/_rolesAssignment/_acrPullRoleAssignment.bicep deleted: infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep deleted: infra/azure.liberty.aks/modules/_rolesAssignment/_roleAssignmentinSubscription.bicep deleted: infra/azure.liberty.aks/modules/_uamiAndRoles.bicep renamed: infra/azure.liberty.aks/parameters.json -> infra/azure.liberty.aks/parameters_json.template modified: README.md modified: infra/azure.liberty.aks/parameters_json.template Signed-off-by: Ed Burns --- README.md | 34 +- infra/azure.liberty.aks/mainTemplate.bicep | 542 ------------------ .../_azure-resoruces/_appgateway.bicep | 183 ------ .../_keyvault/_keyvaultWithExistingCert.bicep | 84 --- .../_keyvault/_keyvaultWithNewCert.bicep | 96 ---- .../_keyvaultForGateway.bicep | 85 --- .../_azure-resoruces/_vnetAppGateway.bicep | 112 ---- .../_deployment-scripts/_ds-networking.bicep | 101 ---- .../_deployment-scripts/_ds-preflight.bicep | 130 ----- .../_deployment-scripts/_ds-primary.bicep | 129 ----- .../_deployment-scripts/_ds_enable_agic.bicep | 63 -- ...ery_available_private_ip_from_subnet.bicep | 60 -- .../modules/_pids/_empty.bicep | 21 - .../_acrPullRoleAssignment.bicep | 53 -- .../_agicRoleAssignment.bicep | 43 -- .../_roleAssignmentinSubscription.bicep | 53 -- .../modules/_uamiAndRoles.bicep | 42 -- ...rameters.json => parameters_json.template} | 4 +- 18 files changed, 32 insertions(+), 1803 deletions(-) delete mode 100644 infra/azure.liberty.aks/mainTemplate.bicep delete mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep delete mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep delete mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep delete mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_keyvaultForGateway.bicep delete mode 100644 infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep delete mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds-networking.bicep delete mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds-preflight.bicep delete mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds-primary.bicep delete mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds_enable_agic.bicep delete mode 100644 infra/azure.liberty.aks/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep delete mode 100644 infra/azure.liberty.aks/modules/_pids/_empty.bicep delete mode 100644 infra/azure.liberty.aks/modules/_rolesAssignment/_acrPullRoleAssignment.bicep delete mode 100644 infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep delete mode 100644 infra/azure.liberty.aks/modules/_rolesAssignment/_roleAssignmentinSubscription.bicep delete mode 100644 infra/azure.liberty.aks/modules/_uamiAndRoles.bicep rename infra/azure.liberty.aks/{parameters.json => parameters_json.template} (80%) diff --git a/README.md b/README.md index 76ab916..9046300 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Cargo Tracker is a Domain-Driven Design Jakarta EE application. The application * [Clone Cargo Tracker](#clone-cargo-tracker) * [Prepare your variables for deployments](#prepare-your-variables-for-deployments) * [Clone Liberty on AKS Bicep templates](#clone-liberty-on-aks-bicep-templates) + * [Build Liberty on AKS Bicep templates](#build-liberty-on-aks-bicep-templates) * [Sign in to Azure](#sign-in-to-azure) * [Create a resource group](#create-a-resource-group) * [Prepare deployment parameters](#prepare-deployment-parameters) @@ -74,7 +75,7 @@ export DIR="$PWD/cargotracker-liberty-aks" git clone https://github.com/Azure-Samples/cargotracker-liberty-aks.git ${DIR}/cargotracker cd ${DIR}/cargotracker -git checkout 20240808 +git checkout 20240924 ``` If you see a message about `detached HEAD state`, it is safe to ignore. It just means you have checked out a tag. @@ -128,7 +129,6 @@ mvn install:install-file -Dfile=${DIR}/azure-javaee-iaas-parent-${VERSION}.pom \ cd ${DIR}/azure.liberty.aks mvn clean package -DskipTests - ``` ### Sign in to Azure @@ -725,15 +725,38 @@ Use following steps to automate deployments using the Azure Developer CLI (azd). 1. [Azure Developer CLI](https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd) (azd) installed. 2. Docker installed. You can install Docker by following the instructions [here](https://docs.docker.com/get-docker/). 3. Azure CLI installed. You can install the Azure CLI by following the instructions [here](https://docs.microsoft.com/en-us/cli/azure/install-azure-cli). +4. You have executed the following steps from the preceding units: + 1. [Clone Cargo Tracker](#clone-cargo-tracker) + 1. [Prepare your variables for deployments](#prepare-your-variables-for-deployments) + 1. [Clone Liberty on AKS Bicep templates](#clone-liberty-on-aks-bicep-templates) + 1. [Build Liberty on AKS Bicep templates](#build-liberty-on-aks-bicep-templates) +5. Populate the `infra/azure.liberty.aks` directory with the built Liberty on AKS Bicep templates. + ```bash + cd infra/azure.liberty.aks + envsubst < parameters_json.template > parameters.json + ``` + + Verify the environment variables have been successfully replaced: + + ```bash + grep azure.liberty.aks parameters.json + ``` + + You should see no `$` characters in this output. If you see a `$` in the output, ensure you have followed the steps in **Prepare your variables for deployments**. + +6. Copy the built Liberty on AKS Bicep templates so azd can invoke them. + + ```bash + cp -r ${DIR}/azure.liberty.aks/target/bicep/* . + ``` ### How to Run -1. Change into the directory that has cargo tracker checked out, and ensure the tag is checked out. +1. Change into the directory that has cargo tracker checked out. ```bash cd ${DIR}/cargotracker - git checkout 20240919 ``` 1. Run the following command to authenticate with Azure using the Azure CLI. @@ -754,6 +777,9 @@ Use following steps to automate deployments using the Azure Developer CLI (azd). 1. Run the following command to provision the required Azure resources. Input the required parameters when prompted. + * Be sure to select the correct Azure subscription when prompted. + * We observe that `westus` region has a higher likelihood of success than `eastus`. + ```bash azd provision ``` diff --git a/infra/azure.liberty.aks/mainTemplate.bicep b/infra/azure.liberty.aks/mainTemplate.bicep deleted file mode 100644 index 767490b..0000000 --- a/infra/azure.liberty.aks/mainTemplate.bicep +++ /dev/null @@ -1,542 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -@description('The base URI where artifacts required by this template are located. When the template is deployed using the accompanying scripts, a private location in the subscription will be used and this value will be automatically generated.') -param _artifactsLocation string = deployment().properties.templateLink.uri - -@description('The sasToken required to access _artifactsLocation. When the template is deployed using the accompanying scripts, a sasToken will be automatically generated. Use the defaultValue if the staging location is not secured.') -@secure() -param _artifactsLocationSasToken string = '' - -@description('Location for all resources.') -param location string = resourceGroup().location - -@description('Flag indicating whether to create a new cluster or not') -param createCluster bool = true - -@description('The VM size of the cluster') -param vmSize string = 'Standard_DS2_v2' - -@description('The minimum node count of the cluster') -param minCount int = 1 - -@description('The maximum node count of the cluster') -param maxCount int = 5 - -@description('Name for the existing cluster') -param clusterName string = '' - -@description('Name for the resource group of the existing cluster') -param clusterRGName string = '' - -@description('Flag indicating whether to create a new ACR or not') -param createACR bool = true - -@description('Name for the existing ACR') -param acrName string = '' - -@description('Name for the resource group of the existing ACR') -param acrRGName string = '' - -@description('true to set up Application Gateway ingress.') -param enableAppGWIngress bool = false - -@description('VNET for Application Gateway.') -param vnetForApplicationGateway object = { - name: 'olaks-app-gateway-vnet' - resourceGroup: resourceGroup().name - addressPrefixes: [ - '172.16.0.0/24' - ] - addressPrefix: '172.16.0.0/24' - newOrExisting: 'new' - subnets: { - gatewaySubnet: { - name: 'olaks-gateway-subnet' - addressPrefix: '172.16.0.0/24' - startAddress: '172.16.0.4' - } - } -} -@description('To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the newOrExisting property when hideExisting is false') -param newOrExistingVnetForApplicationGateway string = 'new' -@description('To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the resourceGroup property when hideExisting is false') -param vnetRGNameForApplicationGateway string = 'vnet-contoso-rg-name' -@description('If true, configure Azure Application Gateway frontend IP with private IP.') -param appgwUsePrivateIP bool = false - -@description('DNS prefix for ApplicationGateway') -param dnsNameforApplicationGateway string = 'olgw' - -@allowed([ - 'haveCert' - 'haveKeyVault' - 'generateCert' -]) -@description('Three scenarios we support for deploying app gateway') -param appGatewayCertificateOption string = 'haveCert' - -@description('Public IP Name for the Application Gateway') -param appGatewayPublicIPAddressName string = 'gwip' - -@secure() -@description('The one-line, base64 string of the SSL certificate data.') -param appGatewaySSLCertData string = newGuid() - -@secure() -@description('The value of the password for the SSL Certificate') -param appGatewaySSLCertPassword string = newGuid() - -@description('Resource group name in current subscription containing the KeyVault') -param keyVaultResourceGroup string = 'kv-contoso-rg' - -@description('Existing Key Vault Name') -param keyVaultName string = 'kv-contoso' - -@description('Price tier for Key Vault.') -param keyVaultSku string = 'Standard' - -@description('The name of the secret in the specified KeyVault whose value is the SSL Certificate Data for Appliation Gateway frontend TLS/SSL.') -param keyVaultSSLCertDataSecretName string = 'kv-ssl-data' - -@description('The name of the secret in the specified KeyVault whose value is the password for the SSL Certificate of Appliation Gateway frontend TLS/SSL') -param keyVaultSSLCertPasswordSecretName string = 'kv-ssl-psw' - -@description('true to enable cookie based affinity.') -param enableCookieBasedAffinity bool = false - -@description('Flag indicating whether to deploy WebSphere Liberty Operator.') -param deployWLO bool = false - -@allowed([ - 'IBM WebSphere Application Server' - 'IBM WebSphere Application Server Liberty Core' - 'IBM WebSphere Application Server Network Deployment' -]) -@description('Product edition') -param edition string = 'IBM WebSphere Application Server' - -@allowed([ - 'Standalone' - 'IBM WebSphere Hybrid Edition' - 'IBM Cloud Pak for Applications' - 'IBM WebSphere Application Server Family Edition' -]) -@description('Entitlement source for the product') -param productEntitlementSource string = 'Standalone' - -@description('Flag indicating whether to deploy an application') -param deployApplication bool = false - -@description('The image path of the application') -param appImagePath string = '' - -@description('The number of application replicas to deploy') -param appReplicas int = 2 - -@description('Flag indicating whether to enable autoscaling for app deployment') -param autoScaling bool = false - -@description('The target average CPU utilization percentage for autoscaling') -param cpuUtilizationPercentage int = 80 - -@description('The minimum application replicas for autoscaling') -param minReplicas int = 1 - -@description('The maximum application replicas for autoscaling') -param maxReplicas int = 100 - -@description('The minimum required CPU core (millicore) over all the replicas for autoscaling') -param requestCPUMillicore int = 300 - -param guidValue string = take(replace(newGuid(), '-', ''), 6) - -var const_acrRGName = (createACR ? resourceGroup().name : acrRGName) -var const_appGatewaySSLCertOptionHaveCert = 'haveCert' -var const_appGatewaySSLCertOptionHaveKeyVault = 'haveKeyVault' -var const_appFrontendTlsSecretName = format('secret{0}', guidValue) -var const_appImage = format('{0}:{1}', const_appImageName, const_appImageTag) -var const_appImageName = format('image{0}', guidValue) -var const_appImagePath = (empty(appImagePath) ? 'NA' : ((const_appImagePathLen == 1) ? format('docker.io/library/{0}', appImagePath) : ((const_appImagePathLen == 2) ? format('docker.io/{0}', appImagePath) : appImagePath))) -var const_appImagePathLen = length(split(appImagePath, '/')) -var const_appImageTag = '1.0.0' -var const_appName = format('app{0}', guidValue) -var const_appProjName = 'default' -var const_arguments = format('{0} {1} {2} {3} {4} {5} {6} {7} {8}', const_clusterRGName, name_clusterName, name_acrName, deployApplication, const_appImagePath, const_appName, const_appProjName, const_appImage, appReplicas) -var const_azureSubjectName = format('{0}.{1}.{2}', name_dnsNameforApplicationGateway, location, 'cloudapp.azure.com') -var const_clusterRGName = (createCluster ? resourceGroup().name : clusterRGName) -var const_cmdToGetAcrLoginServer = format('az acr show -n {0} --query loginServer -o tsv', name_acrName) -var const_metric = productEntitlementSource == 'Standalone' || productEntitlementSource == 'IBM WebSphere Application Server Family Edition' ? 'Processor Value Unit (PVU)' : 'Virtual Processor Core (VPC)' -var const_newVnet = (vnetForApplicationGateway.newOrExisting == 'new') ? true : false -var name_acrName = createACR ? format('acr{0}', guidValue) : acrName -var name_appGatewayPublicIPAddressName = format('{0}{1}', appGatewayPublicIPAddressName, guidValue) -var name_clusterName = createCluster ? format('cluster{0}', guidValue) : clusterName -var name_dnsNameforApplicationGateway = format('{0}{1}', dnsNameforApplicationGateway, guidValue) -var name_keyVaultName = format('keyvault{0}', guidValue) -var name_prefilghtDsName = format('preflightds{0}', guidValue) -var name_primaryDsName = format('primaryds{0}', guidValue) -var name_subnet = vnetForApplicationGateway.subnets.gatewaySubnet.name -var name_vnet = vnetForApplicationGateway.name -var ref_subId = const_newVnet ? resourceId('Microsoft.Network/virtualNetworks/subnets', name_vnet, name_subnet) : existingSubnet.id - -var obj_uamiForDeploymentScript = { - type: 'UserAssigned' - userAssignedIdentities: { - '${uamiDeployment.outputs.uamiIdForDeploymentScript}': {} - } -} - -// Workaround arm-ttk test "Parameter Types Should Be Consistent" -var _appgwUsePrivateIP = appgwUsePrivateIP -var _appGatewaySubnetStartAddress = vnetForApplicationGateway.subnets.gatewaySubnet.startAddress -var _enableAppGWIngress = enableAppGWIngress -var _useExistingAppGatewaySSLCertificate = appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveCert - -module partnerCenterPid './modules/_pids/_empty.bicep' = { - name: 'pid-68a0b448-a573-4012-ab25-d5dc9842063e-partnercenter' - params: {} -} - -module uamiDeployment 'modules/_uamiAndRoles.bicep' = { - name: 'uami-deployment' - params: { - location: location - } -} - -module aksStartPid './modules/_pids/_empty.bicep' = { - name: '628cae16-c133-5a2e-ae93-2b44748012fe' - params: {} -} - -module preflightDsDeployment 'modules/_deployment-scripts/_ds-preflight.bicep' = { - name: name_prefilghtDsName - params: { - name: name_prefilghtDsName - location: location - _artifactsLocation: _artifactsLocation - _artifactsLocationSasToken: _artifactsLocationSasToken - identity: obj_uamiForDeploymentScript - createCluster: createCluster - aksClusterName: name_clusterName - aksClusterRGName: const_clusterRGName - enableAppGWIngress: enableAppGWIngress - vnetForApplicationGateway: vnetForApplicationGateway - appGatewayCertificateOption: appGatewayCertificateOption - keyVaultName: keyVaultName - keyVaultResourceGroup: keyVaultResourceGroup - keyVaultSSLCertDataSecretName: keyVaultSSLCertDataSecretName - keyVaultSSLCertPasswordSecretName: keyVaultSSLCertPasswordSecretName - appGatewaySSLCertData: appGatewaySSLCertData - appGatewaySSLCertPassword: appGatewaySSLCertPassword - vmSize: vmSize - deployApplication: deployApplication - sourceImagePath: const_appImagePath - } - dependsOn: [ - uamiDeployment - ] -} - -resource acrDeployment 'Microsoft.ContainerRegistry/registries@2023-07-01' = if (createACR) { - name: name_acrName - location: location - sku: { - name: 'Basic' - } - properties: { - adminUserEnabled: true - } - dependsOn: [ - preflightDsDeployment - ] -} - -// Get existing VNET -resource existingVnet 'Microsoft.Network/virtualNetworks@2023-11-01' existing = if (enableAppGWIngress && !const_newVnet) { - name: name_vnet - scope: resourceGroup(vnetForApplicationGateway.resourceGroup) -} - -// Get existing subnet -resource existingSubnet 'Microsoft.Network/virtualNetworks/subnets@2023-11-01' existing = if (enableAppGWIngress && !const_newVnet) { - name: name_subnet - parent: existingVnet -} - -// To void space overlap with AKS Vnet, must deploy the Applciation Gateway VNet before AKS deployment -module vnetForAppgatewayDeployment 'modules/_azure-resoruces/_vnetAppGateway.bicep' = if (enableAppGWIngress) { - name: 'vnet-application-gateway' - params: { - location: location - nameSuffix: guidValue - newOrExistingVnetForApplicationGateway: newOrExistingVnetForApplicationGateway - vnetForApplicationGateway: vnetForApplicationGateway - vnetRGNameForApplicationGateway: vnetRGNameForApplicationGateway - } - dependsOn: [ - preflightDsDeployment - ] -} - -resource clusterDeployment 'Microsoft.ContainerService/managedClusters@2023-08-01' = if (createCluster) { - name: name_clusterName - location: location - properties: { - enableRBAC: true - dnsPrefix: format('{0}-dns', name_clusterName) - agentPoolProfiles: [ - { - name: 'agentpool' - osDiskSizeGB: 0 - enableAutoScaling: true - minCount: minCount - maxCount: maxCount - count: minCount - vmSize: vmSize - osType: 'Linux' - type: 'VirtualMachineScaleSets' - mode: 'System' - availabilityZones: preflightDsDeployment.outputs.aksAgentAvailabilityZones - } - ] - networkProfile: { - loadBalancerSku: 'standard' - networkPlugin: 'kubenet' - } - } - identity: { - type: 'SystemAssigned' - } - dependsOn: [ - acrDeployment - vnetForAppgatewayDeployment - ] -} - -module acrPullRoleAssignment 'modules/_rolesAssignment/_acrPullRoleAssignment.bicep' = { - name: 'assign-acrpull-role-to-kubelet-identity' - scope: resourceGroup(const_acrRGName) - params: { - aksClusterName: name_clusterName - aksClusterRGName: const_clusterRGName - acrName: name_acrName - acrRGName: const_acrRGName - } - dependsOn: [ - clusterDeployment - ] -} - -module appgwStartPid './modules/_pids/_empty.bicep' = if (enableAppGWIngress) { - name: '43c417c4-4f5a-555e-a9ba-b2d01d88de1f' - params: {} - dependsOn: [ - acrPullRoleAssignment - ] -} - -module appgwSecretDeployment 'modules/_azure-resoruces/_keyvaultForGateway.bicep' = if (enableAppGWIngress && (appGatewayCertificateOption != const_appGatewaySSLCertOptionHaveKeyVault)) { - name: 'appgateway-certificates-secrets-deployment' - params: { - certificateDataValue: appGatewaySSLCertData - certificatePasswordValue: appGatewaySSLCertPassword - identity: obj_uamiForDeploymentScript - location: location - sku: keyVaultSku - subjectName: format('CN={0}', const_azureSubjectName) - useExistingAppGatewaySSLCertificate: _useExistingAppGatewaySSLCertificate - keyVaultName: name_keyVaultName - } - dependsOn: [ - appgwStartPid - ] -} - -// get key vault object in a resource group -resource existingKeyvault 'Microsoft.KeyVault/vaults@2023-07-01' existing = if (enableAppGWIngress) { - name: (!enableAppGWIngress || appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault) ? keyVaultName : appgwSecretDeployment.outputs.keyVaultName - scope: resourceGroup(appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault ? keyVaultResourceGroup : resourceGroup().name) -} - -module queryPrivateIPFromSubnet 'modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep' = if (enableAppGWIngress && appgwUsePrivateIP) { - name: 'query-available-private-ip-for-app-gateway' - params: { - _artifactsLocation: _artifactsLocation - _artifactsLocationSasToken: _artifactsLocationSasToken - identity: obj_uamiForDeploymentScript - location: location - subnetId: ref_subId - - knownIP: _appGatewaySubnetStartAddress - } - dependsOn: [ - vnetForAppgatewayDeployment - ] -} - -module appgwDeployment 'modules/_azure-resoruces/_appgateway.bicep' = if (enableAppGWIngress) { - name: 'app-gateway-deployment' - params: { - dnsNameforApplicationGateway: name_dnsNameforApplicationGateway - gatewayPublicIPAddressName: name_appGatewayPublicIPAddressName - nameSuffix: guidValue - location: location - gatewaySubnetId: ref_subId - staticPrivateFrontentIP: _appgwUsePrivateIP ? queryPrivateIPFromSubnet.outputs.privateIP : '' - usePrivateIP: appgwUsePrivateIP - } - dependsOn: [ - appgwStartPid - queryPrivateIPFromSubnet - ] -} - -module enableAgic 'modules/_deployment-scripts/_ds_enable_agic.bicep' = if (enableAppGWIngress) { - name: 'enable-agic' - params: { - _artifactsLocation: _artifactsLocation - _artifactsLocationSasToken: _artifactsLocationSasToken - location: location - - identity: obj_uamiForDeploymentScript - - aksClusterName: name_clusterName - aksClusterRGName: const_clusterRGName - appgwName: _enableAppGWIngress ? appgwDeployment.outputs.appGatewayName : '' - } - dependsOn: [ - appgwDeployment - ] -} - -module agicRoleAssignment 'modules/_rolesAssignment/_agicRoleAssignment.bicep' = if (enableAppGWIngress) { - name: 'allow-agic-access-current-resource-group' - params: { - aksClusterName: name_clusterName - aksClusterRGName: const_clusterRGName - } - dependsOn: [ - enableAgic - ] -} - -module networkingDeployment 'modules/_deployment-scripts/_ds-networking.bicep' = if (enableAppGWIngress) { - name: 'networking-deployment' - params: { - _artifactsLocation: _artifactsLocation - _artifactsLocationSasToken: _artifactsLocationSasToken - location: location - - identity: obj_uamiForDeploymentScript - - appgwCertificateOption: appGatewayCertificateOption - appgwFrontendSSLCertData: existingKeyvault.getSecret((!enableAppGWIngress || appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault) ? keyVaultSSLCertDataSecretName : appgwSecretDeployment.outputs.sslCertDataSecretName) - appgwFrontendSSLCertPsw: existingKeyvault.getSecret((!enableAppGWIngress || appGatewayCertificateOption == const_appGatewaySSLCertOptionHaveKeyVault) ? keyVaultSSLCertPasswordSecretName : appgwSecretDeployment.outputs.sslCertPwdSecretName) - - appgwName: _enableAppGWIngress ? appgwDeployment.outputs.appGatewayName : '' - - aksClusterRGName: const_clusterRGName - aksClusterName: name_clusterName - appFrontendTlsSecretName: const_appFrontendTlsSecretName - appProjName: const_appProjName - } - dependsOn: [ - appgwSecretDeployment - agicRoleAssignment - ] -} - -module appgwEndPid './modules/_pids/_empty.bicep' = if (enableAppGWIngress) { - name: 'dfa75d32-05de-5635-9833-b004cabcd378' - params: {} - dependsOn: [ - networkingDeployment - ] -} - -module primaryDsDeployment 'modules/_deployment-scripts/_ds-primary.bicep' = { - name: name_primaryDsName - params: { - name: name_primaryDsName - location: location - _artifactsLocation: _artifactsLocation - _artifactsLocationSasToken: _artifactsLocationSasToken - identity: obj_uamiForDeploymentScript - arguments: const_arguments - acrRGName: const_acrRGName - deployWLO: deployWLO - edition: edition - productEntitlementSource: productEntitlementSource - metric: const_metric - deployApplication: deployApplication - enableAppGWIngress: enableAppGWIngress - appFrontendTlsSecretName: const_appFrontendTlsSecretName - enableCookieBasedAffinity: enableCookieBasedAffinity - appgwUsePrivateIP: appgwUsePrivateIP - autoScaling: autoScaling - cpuUtilizationPercentage: cpuUtilizationPercentage - minReplicas: minReplicas - maxReplicas: maxReplicas - requestCPUMillicore: requestCPUMillicore - } - dependsOn: [ - acrPullRoleAssignment - appgwEndPid - ] -} - -module aksEndPid './modules/_pids/_empty.bicep' = { - name: '59f5f6da-0a6d-587d-b23c-177108cd8bbf' - params: {} - dependsOn: [ - primaryDsDeployment - ] -} - -module autoscalingPid './modules/_pids/_empty.bicep' = if (deployApplication && autoScaling) { - name: '7a4e4f27-dcea-5207-86ed-e7c7de1ccd34' - params: {} - dependsOn: [ - aksEndPid - ] -} - -output appHttpEndpoint string = deployApplication ? (enableAppGWIngress ? appgwDeployment.outputs.appGatewayURL : primaryDsDeployment.outputs.appEndpoint ) : '' -output appHttpsEndpoint string = deployApplication && enableAppGWIngress ? appgwDeployment.outputs.appGatewaySecuredURL : '' -output clusterName string = name_clusterName -output clusterRGName string = const_clusterRGName -output acrName string = name_acrName -output acrServerName string = createACR ? acrDeployment.properties.loginServer : '' -output acrUsername string = createACR ? acrDeployment.name : '' -output acrPassword string = createACR ? listCredentials(acrDeployment.id, acrDeployment.apiVersion).passwords[0].value : '' -output cmdToGetAcrLoginServer string = const_cmdToGetAcrLoginServer -output appNamespaceName string = const_appProjName -output appName string = deployApplication ? const_appName : '' -output appImage string = deployApplication ? const_appImage : '' -output cmdToConnectToCluster string = format('az aks get-credentials -g {0} -n {1} --admin', const_clusterRGName, name_clusterName) -output cmdToGetAppInstance string = deployApplication ? format('kubectl get openlibertyapplication {0}', const_appName) : '' -output cmdToGetAppDeployment string = deployApplication ? format('kubectl get deployment {0}', const_appName) : '' -output cmdToGetAppPods string = deployApplication ? 'kubectl get pod' : '' -output cmdToGetAppService string = deployApplication ? format('kubectl get service {0}', const_appName) : '' -output cmdToLoginInRegistry string = format('az acr login -n {0}', name_acrName) -output cmdToPullImageFromRegistry string = deployApplication ? format('docker pull $({0})/{1}', const_cmdToGetAcrLoginServer, const_appImage) : '' -output cmdToTagImageWithRegistry string = format('docker tag $({0})/', const_cmdToGetAcrLoginServer) -output cmdToPushImageToRegistry string = format('docker push $({0})/', const_cmdToGetAcrLoginServer) -output appDeploymentYaml string = deployApplication? format('echo "{0}" | base64 -d', primaryDsDeployment.outputs.appDeploymentYaml) : '' -output appDeploymentTemplateYaml string = !deployApplication ? format('echo "{0}" | base64 -d', primaryDsDeployment.outputs.appDeploymentYaml) : '' -output cmdToUpdateOrCreateApplication string = 'kubectl apply -f ' diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep deleted file mode 100644 index 9cdc4e6..0000000 --- a/infra/azure.liberty.aks/modules/_azure-resoruces/_appgateway.bicep +++ /dev/null @@ -1,183 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -@description('DNS for ApplicationGateway') -param dnsNameforApplicationGateway string = format('olgw{0}', guidValue) -@description('Public IP Name for the Application Gateway') -param gatewayPublicIPAddressName string = format('gwip{0}', guidValue) -param nameSuffix string = '' -param location string -param gatewaySubnetId string = '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/resourcegroupname/providers/Microsoft.Network/virtualNetworks/vnetname/subnets/subnetname' -param staticPrivateFrontentIP string = '10.0.0.1' -param usePrivateIP bool = false -param guidValue string = take(replace(newGuid(), '-', ''), 6) - -var const_nameSuffix = empty(nameSuffix) ? guidValue : nameSuffix -var name_appGateway = format('appgw{0}', const_nameSuffix) -var name_backendAddressPool = 'myGatewayBackendPool' -var name_frontEndIPConfig = 'appGwPublicFrontendIp' -var name_frontEndPrivateIPConfig = 'appGwPrivateFrontendIp' -var name_httpListener = 'HTTPListener' -var name_httpPort = 'httpport' -var name_httpSetting = 'myHTTPSetting' -var ref_backendAddressPool = resourceId('Microsoft.Network/applicationGateways/backendAddressPools', name_appGateway, name_backendAddressPool) -var ref_backendHttpSettings = resourceId('Microsoft.Network/applicationGateways/backendHttpSettingsCollection', name_appGateway, name_httpSetting) -var ref_frontendHTTPPort = resourceId('Microsoft.Network/applicationGateways/frontendPorts', name_appGateway, name_httpPort) -var ref_frontendIPConfiguration = resourceId('Microsoft.Network/applicationGateways/frontendIPConfigurations', name_appGateway, name_frontEndIPConfig) -var ref_httpListener = resourceId('Microsoft.Network/applicationGateways/httpListeners', name_appGateway, name_httpListener) -var ref_publicIPAddress = resourceId('Microsoft.Network/publicIPAddresses', gatewayPublicIPAddressName) -var obj_frontendIPConfigurations1 = [ - { - name: name_frontEndIPConfig - properties: { - publicIPAddress: { - id: ref_publicIPAddress - } - } - } -] -var obj_frontendIPConfigurations2 = [ - { - name: name_frontEndIPConfig - properties: { - publicIPAddress: { - id: ref_publicIPAddress - } - } - } - { - name: name_frontEndPrivateIPConfig - properties: { - privateIPAllocationMethod: 'Static' - privateIPAddress: staticPrivateFrontentIP - subnet: { - id: gatewaySubnetId - } - } - } -] - -resource gatewayPublicIP 'Microsoft.Network/publicIPAddresses@2023-11-01' = { - name: gatewayPublicIPAddressName - sku: { - name: 'Standard' - } - location: location - properties: { - publicIPAllocationMethod: 'Static' - dnsSettings: { - domainNameLabel: dnsNameforApplicationGateway - } - } -} - -resource wafv2AppGateway 'Microsoft.Network/applicationGateways@2023-11-01' = { - name: name_appGateway - location: location - tags: { - 'managed-by-k8s-ingress': 'true' - } - properties: { - sku: { - name: 'WAF_v2' - tier: 'WAF_v2' - } - gatewayIPConfigurations: [ - { - name: 'appGatewayIpConfig' - properties: { - subnet: { - id: gatewaySubnetId - } - } - } - ] - frontendIPConfigurations: usePrivateIP ? obj_frontendIPConfigurations2 : obj_frontendIPConfigurations1 - frontendPorts: [ - { - name: name_httpPort - properties: { - port: 80 - } - } - ] - backendAddressPools: [ - { - name: 'myGatewayBackendPool' - } - ] - httpListeners: [ - { - name: name_httpListener - properties: { - protocol: 'Http' - frontendIPConfiguration: { - id: ref_frontendIPConfiguration - } - frontendPort: { - id: ref_frontendHTTPPort - } - } - } - ] - backendHttpSettingsCollection: [ - { - name: name_httpSetting - properties: { - port: 80 - protocol: 'Http' - } - } - ] - requestRoutingRules: [ - { - name: 'HTTPRoutingRule' - properties: { - priority: 3 - httpListener: { - id: ref_httpListener - } - backendAddressPool: { - id: ref_backendAddressPool - } - backendHttpSettings: { - id: ref_backendHttpSettings - } - } - } - ] - webApplicationFirewallConfiguration: { - enabled: true - firewallMode: 'Prevention' - ruleSetType: 'OWASP' - ruleSetVersion: '3.0' - } - enableHttp2: false - autoscaleConfiguration: { - minCapacity: 2 - maxCapacity: 3 - } - } - dependsOn: [ - gatewayPublicIP - ] -} - -output appGatewayAlias string = usePrivateIP ? staticPrivateFrontentIP : reference(gatewayPublicIP.id).dnsSettings.fqdn -output appGatewayName string = name_appGateway -output appGatewayURL string = uri(format('http://{0}/', usePrivateIP ? staticPrivateFrontentIP : reference(gatewayPublicIP.id).dnsSettings.fqdn), '') -output appGatewaySecuredURL string = uri(format('https://{0}/', usePrivateIP ? staticPrivateFrontentIP : reference(gatewayPublicIP.id).dnsSettings.fqdn), '') diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep deleted file mode 100644 index c314c97..0000000 --- a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithExistingCert.bicep +++ /dev/null @@ -1,84 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -@description('Secret name of certificate data.') -param certificateDataName string = 'myIdentityKeyStoreData' - -@secure() -@description('Certificate data to store in the secret') -param certificateDataValue string = newGuid() - -@description('Secret name of certificate password.') -param certificatePswSecretName string = 'myIdentityKeyStorePsw' - -@secure() -@description('Certificate password to store in the secret') -param certificatePasswordValue string = newGuid() - -@description('Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') -param enabledForTemplateDeployment bool = true - -@description('Name of the vault') -param keyVaultName string = 'kv-${uniqueString(utcValue)}' - -param location string - -@description('Price tier for Key Vault.') -param sku string = 'Standard' - -param utcValue string = utcNow() - -resource keyvault 'Microsoft.KeyVault/vaults@2023-07-01' = { - name: keyVaultName - location: location - properties: { - accessPolicies: [] - enabledForTemplateDeployment: enabledForTemplateDeployment - sku: { - name: sku - family: 'A' - } - tenantId: subscription().tenantId - } - tags:{ - 'managed-by-azure-liberty-aks': utcValue - } -} - -resource secretForCertificate 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = { - name: format('{0}/{1}', keyVaultName, certificateDataName) - properties: { - value: certificateDataValue - } - dependsOn: [ - keyvault - ] -} - -resource secretForCertPassword 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = { - name: format('{0}/{1}', keyVaultName, certificatePswSecretName) - properties: { - value: certificatePasswordValue - } - dependsOn: [ - keyvault - ] -} - -output keyVaultName string = keyVaultName -output sslCertDataSecretName string = certificateDataName -output sslCertPwdSecretName string = certificatePswSecretName diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep deleted file mode 100644 index 32b35be..0000000 --- a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvault/_keyvaultWithNewCert.bicep +++ /dev/null @@ -1,96 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -@description('Managed identity to be used for the deployment script. Currently, only user-assigned MSI is supported.') -param identity object = {} - -@description('Used to name the new Azure Key Vault resoure.') -param keyVaultName string = 'kv-${uniqueString(utcValue)}' - -param location string - -@description('Access permission of the key vault, will applied to all access policies.') -param permission object = { - certificates: [ - 'get' - 'list' - 'update' - 'create' - ] -} - -@description('Used to name the new certificate resource.') -param secretName string = 'mySelfSignedCertificate' - -@description('Price tier for Key Vault.') -param sku string = 'Standard' - -@description('Subject name to create a new certificate, example: \'CN=contoso.com\'.') -param subjectName string = 'contoso.xyz' -param utcValue string = utcNow() - -var const_identityId = substring(string(identity.userAssignedIdentities), indexOf(string(identity.userAssignedIdentities), '"') + 1, lastIndexOf(string(identity.userAssignedIdentities), '"') - (indexOf(string(identity.userAssignedIdentities), '"') + 1)) - -resource keyvault 'Microsoft.KeyVault/vaults@2023-07-01' = { - name: keyVaultName - location: location - properties: { - sku: { - family: 'A' - name: sku - } - tenantId: subscription().tenantId - accessPolicies: [ - { - // Must specify API version of identity. - objectId: reference(const_identityId, '2023-01-31').principalId - tenantId: subscription().tenantId - permissions: permission - } - ] - enabledForDeployment: false - enabledForDiskEncryption: false - enabledForTemplateDeployment: true - enableSoftDelete: true - } - tags:{ - 'managed-by-azure-liberty-aks': utcValue - } -} - -resource createAddCertificate 'Microsoft.Resources/deploymentScripts@2023-08-01' = { - name: 'ds-create-add-appgw-certificate' - location: location - identity: identity - kind: 'AzurePowerShell' - properties: { - forceUpdateTag: utcValue - azPowerShellVersion: '11.5' - timeout: 'PT30M' - arguments: format(' -vaultName {0} -certificateName {1} -subjectName {2}', keyVaultName, secretName, subjectName) - scriptContent: '\n param(\n [string] [Parameter(Mandatory=$true)] $vaultName,\n [string] [Parameter(Mandatory=$true)] $certificateName,\n [string] [Parameter(Mandatory=$true)] $subjectName\n )\n\n $ErrorActionPreference = \'Stop\'\n $DeploymentScriptOutputs = @{}\n\n $existingCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName\n\n if ($existingCert -and $existingCert.Certificate.Subject -eq $subjectName) {\n\n Write-Host \'Certificate $certificateName in vault $vaultName is already present.\'\n\n $DeploymentScriptOutputs[\'certThumbprint\'] = $existingCert.Thumbprint\n $existingCert | Out-String\n }\n else {\n $policy = New-AzKeyVaultCertificatePolicy -SubjectName $subjectName -IssuerName Self -ValidityInMonths 12 -Verbose\n\n # private key is added as a secret that can be retrieved in the ARM template\n Add-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName -CertificatePolicy $policy -Verbose\n\n $newCert = Get-AzKeyVaultCertificate -VaultName $vaultName -Name $certificateName\n\n # it takes a few seconds for KeyVault to finish\n $tries = 0\n do {\n Write-Host \'Waiting for certificate creation completion...\'\n Start-Sleep -Seconds 10\n $operation = Get-AzKeyVaultCertificateOperation -VaultName $vaultName -Name $certificateName\n $tries++\n\n if ($operation.Status -eq \'failed\')\n {\n throw \'Creating certificate $certificateName in vault $vaultName failed with error $($operation.ErrorMessage)\'\n }\n\n if ($tries -gt 120)\n {\n throw \'Timed out waiting for creation of certificate $certificateName in vault $vaultName\'\n }\n } while ($operation.Status -ne \'completed\')\n\n $DeploymentScriptOutputs[\'certThumbprint\'] = $newCert.Thumbprint\n $newCert | Out-String\n }\n ' - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - } - dependsOn: [ - keyvault - ] -} - -output keyVaultName string = keyVaultName -output secretName string = secretName -output identityId string = const_identityId diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvaultForGateway.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvaultForGateway.bicep deleted file mode 100644 index 67eb68f..0000000 --- a/infra/azure.liberty.aks/modules/_azure-resoruces/_keyvaultForGateway.bicep +++ /dev/null @@ -1,85 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -@secure() -@description('Certificate data to store in the secret') -param certificateDataValue string = newGuid() - -@secure() -@description('Certificate password to store in the secret') -param certificatePasswordValue string = newGuid() - -@description('Property to specify whether Azure Resource Manager is permitted to retrieve secrets from the key vault.') -param enabledForTemplateDeployment bool = true - -param identity object = {} -param location string -param permission object = { - certificates: [ - 'get' - 'list' - 'update' - 'create' - ] -} - -@description('Price tier for Key Vault.') -param sku string = 'Standard' - -@description('Subject name to create a certificate.') -param subjectName string = '' - -@description('If false, will create a certificate.') -param useExistingAppGatewaySSLCertificate bool = false - -@description('Current deployment time. Used as a tag in deployment script.') -param keyVaultName string = 'GEN_UNIQUE' - -var name_sslCertSecretName = 'myAppGatewaySSLCert' -var name_sslCertPasswordSecretName = 'myAppGatewaySSLCertPassword' - -module keyVaultwithSelfSignedAppGatewaySSLCert '_keyvault/_keyvaultWithNewCert.bicep' = if (!useExistingAppGatewaySSLCertificate) { - name: 'kv-appgw-selfsigned-certificate-deployment' - params: { - identity: identity - keyVaultName: keyVaultName - location: location - permission: permission - subjectName: subjectName - sku: sku - } -} - -module keyVaultwithExistingAppGatewaySSLCert '_keyvault/_keyvaultWithExistingCert.bicep' = if (useExistingAppGatewaySSLCertificate) { - name: 'kv-appgw-existing-certificate-deployment' - params: { - certificateDataName: name_sslCertSecretName - certificateDataValue: certificateDataValue - certificatePswSecretName: name_sslCertPasswordSecretName - certificatePasswordValue: certificatePasswordValue - enabledForTemplateDeployment: enabledForTemplateDeployment - keyVaultName: keyVaultName - location: location - sku: sku - } -} - -output keyVaultName string = (useExistingAppGatewaySSLCertificate ? keyVaultwithExistingAppGatewaySSLCert.outputs.keyVaultName : keyVaultwithSelfSignedAppGatewaySSLCert.outputs.keyVaultName) -output sslCertDataSecretName string = (useExistingAppGatewaySSLCertificate ? keyVaultwithExistingAppGatewaySSLCert.outputs.sslCertDataSecretName : keyVaultwithSelfSignedAppGatewaySSLCert.outputs.secretName) -output sslCertPwdSecretName string = (useExistingAppGatewaySSLCertificate ? keyVaultwithExistingAppGatewaySSLCert.outputs.sslCertPwdSecretName: keyVaultwithSelfSignedAppGatewaySSLCert.outputs.secretName) -output sslBackendCertDataSecretName string = '' - diff --git a/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep b/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep deleted file mode 100644 index 630094e..0000000 --- a/infra/azure.liberty.aks/modules/_azure-resoruces/_vnetAppGateway.bicep +++ /dev/null @@ -1,112 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -param location string -param newOrExistingVnetForApplicationGateway string -param vnetForApplicationGateway object = { - name: 'olaks-app-gateway-vnet' - resourceGroup: resourceGroup().name - addressPrefixes: [ - '172.16.0.0/24' - ] - addressPrefix: '172.16.0.0/24' - newOrExisting: 'new' - subnets: { - gatewaySubnet: { - name: 'olaks-gateway-subnet' - addressPrefix: '172.16.0.0/24' - startAddress: '172.16.0.4' - } - } -} -param vnetRGNameForApplicationGateway string -param nameSuffix string = '' -param guidValue string = take(replace(newGuid(), '-', ''), 6) - -var const_nameSuffix = empty(nameSuffix) ? guidValue : nameSuffix -var const_subnetAddressPrefixes = vnetForApplicationGateway.subnets.gatewaySubnet.addressPrefix -var const_vnetAddressPrefixes = vnetForApplicationGateway.addressPrefixes -var const_newVnet = (vnetForApplicationGateway.newOrExisting == 'new') ? true : false -var name_nsg = format('olaks-nsg{0}', const_nameSuffix) -var name_subnet = vnetForApplicationGateway.subnets.gatewaySubnet.name -var name_vnet = vnetForApplicationGateway.name - -// Create new network security group. -resource nsg 'Microsoft.Network/networkSecurityGroups@2023-11-01' = if (const_newVnet) { - name: name_nsg - location: location - properties: { - securityRules: [ - { - properties: { - protocol: 'Tcp' - sourcePortRange: '*' - destinationPortRange: '65200-65535' - sourceAddressPrefix: 'GatewayManager' - destinationAddressPrefix: '*' - access: 'Allow' - priority: 500 - direction: 'Inbound' - } - name: 'ALLOW_APPGW' - } - { - properties: { - protocol: 'Tcp' - sourcePortRange: '*' - sourceAddressPrefix: 'Internet' - destinationAddressPrefix: '*' - access: 'Allow' - priority: 510 - direction: 'Inbound' - destinationPortRanges: [ - '80' - '443' - ] - } - name: 'ALLOW_HTTP_ACCESS' - } - ] - } -} - -// Create new VNET and subnet. -resource newVnet 'Microsoft.Network/virtualNetworks@2023-11-01' = if (const_newVnet) { - name: name_vnet - location: location - properties: { - addressSpace: { - addressPrefixes: const_vnetAddressPrefixes - } - subnets: [ - { - name: name_subnet - properties: { - addressPrefix: const_subnetAddressPrefixes - networkSecurityGroup: { - id: nsg.id - } - } - } - ] - } -} - -// To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the resourceGroup property when hideExisting is false -output vnetResourceGroupName string = vnetRGNameForApplicationGateway -// To mitigate ARM-TTK error: Control Named vnetForApplicationGateway must output the newOrExisting property when hideExisting is false -output newOrExisting string = newOrExistingVnetForApplicationGateway diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-networking.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-networking.bicep deleted file mode 100644 index e004f2e..0000000 --- a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-networking.bicep +++ /dev/null @@ -1,101 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -param _artifactsLocation string = deployment().properties.templateLink.uri -@secure() -param _artifactsLocationSasToken string = '' -param location string - -param identity object = {} - -@allowed([ - 'haveCert' - 'haveKeyVault' - 'generateCert' -]) -@description('Three scenarios we support for deploying app gateway') -param appgwCertificateOption string = 'haveCert' -@secure() -param appgwFrontendSSLCertData string = newGuid() -@secure() -param appgwFrontendSSLCertPsw string = newGuid() - -param appgwName string = 'appgw-contoso' - -param aksClusterRGName string = 'aks-contoso-rg' -param aksClusterName string = 'aks-contoso' -param appFrontendTlsSecretName string = 'tls-secret' -param appProjName string = 'default' - -param utcValue string = utcNow() - -var const_scriptLocation = uri(_artifactsLocation, 'scripts/') - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { - name: 'ds-networking-deployment' - location: location - kind: 'AzureCLI' - identity: identity - properties: { - azCliVersion: '2.15.0' - environmentVariables: [ - { - name: 'AKS_CLUSTER_RG_NAME' - value: aksClusterRGName - } - { - name: 'AKS_CLUSTER_NAME' - value: aksClusterName - } - { - name: 'CURRENT_RG_NAME' - value: resourceGroup().name - } - { - name: 'APP_GW_NAME' - value: appgwName - } - { - name: 'APP_GW_FRONTEND_SSL_CERT_DATA' - value: appgwFrontendSSLCertData - } - { - name: 'APP_GW_FRONTEND_SSL_CERT_PSW' - secureValue: appgwFrontendSSLCertPsw - } - { - name: 'APP_GW_CERTIFICATE_OPTION' - value: appgwCertificateOption - } - { - name: 'APP_FRONTEND_TLS_SECRET_NAME' - value: appFrontendTlsSecretName - } - { - name: 'APP_PROJ_NAME' - value: appProjName - } - ] - primaryScriptUri: uri(const_scriptLocation, 'createAppGatewayIngress.sh${_artifactsLocationSasToken}') - supportingScriptUris: [ - uri(const_scriptLocation, 'utility.sh${_artifactsLocationSasToken}') - ] - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - forceUpdateTag: utcValue - } -} diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-preflight.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-preflight.bicep deleted file mode 100644 index 0b813db..0000000 --- a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-preflight.bicep +++ /dev/null @@ -1,130 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -param _artifactsLocation string = deployment().properties.templateLink.uri -@secure() -param _artifactsLocationSasToken string = '' -param location string -param name string = '' -param identity object = {} -param createCluster bool = true -param aksClusterName string = '' -param aksClusterRGName string = '' -param enableAppGWIngress bool = false -param vnetForApplicationGateway object = {} -param appGatewayCertificateOption string = '' -param keyVaultName string = '' -param keyVaultResourceGroup string = '' -param keyVaultSSLCertDataSecretName string = '' -param keyVaultSSLCertPasswordSecretName string = '' -@secure() -param appGatewaySSLCertData string = '' -@secure() -param appGatewaySSLCertPassword string = '' -param vmSize string -param deployApplication bool -param sourceImagePath string - -param utcValue string = utcNow() - -var const_scriptLocation = uri(_artifactsLocation, 'scripts/') - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { - name: name - location: location - kind: 'AzureCLI' - identity: identity - properties: { - azCliVersion: '2.53.0' - environmentVariables: [ - { - name: 'CREATE_CLUSTER' - value: string(createCluster) - } - { - name: 'AKS_CLUSTER_NAME' - value: aksClusterName - } - { - name: 'AKS_CLUSTER_RG_NAME' - value: aksClusterRGName - } - { - name: 'ENABLE_APPLICATION_GATEWAY_INGRESS_CONTROLLER' - value: string(enableAppGWIngress) - } - { - name: 'VNET_FOR_APPLICATIONGATEWAY' - value: string(vnetForApplicationGateway) - } - { - name: 'APPLICATION_GATEWAY_CERTIFICATE_OPTION' - value: appGatewayCertificateOption - } - { - name: 'APPLICATION_GATEWAY_SSL_KEYVAULT_NAME' - value: keyVaultName - } - { - name: 'APPLICATION_GATEWAY_SSL_KEYVAULT_RESOURCEGROUP' - value: keyVaultResourceGroup - } - { - name: 'APPLICATION_GATEWAY_SSL_KEYVAULT_FRONTEND_CERT_DATA_SECRET_NAME' - value: keyVaultSSLCertDataSecretName - } - { - name: 'APPLICATION_GATEWAY_SSL_KEYVAULT_FRONTEND_CERT_PASSWORD_SECRET_NAME' - value: keyVaultSSLCertPasswordSecretName - } - { - name: 'APPLICATION_GATEWAY_SSL_FRONTEND_CERT_DATA' - secureValue: appGatewaySSLCertData - } - { - name: 'APPLICATION_GATEWAY_SSL_FRONTEND_CERT_PASSWORD' - secureValue: appGatewaySSLCertPassword - } - { - name: 'LOCATION' - value: location - } - { - name: 'VM_SIZE' - value: vmSize - } - { - name: 'DEPLOY_APPLICATION' - value: string(deployApplication) - } - { - name: 'SOURCE_IMAGE_PATH' - value: sourceImagePath - } - ] - primaryScriptUri: uri(const_scriptLocation, 'preflight.sh${_artifactsLocationSasToken}') - supportingScriptUris: [ - uri(const_scriptLocation, 'utility.sh${_artifactsLocationSasToken}') - ] - - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - forceUpdateTag: utcValue - } -} - -output aksAgentAvailabilityZones array = json(deploymentScript.properties.outputs.agentAvailabilityZones) diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-primary.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-primary.bicep deleted file mode 100644 index 1d754ab..0000000 --- a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds-primary.bicep +++ /dev/null @@ -1,129 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -param _artifactsLocation string = deployment().properties.templateLink.uri -@secure() -param _artifactsLocationSasToken string = '' -param location string -param name string = '' -param identity object = {} -param arguments string = '' -param acrRGName string = '' -param deployWLO bool = false -param edition string = 'IBM WebSphere Application Server' -param productEntitlementSource string = 'Standalone' -param metric string = 'Processor Value Unit (PVU)' -param deployApplication bool = false -param enableAppGWIngress bool = false -param appFrontendTlsSecretName string ='' -param enableCookieBasedAffinity bool = false -param appgwUsePrivateIP bool = false -param autoScaling bool = false -param cpuUtilizationPercentage int = 80 -param minReplicas int = 1 -param maxReplicas int = 100 -param requestCPUMillicore int = 300 - -param utcValue string = utcNow() - -var const_scriptLocation = uri(_artifactsLocation, 'scripts/') - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { - name: name - location: location - kind: 'AzureCLI' - identity: identity - properties: { - azCliVersion: '2.15.0' - environmentVariables: [ - { - name: 'ACR_RG_NAME' - value: string(acrRGName) - } - { - name: 'ENABLE_APP_GW_INGRESS' - value: string(enableAppGWIngress) - } - { - name: 'APP_FRONTEND_TLS_SECRET_NAME' - value: string(appFrontendTlsSecretName) - } - { - name: 'ENABLE_COOKIE_BASED_AFFINITY' - value: string(enableCookieBasedAffinity) - } - { - name: 'APP_GW_USE_PRIVATE_IP' - value: string(appgwUsePrivateIP) - } - { - name: 'DEPLOY_WLO' - value: string(deployWLO) - } - { - name: 'WLA_EDITION' - value: string(edition) - } - { - name: 'WLA_PRODUCT_ENTITLEMENT_SOURCE' - value: string(productEntitlementSource) - } - { - name: 'WLA_METRIC' - value: string(metric) - } - { - name: 'AUTO_SCALING' - value: string(autoScaling) - } - { - name: 'CPU_UTILIZATION_PERCENTAGE' - value: string(cpuUtilizationPercentage) - } - { - name: 'MIN_REPLICAS' - value: string(minReplicas) - } - { - name: 'MAX_REPLICAS' - value: string(maxReplicas) - } - { - name: 'REQUEST_CPU_MILLICORE' - value: string(requestCPUMillicore) - } - ] - arguments: arguments - primaryScriptUri: uri(const_scriptLocation, 'install.sh${_artifactsLocationSasToken}') - supportingScriptUris: [ - uri(const_scriptLocation, 'open-liberty-application.yaml.template${_artifactsLocationSasToken}') - uri(const_scriptLocation, 'open-liberty-application-agic.yaml.template${_artifactsLocationSasToken}') - uri(const_scriptLocation, 'websphere-liberty-application.yaml.template${_artifactsLocationSasToken}') - uri(const_scriptLocation, 'websphere-liberty-application-agic.yaml.template${_artifactsLocationSasToken}') - uri(const_scriptLocation, 'open-liberty-application-autoscaling.yaml.template${_artifactsLocationSasToken}') - uri(const_scriptLocation, 'open-liberty-application-agic-autoscaling.yaml.template${_artifactsLocationSasToken}') - uri(const_scriptLocation, 'websphere-liberty-application-autoscaling.yaml.template${_artifactsLocationSasToken}') - uri(const_scriptLocation, 'websphere-liberty-application-agic-autoscaling.yaml.template${_artifactsLocationSasToken}') - ] - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - forceUpdateTag: utcValue - } -} - -output appEndpoint string = (deployApplication && !enableAppGWIngress) ? deploymentScript.properties.outputs.appEndpoint : '' -output appDeploymentYaml string = deploymentScript.properties.outputs.appDeploymentYaml diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_enable_agic.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_enable_agic.bicep deleted file mode 100644 index e7cf2bc..0000000 --- a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_enable_agic.bicep +++ /dev/null @@ -1,63 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -param _artifactsLocation string = deployment().properties.templateLink.uri -@secure() -param _artifactsLocationSasToken string = '' -param aksClusterName string = '' -param aksClusterRGName string = '' -param appgwName string = 'appgw-contoso' -param identity object = {} -param location string -param utcValue string = utcNow() - -var const_scriptLocation = uri(_artifactsLocation, 'scripts/') - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { - name: 'ds-enable-agic' - location: location - kind: 'AzureCLI' - identity: identity - properties: { - azCliVersion: '2.33.1' - primaryScriptUri: uri(const_scriptLocation, 'enableAgic.sh${_artifactsLocationSasToken}') - supportingScriptUris: [ - uri(const_scriptLocation, 'utility.sh${_artifactsLocationSasToken}') - ] - environmentVariables: [ - { - name: 'AKS_CLUSTER_RG_NAME' - value: aksClusterRGName - } - { - name: 'AKS_CLUSTER_NAME' - value: aksClusterName - } - { - name: 'APP_GW_NAME' - value: appgwName - } - { - name: 'CURRENT_RG_NAME' - value: resourceGroup().name - } - ] - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - forceUpdateTag: utcValue - } -} diff --git a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep b/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep deleted file mode 100644 index 6cf38e7..0000000 --- a/infra/azure.liberty.aks/modules/_deployment-scripts/_ds_query_available_private_ip_from_subnet.bicep +++ /dev/null @@ -1,60 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -param _artifactsLocation string = deployment().properties.templateLink.uri -@secure() -param _artifactsLocationSasToken string = '' - -param subnetId string = '/subscriptions/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/resourceGroups/resourcegroupname/providers/Microsoft.Network/virtualNetworks/vnetname/subnets/subnetname' -param knownIP string = '10.0.0.1' - -param identity object = {} -param location string -param utcValue string = utcNow() - -var const_azcliVersion='2.15.0' -var const_deploymentName='ds-query-private-ip' -var const_scriptLocation = uri(_artifactsLocation, 'scripts/') - -resource deploymentScript 'Microsoft.Resources/deploymentScripts@2023-08-01' = { - name: const_deploymentName - location: location - kind: 'AzureCLI' - identity: identity - properties: { - azCliVersion: const_azcliVersion - environmentVariables: [ - { - name: 'SUBNET_ID' - value: subnetId - } - { - name: 'KNOWN_IP' - value: knownIP - } - ] - primaryScriptUri: uri(const_scriptLocation, 'queryPrivateIPForAppGateway.sh${_artifactsLocationSasToken}') - supportingScriptUris: [ - uri(const_scriptLocation, 'utility.sh${_artifactsLocationSasToken}') - ] - cleanupPreference: 'OnSuccess' - retentionInterval: 'P1D' - forceUpdateTag: utcValue - } -} - -output privateIP string = string(reference(const_deploymentName).outputs.privateIP) diff --git a/infra/azure.liberty.aks/modules/_pids/_empty.bicep b/infra/azure.liberty.aks/modules/_pids/_empty.bicep deleted file mode 100644 index d844be7..0000000 --- a/infra/azure.liberty.aks/modules/_pids/_empty.bicep +++ /dev/null @@ -1,21 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -// Workaround to arm-ttk complain: Parameters property must exist in the template -param name string = 'This is an empty deployment' - -output name string = name diff --git a/infra/azure.liberty.aks/modules/_rolesAssignment/_acrPullRoleAssignment.bicep b/infra/azure.liberty.aks/modules/_rolesAssignment/_acrPullRoleAssignment.bicep deleted file mode 100644 index 81c07ff..0000000 --- a/infra/azure.liberty.aks/modules/_rolesAssignment/_acrPullRoleAssignment.bicep +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -param aksClusterName string = '' -param aksClusterRGName string = '' -param acrName string = '' -param acrRGName string = '' - -var const_APIVersion = '2020-12-01' -// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles -var const_roleDefinitionIdOfAcrPull = '7f951dda-4ed3-4680-a7ca-43fe172d538d' - -resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-08-01' existing = { - name: aksClusterName - scope: resourceGroup(aksClusterRGName) -} - -resource acr 'Microsoft.ContainerRegistry/registries@2023-07-01' existing = { - name: acrName - scope: resourceGroup(acrRGName) -} - -// https://github.com/Azure/azure-quickstart-templates/issues/4205 -resource acrPullRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: guid('${aksCluster.id}${acr.id}ForKubeletIdentity') - properties: { - description: 'Assign Resource Group Contributor role to User Assigned Managed Identity ' - principalId: reference(aksCluster.id, const_APIVersion , 'Full').properties.identityProfile.kubeletidentity.objectId - principalType: 'ServicePrincipal' - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', const_roleDefinitionIdOfAcrPull) - } - dependsOn: [ - aksCluster - acr - ] -} - -output aksClusterId string = aksCluster.id -output acrId string = acr.id diff --git a/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep b/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep deleted file mode 100644 index b21184e..0000000 --- a/infra/azure.liberty.aks/modules/_rolesAssignment/_agicRoleAssignment.bicep +++ /dev/null @@ -1,43 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -param aksClusterName string = '' -param aksClusterRGName string = '' -param utcValue string = utcNow() - -var const_APIVersion = '2020-12-01' -var name_appGwContributorRoleAssignmentName = guid('${resourceGroup().id}${utcValue}ForApplicationGateway') -// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles -var const_roleDefinitionIdOfContributor = 'b24988ac-6180-42a0-ab88-20f7382dd24c' - -resource aksCluster 'Microsoft.ContainerService/managedClusters@2023-08-01' existing = { - name: aksClusterName - scope: resourceGroup(aksClusterRGName) -} - -resource agicUamiRoleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: name_appGwContributorRoleAssignmentName - properties: { - description: 'Assign Resource Group Contributor role to User Assigned Managed Identity ' - principalId: reference(aksCluster.id, const_APIVersion , 'Full').properties.addonProfiles.ingressApplicationGateway.identity.objectId - principalType: 'ServicePrincipal' - roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', const_roleDefinitionIdOfContributor) - } - dependsOn: [ - aksCluster - ] -} diff --git a/infra/azure.liberty.aks/modules/_rolesAssignment/_roleAssignmentinSubscription.bicep b/infra/azure.liberty.aks/modules/_rolesAssignment/_roleAssignmentinSubscription.bicep deleted file mode 100644 index 4832c98..0000000 --- a/infra/azure.liberty.aks/modules/_rolesAssignment/_roleAssignmentinSubscription.bicep +++ /dev/null @@ -1,53 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -/* -Description: assign roles cross resource group. -Usage: - module roleAssignment '_roleAssignmentinSubscription.bicep' = { - name: 'assign-role' - scope: subscription() - params: { - roleDefinitionId: roleDefinitionId - principalId: principalId - } - } -*/ - -targetScope = 'subscription' - -// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles -param roleDefinitionId string = '' -param principalId string = '' - -var name_roleAssignmentName = guid('${subscription().id}${principalId}Role assignment in subscription scope') - -// Get role resource id in subscription -resource roleResourceDefinition 'Microsoft.Authorization/roleDefinitions@2022-04-01' existing = { - name: roleDefinitionId -} - -// Assign role -resource roleAssignment 'Microsoft.Authorization/roleAssignments@2022-04-01' = { - name: name_roleAssignmentName - properties: { - description: 'Assign subscription scope role to User Assigned Managed Identity ' - principalId: principalId - principalType: 'ServicePrincipal' - roleDefinitionId: roleResourceDefinition.id - } -} diff --git a/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep b/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep deleted file mode 100644 index 99bed69..0000000 --- a/infra/azure.liberty.aks/modules/_uamiAndRoles.bicep +++ /dev/null @@ -1,42 +0,0 @@ -/* - Copyright (c) Microsoft Corporation. - Copyright (c) IBM Corporation. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -param location string -param name_deploymentScriptContributorRoleAssignmentName string = newGuid() - -// https://docs.microsoft.com/en-us/azure/role-based-access-control/built-in-roles -var const_roleDefinitionIdOfContributor = 'b24988ac-6180-42a0-ab88-20f7382dd24c' -var name_deploymentScriptUserDefinedManagedIdentity = 'ol-aks-deployment-script-user-defined-managed-itentity-${substring(uniqueString(name_deploymentScriptContributorRoleAssignmentName),0,5)}' - - -// UAMI for deployment script -resource uamiForDeploymentScript 'Microsoft.ManagedIdentity/userAssignedIdentities@2023-01-31' = { - name: name_deploymentScriptUserDefinedManagedIdentity - location: location -} - -// Assign Contributor role in subscription scope, we need the permission to get/update resource cross resource groups. -module deploymentScriptUAMICotibutorRoleAssignment '_rolesAssignment/_roleAssignmentinSubscription.bicep' = { - name: name_deploymentScriptContributorRoleAssignmentName - scope: subscription() - params: { - roleDefinitionId: const_roleDefinitionIdOfContributor - principalId: reference(resourceId('Microsoft.ManagedIdentity/userAssignedIdentities', name_deploymentScriptUserDefinedManagedIdentity)).principalId - } -} - -output uamiIdForDeploymentScript string = uamiForDeploymentScript.id diff --git a/infra/azure.liberty.aks/parameters.json b/infra/azure.liberty.aks/parameters_json.template similarity index 80% rename from infra/azure.liberty.aks/parameters.json rename to infra/azure.liberty.aks/parameters_json.template index ffb7d84..b3f6fa4 100644 --- a/infra/azure.liberty.aks/parameters.json +++ b/infra/azure.liberty.aks/parameters_json.template @@ -3,7 +3,7 @@ "contentVersion": "1.0.0.0", "parameters": { "_artifactsLocation": { - "value": "https://raw.githubusercontent.com/WASdev/azure.liberty.aks/048e776e9efe2ffed8368812e198c1007ba94b2c/src/main/" + "value": "https://raw.githubusercontent.com/WASdev/azure.liberty.aks/${LIBERTY_AKS_REPO_REF}/src/main/" }, "createCluster": { "value": true @@ -33,4 +33,4 @@ "value": true } } -} \ No newline at end of file +}