diff --git a/AWS-EKS-CLI/README.md b/AWS-EKS-CLI/README.md index efbcf6f5..98a26ee1 100644 --- a/AWS-EKS-CLI/README.md +++ b/AWS-EKS-CLI/README.md @@ -1,19 +1,19 @@ # Deploy Profisee platform on to AWS Elastic Kubernetes services (EKS) -This explains the process to deploy the Profisee platform onto a new AWS EKS cluster +The process below explains how to deploy the Profisee platform onto a new AWS EKS cluster. Profisee requires a Windows and a Linux node. Linux nodes are managed nodes ## Prerequisites -1. License - - Profisee license associated with the dns for the environment +1. The following will be provided by Profisee: + - Please decide on what DNS (FQDN) you will use to access Profisee at and we will generate a license for it. - ACR username, password and token -2. Https certificate and the private key +2. TLS certificate and the private key. -3. Choose your AWS region you want to use eg us-east-1 +3. Pick your AWS region, our sample script uses us-east-1. 4. SQL Server - - AWS RDS instance - https://aws.amazon.com/getting-started/hands-on/create-microsoft-sql-db/ + - An appropriately sized AWS RDS instance - https://aws.amazon.com/getting-started/hands-on/create-microsoft-sql-db/ - Goto https://console.aws.amazon.com/rds - Click create database @@ -30,9 +30,9 @@ This explains the process to deploy the Profisee platform onto a new AWS EKS clu - Public access yes (simpler to debug) - Change to fit your security needs when ready - Defaults for the rest of the options - Wait for database to be available - - CLI sample: aws rds create-db-instance --engine sqlserver-ex --db-instance-class db.t3.small --db-instance-identifier profiseedemo --master-username sqladmin --master-user-password Password123 --allocated-storage 20 + - CLI sample: aws rds create-db-instance --engine sqlserver-ex --db-instance-class db.t3.small --db-instance-identifier --master-username --master-user-password --allocated-storage 50 -5. Create EBS volume - must be created in the same region/zone as the eks cluster +5. You will need a storage account so please create an EBS volume. It must be created in the same region/zone as the EKS cluster - EBS volume - https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ebs-creating-volume.html - https://console.aws.amazon.com/ec2 @@ -54,88 +54,88 @@ This explains the process to deploy the Profisee platform onto a new AWS EKS clu - Setup IAM - https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-quickstart.html#cli-configure-quickstart-creds 7. Configure DNS - - Choose a DNS host name that you want to use eg: profiseemdm.mycompany.com - - Register that hostname in your DNS provider with a CNAME that points to xxxxxx.elb..amazonaws.com (this will be updated later. + - Choose a fully qualified domain name that you would like to use, ex. https://profiseemdm.mycompany.com + - Create a CNAME record for the profiseemdm hostname with your domain DNS provider and map it to point to xxxxxx.elb..amazonaws.com (this will be updated later). ## Deployment -1. Make cluster.yaml and upload to cloudshell. +1. Edit the provided cluster.yaml to match your requirement and upload it to cloudshell. - Download the cluster.yaml - curl -fsSL -o cluster.yaml https://raw.githubusercontent.com/profiseedev/kubernetes/master/AWS-EKS-CLI/cluster.yaml; + curl -fsSL -o cluster.yaml https://raw.githubusercontent.com/profiseeadmin/kubernetes/master/AWS-EKS-CLI/cluster.yaml; - - Change the name, region and availabilityzones + - Change the name, region and availability zones - Change the instance type(s) to fit your needs. https://aws.amazon.com/ec2/pricing/on-demand/ - - For more complex deployments, including networking vpc and subnet configurations see https://eksctl.io/usage/schema/ + - For more complex deployments, including networking VPC and subnet configurations see https://eksctl.io/usage/schema/ -2. Create the EKS Clusterr +2. Using CLI, create the EKS Cluster. eksctl create cluster -f cluster.yaml --install-vpc-controllers --timeout 30m -3. Configure kubectl +3. Using CLI, configure kubectl to connect to the newly created cluster. - aws eks --region us-east-1 update-kubeconfig --name MyCluster + aws eks --region us-east-1 update-kubeconfig --name -4. Update the sql security group to allow the kubernetes nodes ips in - - Get the outbound IP's of the cluster. +4. Configure your SQL security group to permit inbound traffic from the cluster's subnet (you can further lock it down to just the kubernetes Windows node IPs. Note: As AWS implements a rolling deprecation of old Windows Server AMIs you will need to implement a maintenance window to update the underlying AMI in the Windows Nodegroup, so please make sure to update your SQL security group with those updated node IPs. + - Get the outbound IPs of the cluster. kubectl get nodes -o jsonpath='{.items[*].status.addresses[?(@.type == "ExternalIP")].address}' - - Click on sql instance + - Click on SQL instance - Click on VPC security group - Inbound rules - Edit inbound rules - - Add MSSQL for outbound IP's of cluster + - Add MSSQL for outbound IPs of cluster 5. Install nginx for AWS helm repo add stable https://charts.helm.sh/stable; curl -o nginxSettingsAWS.yaml https://raw.githubusercontent.com/Profisee/kubernetes/master/AWS-EKS-CLI/nginxSettingsAWS.yaml; kubectl create namespace profisee - helm install nginx stable/nginx-ingress --values nginxSettingsAWS.yaml --namespace profisee + helm install nginx stable/nginx-ingress --values nginxSettingsAWS.yaml -n profisee - - Wait for the load balancer to be provisioned. goto aws ec2/load balancing console and wait for the state to go from provisioning to active (3ish minutes) + - Wait for the load balancer to be provisioned. Go to AWS EC2 load balancing console and wait for the state to go from provisioning to active (approximately 3 minutes). 6. Get nginx IP - kubectl get services nginx-nginx-ingress-controller --namespace profisee + kubectl get services nginx-nginx-ingress-controller -n profisee #Note the external-ip and update the DNS hostname you created earlier and have it point to it (xxxxxx.elb..amazonaws.com) 7. (Optional) - Install cert-manager for Let's Encrypt - helm install --namespace profisee cert-manager jetstack/cert-manager --namespace default --version v0.16.1 --set installCRDs=true --set nodeSelector."beta\.kubernetes\.io/os"=linux --set webhook.nodeSelector."beta\.kubernetes\.io/os"=linux --set cainjector.nodeSelector."beta\.kubernetes\.io/os"=linux + helm install -n profisee cert-manager jetstack/cert-manager --set installCRDs=true --set nodeSelector."beta\.kubernetes\.io/os"=linux --set webhook.nodeSelector."beta\.kubernetes\.io/os"=linux --set cainjector.nodeSelector."beta\.kubernetes\.io/os"=linux - update Settings.yaml useLetsEncrypt flag to true + Set the Settings.yaml useLetsEncrypt flag to true. 8. Configue Authentication provider - - Create/configure an auth provider in your auth providr of choice. eg Azure Active Directory, OKTA - - Register redirect url http(s)://profiseemdm.mycompany.com/Profisee/auth/signin-microsoft + - Create/configure an auth provider in your auth provider of choice. eg Azure Active Directory, OKTA + - Register redirect url http(s)://profiseemdm.mycompany.com/Profisee/auth/signin-microsoft (or .../auth/signing-okta). Make sure that your URL in the the application registration matches. The /signin-microsoft part from the URL can be anything you like so long as the application registration redirect URL and the value in the Settings.yaml template match. - Note the clientid, secret and authority url. The authority url for AAD is https://login.microsoftonline.com/{tenantid} 9. Create Profisee Settings.yaml - Fetch the Settings.yaml template, download the yaml file so you can edit it locally - curl -fsSL -o Settings.yaml https://raw.githubusercontent.com/profiseedev/kubernetes/master/AWS-EKS-CLI/Settings.yaml; + curl -fsSL -o Settings.yaml https://raw.githubusercontent.com/profiseeadmin/kubernetes/master/AWS-EKS-CLI/Settings.yaml; - Update the values - Upload to cloudshell 10. Install Profisee - helm repo add profisee https://profiseedev.github.io/kubernetes - helm uninstall --namespace profisee profiseeplatform - helm install --namespace profisee profiseeplatform profisee/profisee-platform --values Settings.yaml + helm repo add profisee https://profiseeadmin.github.io/kubernetes + helm uninstall -n profisee profiseeplatform + helm install -n profisee profiseeplatform profisee/profisee-platform --values Settings.yaml # Verify and finalize: -1. The initial deploy will have to download the container which takes about 10 minutes. Verify its finished downloading the container: +1. The initial deployment will have to download the container which takes about 10 minutes. Verify it's finished downloading the container: #check status and wait for "Pulling" to finish - kubectl --namespace profisee describe pod profisee-0 + kubectl -n profisee describe pod profisee-0 -2. View the kubernetes logs and wait for it to finish successfully starting up. takes longer on the first time as it has to create all the objects in teh database +2. View the kubernetes logs and wait for it to finish successfully starting up. It takes longer on the first time as it has to create all the objects in the database. - kubectl logs profisee-0 --namespace profisee --follow + kubectl logs profisee-0 -n profisee --follow 3. Voila, goto Profisee Platform web portal - http(s)://FQDNThatPointsToClusterIP/Profisee diff --git a/Azure-ARM/README.md b/Azure-ARM/README.md index fdb7682c..ac8702df 100644 --- a/Azure-ARM/README.md +++ b/Azure-ARM/README.md @@ -1,21 +1,69 @@ # DEVELOPMENT. INTERNAL USE ONLY -# Deploy Profisee platform on to AKS using ARM template +# Deploying Profisee Platform on AKS using the ARM template -This ARM template deploys Profisee platform into a Azure Kubernetes Service cluster. - -[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fprofiseedev%2Fkubernetes%2Fmaster%2FAzure-ARM%2Fazuredeploy.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2Fprofiseedev%2Fkubernetes%2Fmaster%2FAzure-ARM%2FcreateUIDefinition.json) ## Prerequisites -1. Managed Identity - - A user assigned managed identity configured ahead of time. The managed identity must have Contributor role for the resource group, and the DNS zone resource group if updating Azure DNS. This can be done by assigning the contributor role to each individual resource group, or assigning the subscription level resource group. If creating an Azure Active Directory application registration, the managed identity must have the Application Developer role assigned to it. Click [here](https://support.profisee.com/wikis/2020_r2_support/planning_your_managed_identity_configuration) for more information. -2. License - - Profisee license associated with the dns for the environment. +Please **DO** review the guide and links below **before** you run the Azure ARM template. We have a pre-requisites script that runs before the deployment to check on the permissions needed. + +Click [here](https://support.profisee.com/wikis/2022_r2_support/deploying_the_AKS_cluster_with_the_arm_template) for a detailed deployment guide for Profisee ver. 2022R2 and [here](https://support.profisee.com/lms/courseinfo?id=00u00000000002b00aM&mode=browsecourses) for video training course and slide deck. + + +Here's **what** you will need. You will need a license tied to the DNS URL that will be used by the environment (ex. customer.eastus2.cloudapp.azure.com OR YourOwnEnvironment.Customer.com) This license can be acquired from [Profisee Support](https://support.profisee.com/aspx/ProfiseeCustomerHome). + +Here's **what** will be deployed, or used if available, by the ARM template: +1. An AKS Cluster with a **publicly** accessible Management API. +2. Two Public IPs for Ingress and Egress. +3. A Load Balancer needed for Nginx. +4. A SQL Server, or we'll use one that you already have. You can either pre-create the database or let the Managed Identity create one for you. +5. A Storage account, or use one that you already have. If you precreate the storage account, please make sure to precreate the files share that you'd like to use. +6. A DNS entry into a zone, assuming the necessary permissions are there. If you use external DNS, you'd have to update/create the record to match the Egress IP. +7. A free Let's Encrypt certificate, if you choose that option. Please be aware that if you plan on using your own domain with Let's Encrypt you'll need to make sure that if there is a [CAA record set](https://letsencrypt.org/docs/caa/) on your domain it allows Let's Encrypt as the Issuing Authority. + +Here's **how** it will be deployed. You must have a Managed Identity created to run the deployment. This Managed Identity must have the following permissions ONLY when running a deployment. After it is done, the Managed Identity can be deleted. Based on your ARM template choices, you will need some or all of the following permissions assigned to your Managed Identity: +1. **Contributor** role to the Resource Group where AKS will be deployed. This can either be assigned directly to the Resource Group OR at Subscription level. **Note:** If you want to allow the Deployment Managed Identity to create the resource group for you, then this permission would have to be at Subscription level. +2. **DNS Zone Contributor** role to the particular DNS zone where the entry will be created OR **Contributor** role to the DNS Zone Resource Group.This is needed only if updating DNS hosted in Azure. To follow best practice for least access, the DNS Zone Contributor on the zone itself is the recommended option. +3. **Application Administrator** role in Azure Active Directory, so the Application registration can be created by the Deployment Managed Identity and the required permissions can be assigned to it. +4. **Managed Identity Contributor** and **User Access Administrator** at the Subscription level. These two are needed in order for the ARM template Deployment Managed Identity to be able to create the Key Vault specific Managed Identity that will be used by Profisee to pull the values stored in the Key Vault, as well as to assign the AKSCluster-agentpool the Managed Identity Operator role (to the Resource and Infrastructure Resource groups) and Virtual Machine Operator role (to the Infrastructure Resource group). If Key Vault will not be used, these roles are not required. +5. **Key Vault requirements**. If you are using a Key Vault, please make sure that your Access Policy page has a checkmark on "Azure Resource Manager for template deployment". Otherwise, MS will not be able to validate the ARM template's access against your Key Vault and will result in validation failure in the ARM template before it begins deployment. +6. **Purview Integration requirements**. If Profisee will be configured to integrate with Microsoft Purview, a Purview specific Application Registration will need to be created and have the **Collections Admin** and **Data Curator Role** assigned in the Purview account at either collection or account level. It will also have to be assigned the User.Read **delegated** permission as well as the User.Read.All, Group.Read.All and GroupMember.Read.All **application** permissions (these 3 required Global Admin consent). During the ARM template deployment you will now have to provide the Purview collection friendly name, as seen in the Purview web portal, regardless if this is a sub-collection or the root collection of Purview. + + +## Upgrade instructions + +For customers upgrading **from** v2022**R1** and earlier. There are two changes that require careful consideration: +1. Purview Collections integration necessitated changes in the ARM template, container and deployment templates. Please **DO** review the upgrade instructions posted below **before** you start the upgrade process. +2. History tables improvements - you will need to run this immediately **after** the upgrade to 2022**R2**, one time **only**. + +Please read through the upgrade instructions both here and in our Support portal and prepare for the upgrade process. The instructions below are combined for both Purview Collections and the History table improvements. + +For customers who do **NOT** use Purview. +1. Connect to your cluster from the Azure portal or powershell. For customers running Private PaaS please connect to your jumpbox first, then connect via powershell or Lens. +2. Run the following commands (if you do not have the repo added that would be the first step): +helm -n profisee repo add profisee https://profiseedev.github.io/kubernetes +helm repo update +helm upgrade -n profisee profiseeplatform profisee/profisee-platform --reuse-values --set image.tag=2022r2.0 +kubectl logs -n profisee profisee-0 -f #this will allow you to follow the upgrade as it is happening +3. This will upgrade your installation to version 2022r2.0 while keeping the rest of the values. +4. To run the Histroy tables upgrade please follow the steps as outlined [here](https://support.profisee.com/wikis/release_notes/upgrade_considerations_and_prerequisites) +For customers who **DO** use Purview. +1. Connect to your cluster from the Azure portal or powershell. For customers running Private PaaS please connect to your jumpbox first, then connect via powershell or Lens. +2. Locate your Purview collection Id by visiting your MS Purview Governance Portal. Go to the collection where you would like Profisee to deploy to. Your URL will look like so: web.purview.azure.com/resource/**YourPurviewAccountName**/main/datasource/collections?collection=**ThisIsTheCollectionId**&feature.tenant=**YourAzureTenantId** +3. Run the following commands (if you do not have the repo added that would be the first step): +helm -n profisee repo add profisee https://profiseedev.github.io/kubernetes +helm repo update +helm upgrade -n profisee profiseeplatform profisee/profisee-platform --reuse-values --set cloud.azure.purview.collectionId=YourCollectionId --set image.tag=2022r2.0 +kubectl logs -n profisee profisee-0 -f #this will allow you to follow the upgrade as it is happening +4. This will upgrade your installation to version 2022r2.0 and provide the required collection Id while keeping the rest of the values. Failure to provide the collection Id would result in a failed upgrade. +5. To run the Histroy tables upgrade please follow the steps as outlined [here](https://support.profisee.com/wikis/release_notes/upgrade_considerations_and_prerequisites) + + ## Deployment steps -Click the "Deploy to Azure" button at the beginning of this document. +[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fprofiseeadmin%2Fkubernetes%2Fmaster%2FAzure-ARM%2Fazuredeploy.json/createUIDefinitionUri/https%3A%2F%2Fraw.githubusercontent.com%2Fprofiseeadmin%2Fkubernetes%2Fmaster%2FAzure-ARM%2FcreateUIDefinition.json) ## Troubleshooting -All troubleshooting is in the [Wiki](https://github.com/profiseedev/kubernetes/wiki) +All troubleshooting is in the [Wiki](https://github.com/profisee/kubernetes/wiki) + diff --git a/Azure-ARM/Settings.yaml b/Azure-ARM/Settings.yaml index 4f5aa9ab..9631a217 100644 --- a/Azure-ARM/Settings.yaml +++ b/Azure-ARM/Settings.yaml @@ -28,6 +28,7 @@ profiseeRunTime: firstNameClaim: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" lastNameClaim: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" emailClaim: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" + groupsClaim: "groups" clusterNodeCount: 1 clusterNode: limits: @@ -66,7 +67,7 @@ cloud: isProvider: true useKeyVault: $USEKEYVAULT keyVault: - identity: #must be created in the aks node resource group and have reader ploicy's on keyvault + identity: #must be created in the AKS node resource group and have Get policies for key vault or Key Vault Secrets User for an RBAC key vault. clientId: "$KEYVAULTIDENTITCLIENTID" resourceId: $KEYVAULTIDENTITYRESOURCEID secrets: @@ -78,18 +79,19 @@ cloud: resourceGroup: "$KEYVAULTRESOURCEGROUP" subscriptionId: "$AZURESUBSCRIPTIONID" tenantId: "$AZURETENANTID" - clusterClientId: "$KUBERNETESCLIENTID" #clientid of the aks cluster; Roles must be assigned ot it; role to main RG: "Managed Identity Operator"; roles to node RG: "Managed Identity Operator", "Virtual Machine Contributor" + clusterClientId: "$KUBERNETESCLIENTID" #clientId of the AKSCluster-agentpool identity; The "Managed Identity Operator" role must be assigned to the RG and Node RG; "Virtual Machine Contributor" role must be assigned to the Node RG. useManagedIdentity: false managedIdentity: name: "" clientId: "" resourceId: "" purview: + tenantId: "$PURVIEWTENANTID" + url: "$PURVIEWURL" + collectionId: "$PURVIEWCOLLECTIONID" clientId: "$PURVIEWCLIENTID" clientSecret: "$PURVIEWCLIENTSECRET" - tenantId: "$PURVIEWTENANTID" - url: "$PURVIEWURL" aws: isProvider: false google: - isProvider: false \ No newline at end of file + isProvider: false diff --git a/Azure-ARM/azuredeploy.json b/Azure-ARM/azuredeploy.json index 2cf3ff29..3775d56c 100644 --- a/Azure-ARM/azuredeploy.json +++ b/Azure-ARM/azuredeploy.json @@ -29,6 +29,10 @@ "defaultValue": "", "type": "String" }, + "PurviewCollectionFriendlyName": { + "defaultValue": "", + "type": "String" + }, "PurviewClientId": { "defaultValue": "", "type": "String" @@ -91,6 +95,9 @@ "defaultValue": "", "type": "string" }, + "AuthenticationType":{ + "type": "string" + }, "SQLServerCreateNew": { "type": "String" }, @@ -163,10 +170,10 @@ "type": "String" } }, - "variables": + "variables": { - "ScriptURL":"https://raw.githubusercontent.com/profiseedev/kubernetes/master/Azure-ARM/deployprofisee.sh", - "PreReqCheckScriptURL":"https://raw.githubusercontent.com/profiseedev/kubernetes/master/Azure-ARM/prereqcheck.sh", + "ScriptURL":"https://raw.githubusercontent.com/profiseeadmin/kubernetes/master/Azure-ARM/deployprofisee.sh", + "PreReqCheckScriptURL":"https://raw.githubusercontent.com/profiseeadmin/kubernetes/master/Azure-ARM/prereqcheck.sh", "KubernetesVnetResourceGroup":"[parameters('KubernetesVnetResourceGroup')]", "vnetId":"[resourceId(parameters('KubernetesVnetResourceGroup'),'Microsoft.Network/virtualNetworks/subnets',parameters('KubernetesVnetName'),parameters('KubernetesSubnetName'))]", "PROFISEEVERSION":"[parameters('ProfiseeVersion')]", @@ -188,6 +195,7 @@ "KubernetesDockerBridgeCidr": "[parameters('KubernetesDockerBridgeCidr')]", "KubernetesLinuxNodeCount": "[int(parameters('KubernetesLinuxNodeCount'))]", "KubernetesLinuxNodeSize": "[parameters('KubernetesLinuxNodeSize')]", + "AuthenticationType": "[parameters('AuthenticationType')]", "KubernetesWindowsNodeCount": "[int(parameters('KubernetesWindowsNodeCount'))]", "KubernetesWindowsNodeSize": "[parameters('KubernetesWindowsNodeSize')]", @@ -226,11 +234,12 @@ "UsePurview":"[parameters('UsePurview')]", "PurviewUrl":"[parameters('PurviewUrl')]", + "PurviewCollectionId":"[parameters('PurviewCollectionFriendlyName')]", "PurviewClientId":"[parameters('PurviewClientId')]", "PurviewClientSecret":"[parameters('PurviewClientSecret')]", "PurviewAccountResourceGroup":"[parameters('PurviewAccountResourceGroup')]" }, - "resources": + "resources": [ { "type": "Microsoft.Resources/deploymentScripts", @@ -241,7 +250,7 @@ "identity": "[variables('ManagedIdentity')]", "properties": { "forceUpdateTag": "[parameters('NewGuid')]", - "azCliVersion": "2.26.0", + "azCliVersion": "2.45.0", "timeout": "PT1H", "cleanupPreference": "OnExpiration", "retentionInterval": "P1D", @@ -255,6 +264,10 @@ "name": "SUBSCRIPTIONID", "value": "[subscription().subscriptionId]" }, + { + "name": "TENANTID", + "value": "[subscription().tenantId]" + }, { "name": "DOMAINNAMERESOURCEGROUP", "value": "[variables('DOMAINNAMERESOURCEGROUP')]" @@ -263,6 +276,10 @@ "name": "UPDATEDNS", "value": "[variables('DNSUpdate')]" }, + { + "name": "DNSDOMAINNAME", + "value": "[variables('DNSDomainName')]" + }, { "name": "UPDATEAAD", "value": "[variables('UPDATEAAD')]" @@ -283,11 +300,19 @@ "name": "PURVIEWURL", "value": "[variables('PurviewUrl')]" }, + { + "name": "PURVIEWCOLLECTIONID", + "value": "[variables('PurviewCollectionId')]" + }, { "name": "PURVIEWCLIENTID", "value": "[variables('PurviewClientId')]" + }, + { + "name": "PURVIEWCLIENTSECRET", + "value": "[variables('PurviewClientSecret')]" } - ] + ] } }, { @@ -298,11 +323,11 @@ "dependsOn": ["[resourceId('Microsoft.Resources/deploymentScripts', 'PreReqChecks')]"], "properties": { "mode": "Incremental", - "expressionEvaluationOptions": + "expressionEvaluationOptions": { "scope": "inner" }, - "template": + "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", @@ -341,11 +366,11 @@ "dependsOn": ["[resourceId('Microsoft.Resources/deploymentScripts', 'PreReqChecks')]"], "properties": { "mode": "Incremental", - "expressionEvaluationOptions": + "expressionEvaluationOptions": { "scope": "inner" }, - "template": + "template": { "$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#", "contentVersion": "1.0.0.0", @@ -454,9 +479,9 @@ "secretName": "[parameters('SQLServerPassword')]" } } - } + } } - }, + }, { "type": "Microsoft.ContainerService/managedClusters", "apiVersion": "2020-07-01", @@ -499,20 +524,6 @@ "vnetSubnetID": "[if(not(empty(variables('KubernetesVnetResourceGroup'))),variables('vnetId'),json('null'))]" } ], - "linuxProfile": { - "adminUsername": "azureuser", - "ssh": { - "publicKeys": [ - { - "keyData": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDOJtY73a8o8/+lSlrEycIchV77zZJeXHZT1+Lvhf97yrmPIU5hiVDLm3z8gD8sxi5VSQ7K3KvTbI7ssNUruXCVSWziDl2jTxOVfGo9faneP1dXGDnU7sRvRHHZ+9xwzh4zGdX4eMWZf1Szh8868f7KBn93mZJZt4Z3uQKJJZuDIveAeYMNQrOi1KGwRPNIOpK3Mu/TzDPo0q51mOYM7KoB0HsZmgWVVMY7vFnwWZGnBOS3QJEZKd369mFgDZ42h3p3gDkcMN76naApSnfCqTZMJ9jr1w0wSNw21IKMFCHph2t5kOPMNQCTq3uA4tbkWHMHyxrXgqBOKHgmVXNFF2BT" - } - ] - } - }, - "windowsProfile": { - "adminUsername": "winadmin", - "adminPassword": "Ple@seCh@ngeMe1234!" - }, "nodeResourceGroup": "[variables('KubenetesInfrastructureResourceGroupName')]", "enableRBAC": true, "networkProfile": { @@ -593,7 +604,7 @@ "[resourceId('Microsoft.Resources/deploymentScripts', 'PreReqChecks')]", "[resourceId('Microsoft.Storage/storageAccounts', tolower(variables('StorageAccountName')))]" ] - }, + }, { "type": "Microsoft.Resources/deploymentScripts", "apiVersion": "2020-10-01", @@ -607,7 +618,7 @@ "identity": "[variables('ManagedIdentity')]", "properties": { "forceUpdateTag": "1", - "azCliVersion": "2.26.0", + "azCliVersion": "2.45.0", "timeout": "PT1H", "cleanupPreference": "OnExpiration", "retentionInterval": "P1D", @@ -671,7 +682,7 @@ { "name": "EXTERNALDNSURL", "value": "[variables('ExternalDNSURL')]" - }, + }, { "name": "OIDCURL", "value": "[variables('OIDCURL')]" @@ -754,6 +765,10 @@ "name": "KUBERNETESCLIENTID", "value": "[reference(resourceId('Microsoft.ContainerService/managedClusters', variables('KubernetesClusterName'))).identityProfile.kubeletidentity.clientId]" }, + { + "name": "KUBERNETESOBJECTID", + "value": "[reference(resourceId('Microsoft.ContainerService/managedClusters', variables('KubernetesClusterName'))).identityProfile.kubeletidentity.objectId]" + }, { "name": "USEPURVIEW", "value": "[variables('UsePurview')]" @@ -762,6 +777,10 @@ "name": "PURVIEWURL", "value": "[variables('PurviewUrl')]" }, + { + "name": "PURVIEWCOLLECTIONID", + "value": "[variables('PurviewCollectionId')]" + }, { "name": "PURVIEWCLIENTID", "value": "[variables('PurviewClientId')]" @@ -774,12 +793,16 @@ "name": "PURVIEWACCOUNTRESOURCEGROUP", "value": "[variables('PurviewAccountResourceGroup')]" }, + { + "name": "AUTHENTICATIONTYPE", + "value": "[variables('AuthenticationType')]" + }, { "name": "WEBAPPNAME", "value": "[variables('WEBAPPNAME')]" } ], - "primaryScriptUri": "[variables('ScriptURL')]" + "primaryScriptUri": "[variables('ScriptURL')]" } }, { @@ -797,8 +820,8 @@ } } ], - "outputs": - { + "outputs": + { "PreReqChecks": { "value": "[reference('PreReqChecks').outputs]", "type": "object" diff --git a/Azure-ARM/azuredeploy.parameters.json b/Azure-ARM/azuredeploy.parameters.json index 22e38318..929d5541 100644 --- a/Azure-ARM/azuredeploy.parameters.json +++ b/Azure-ARM/azuredeploy.parameters.json @@ -3,7 +3,7 @@ "contentVersion": "1.0.0.0", "parameters": { "ProfiseeVersion": { - "value": "profiseeplatform:2021R3.0" + "value": "profiseeplatform:2022r2.0" }, "ProfiseeAdminUserAccount": { "value": "" @@ -14,6 +14,9 @@ "ProfiseeWebAppName": { "value": "" }, + "TenantId": { + "value": "" + }, "ActiveDirectoryCreateApp": { "value": "Yes" }, @@ -23,6 +26,9 @@ "PurviewUrl": { "value": "" }, + "PurviewCollectionFriendlyName": { + "value": "" + }, "PurviewClientId": { "value": "" }, @@ -30,20 +36,20 @@ "value": "" }, "ManagedIdentityName": { - "value": { + "value": { } }, "KubernetesClusterName": { "value": "ProfiseeAKSCluster" }, "KubernetesLinuxNodeSize": { - "value": "Standard_D2s_v3" + "value": "Standard_B2s" }, "KubernetesLinuxNodeCount": { "value": 1 }, "KubernetesWindowsNodeSize": { - "value": "Standard_D4s_v3" + "value": "Standard_B4ms" }, "KubernetesWindowsNodeCount": { "value": 1 @@ -131,6 +137,9 @@ }, "KubenetesInfrastructureResourceGroupName": { "value": "" + }, + "AuthenticationType":{ + "value": "" } } -} \ No newline at end of file +} diff --git a/Azure-ARM/createUIDefinition.json b/Azure-ARM/createUIDefinition.json index dc54c6e9..58f266fb 100644 --- a/Azure-ARM/createUIDefinition.json +++ b/Azure-ARM/createUIDefinition.json @@ -1,7 +1,7 @@ { - "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", - "handler": "Microsoft.Azure.CreateUIDef", - "version": "0.1.2-preview", + "$schema": "https://schema.management.azure.com/schemas/0.1.2-preview/CreateUIDefinition.MultiVm.json#", + "handler": "Microsoft.Azure.CreateUIDef", + "version": "0.1.2-preview", "parameters": { "resourceTypes": [ "microsoft.containerservice/managedclusters", @@ -11,7 +11,6 @@ "microsoft.resources/resourcegroups" ], "basics": [ - { "name": "text2", "type": "Microsoft.Common.TextBlock", @@ -30,7 +29,7 @@ "label": "Managed Identity", "toolTip": { "systemAssignedIdentity": "", - "userAssignedIdentity": " The identity used to run the Profisee deployment" + "userAssignedIdentity": "Pick the Managed Identity that will run the Profisee deployment." }, "defaultValue": { "systemAssignedIdentity": "OffOnly" @@ -50,11 +49,10 @@ "visible": true, "options": { "icon": "Info", - "text": "Click here to learn more about managed identities.", - "uri": "https://support.profisee.com/wikis/2020_r2_support/planning_your_managed_identity_configuration" + "text": "Click here to learn how Profisee uses Managed Identities.", + "uri": "https://support.profisee.com/wikis/2022_r2_support/planning_your_managed_identity_configuration" } } - ], "steps": [ { @@ -65,8 +63,8 @@ "name": "UseKeyVault", "type": "Microsoft.Common.OptionsGroup", "label": "Use Key Vault?", - "defaultValue": "No, I will supply them.", - "toolTip": "", + "defaultValue": "No, I will supply the required values.", + "toolTip": "Profisee can pull a TLS certificate from a Key Vault, as well as these secrets: SQL Username, SQL Password and Profisee License.", "constraints": { "allowedValues": [ { @@ -74,7 +72,7 @@ "value": "Yes" }, { - "label": "No, I will supply them.", + "label": "No, I will supply the required values.", "value": "No" } ], @@ -98,24 +96,12 @@ { "name": "ProfiseeVersion", "type": "Microsoft.Common.DropDown", - "label": "Version", - "defaultValue": "2022R1.0", - "toolTip": "Which release of the Profisee Platform to start with.", + "label": "Profisee version", + "defaultValue": "2022R2.0", + "toolTip": "Which release of the Profisee Platform to deploy.", "constraints": { "required": true, "allowedValues": [ - { - "label": "2020R1.0", - "value": "profiseeplatform:2020r1.0" - }, - { - "label": "2020R1.1", - "value": "profiseeplatform:2020r1.1" - }, - { - "label": "2020R2.0", - "value": "profiseeplatform:2020r2.0" - }, { "label": "2021R1.0", "value": "profiseeplatform:2021r1.0" @@ -132,25 +118,21 @@ "label": "2021R3.0", "value": "profiseeplatform:2021r3.0" }, - { - "label": "2021R3.0.saas", - "value": "profiseeplatform:2021r3.0.saas" - }, { "label": "2022R1.0", - "value": "profiseeplatform:2022r1.preview" + "value": "profiseeplatform:2022r1.0" }, { - "label": "2022R2.preview", - "value": "profiseeplatform:2022r2.preview" + "label": "2022R1-126062", + "value": "profiseeplatform:2022r1-126062" }, { - "label": "2022R2.preview-history", - "value": "profiseeplatform:2022r2.preview-history" + "label": "2022R2.0", + "value": "profiseeplatform:2022r2.0" }, { - "label": "2022R2.preview-matching", - "value": "profiseeplatform:2022r2.preview-matching" + "label": "2023R1.preview", + "value": "profiseeplatform:2023r1.preview" } ] }, @@ -159,10 +141,10 @@ { "name": "ProfiseeAdminUserAccount", "type": "Microsoft.Common.TextBox", - "label": "Admin User Account", + "label": "Super Admin Account", "defaultValue": "", "placeholder": "first.last@company.com", - "toolTip": "The first Super User, who will be able to login and add other users.", + "toolTip": "The first Super User, who will be able to log in and add other users.", "constraints": { "required": true, "regex": "", @@ -173,8 +155,8 @@ { "name": "ProfiseeLicense", "type": "Microsoft.Common.FileUpload", - "label": "License", - "toolTip": "", + "label": "Profisee license", + "toolTip": "This file will be provided by Profisee Support. Please provide the file in txt format.", "constraints": { "required": true, "accept": ".txt" @@ -190,10 +172,10 @@ { "name": "ProfiseeLicenseSecret", "type": "Microsoft.Common.TextBox", - "label": "License", + "label": " Profisee License", "defaultValue": "", - "placeholder": "License secret name in KeyVault", - "toolTip": "", + "placeholder": "License secret name in Key Vault", + "toolTip": "This file will be provided by Profisee Support. Please provide the name of the secret that holds the Profisee license: ex. profisee-license", "constraints": { "required": true, "regex": "", @@ -202,46 +184,39 @@ "visible": "[equals(steps('profisee').UseKeyVault,'Yes')]" }, { - "name": "ActiveDirectoryCreateApp", - "type": "Microsoft.Common.OptionsGroup", - "label": "Do you want the deployment to create a new Azure Active Directory app registration for you?", - "defaultValue": "Yes, create and configure a new Azure Active Directory app registration", - "toolTip": "", + "name": "ProfiseeWebAppName", + "type": "Microsoft.Common.TextBox", + "label": "Web app name", + "defaultValue": "profisee", + "placeholder": "", + "toolTip": "https://host.domain.com/{webAppName}", "constraints": { - "allowedValues": [ - { - "label": "Yes, create and configure a new Azure Active Directory app registration", - "value": "Yes" - }, - { - "label": "No, I will specify the client ID for an existing Azure Active Directory app registration", - "value": "No" - } - ], - "required": true + "required": true, + "regex": "", + "validationMessage": "" }, "visible": true }, { - "name": "UsePurview", + "name": "ActiveDirectoryCreateApp", "type": "Microsoft.Common.OptionsGroup", - "label": "Use Purview?", - "defaultValue": "No, I don't want to use Purview for this configuration", - "toolTip": "", + "label": "Create a new Azure AD application registration for you?", + "defaultValue": "Yes, create and configure it for me.", + "toolTip": "An Azure AD application registration will be used for authentication via ID tokens. For more information please visit https://support.profisee.com/wikis/2022_r2_support/deploying_the_AKS_cluster_with_the_arm_template.", "constraints": { "allowedValues": [ { - "label": "Yes, configure using Purview", + "label": "Yes, create and configure it for me.", "value": "Yes" }, { - "label": "No, I don't want to use Purview for this configuration", + "label": "No, I will specify the client ID of an existing Azure Active Directory app registration.", "value": "No" } ], "required": true }, - "visible": "[or(equals(steps('profisee').ProfiseeVersion,'profiseeplatform:2022r1.preview'), equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2021r3.0'), equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2022r2.preview-history'))]" + "visible": true }, { "name": "UserSuppliedClientyId", @@ -253,7 +228,7 @@ "type": "Microsoft.Common.TextBox", "label": "Application Registration Client Id", "defaultValue": "", - "toolTip": "ClientId of existing Azure Active Directory App Registration which will be used by the Profisee platform for authentication.", + "toolTip": "Please provide the client ID of the Azure AD application to be used by Profisee for authentication.", "constraints": { "required": "[equals(steps('profisee').ActiveDirectoryCreateApp,'No')]", "regex": "", @@ -264,6 +239,27 @@ ], "visible": "[equals(steps('profisee').ActiveDirectoryCreateApp,'No')]" }, + { + "name": "UsePurview", + "type": "Microsoft.Common.OptionsGroup", + "label": "Integrate Profisee with Microsoft Purview?", + "defaultValue": "No, no need at this point.", + "toolTip": "Profisee can integrate with Microsoft Purview during initial configuration or at a later time.", + "constraints": { + "allowedValues": [ + { + "label": "Yes, integrate with Microsoft Purview.", + "value": "Yes" + }, + { + "label": "No, no need at this point.", + "value": "No" + } + ], + "required": true + }, + "visible": "[or(equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2021r2.0'), equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2021r2.1'), equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2021r3.0'), equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2022r1.0'), equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2022r1-126062'), equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2022r2.0'), equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2023r1.preview'))]" + }, { "name": "PurviewAccountName", "type": "Microsoft.Solutions.ResourceSelector", @@ -278,35 +274,35 @@ "visible": "[equals(steps('profisee').UsePurview,'Yes')]" }, { - "name":"GetPurviewUrlRestApiResponse", - "type":"Microsoft.Solutions.ArmApiControl", - "request":{ + "name": "GetPurviewUrlRestApiResponse", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { "method": "GET", "path": "[concat(subscription().id,'/resourceGroups/',last(take(split(steps('profisee').PurviewAccountName.id, '/'), 5)),'/providers/Microsoft.Purview/accounts/',steps('profisee').PurviewAccountName.name,'?api-version=2020-12-01-preview')]", "body": "" } }, { - "name": "PurviewClientID", + "name": "PurviewCollectionFriendlyName", "type": "Microsoft.Common.TextBox", - "label": "Purview Service Principal ID", + "label": "Purview Collection Friendly Name", "defaultValue": "", - "placeholder": "", - "toolTip": "", + "placeholder": "tHiS iS CaSe SenSiTiVe!", + "toolTip": "Please provide the Purview Collection Friendly Name that you see in your Purview account. Profisee will deploy to that collection. If you would like to deploy in the root collection, please specify its friendly name.", "constraints": { "required": true, "regex": "", "validationMessage": "" }, - "visible": "[equals(steps('profisee').UsePurview,'Yes')]" + "visible": "[and(equals(steps('profisee').UsePurview,'Yes'), or(equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2022r2.0'), equals(steps('profisee').ProfiseeVersion, 'profiseeplatform:2023r1.preview')))]" }, { - "name": "PurviewClientSecret", + "name": "PurviewClientID", "type": "Microsoft.Common.TextBox", - "label": "Purview Service Principal Secret", + "label": "Purview application client ID", "defaultValue": "", "placeholder": "", - "toolTip": "", + "toolTip": "A Purview specific Azure AD application client ID. This application registration must be added as Data Curator to Purview and have the appropriate permissions assigned to it by a Global Admin.", "constraints": { "required": true, "regex": "", @@ -315,18 +311,18 @@ "visible": "[equals(steps('profisee').UsePurview,'Yes')]" }, { - "name": "ProfiseeWebAppName", + "name": "PurviewClientSecret", "type": "Microsoft.Common.TextBox", - "label": "Web app name", - "defaultValue": "profisee", + "label": "Purview application secret", + "defaultValue": "", "placeholder": "", - "toolTip": "https://host.domain.com/{webAppName}", + "toolTip": "Please generate a secret in the Purview specific application and paste its value here.", "constraints": { "required": true, "regex": "", "validationMessage": "" }, - "visible": true + "visible": "[equals(steps('profisee').UsePurview,'Yes')]" } ] }, @@ -337,9 +333,9 @@ { "name": "KubernetesClusterName", "type": "Microsoft.Common.TextBox", - "label": "Cluster Name", + "label": " AKS Cluster Name", "defaultValue": "ProfiseeAKSCluster", - "toolTip": "Can only contain letters, numbers, underscores, and hyphens, must start and end with a letter or number, and must be unique in the current resource group", + "toolTip": "Can only contain letters, numbers, underscores, and hyphens, must start and end with a letter or number, and must be unique in the current resource group.", "constraints": { "required": true, "regex": "", @@ -352,7 +348,7 @@ "type": "Microsoft.Common.TextBox", "label": "Infrastructure Resource Group Name", "defaultValue": "", - "toolTip": "Set blank for default of MC_resourcegroupname_clustername_location, or enter the resouce group name you want to use. It must be new, cannot already exist.", + "toolTip": "Leave blank for default of MC_ResourceGroupName_ClusterName_Location, or enter the resouce group name you want to use. You can only specify the name, you can NOT precreate it.", "constraints": { "required": false, "regex": "", @@ -365,7 +361,7 @@ "type": "Microsoft.Common.TextBox", "label": "Version", "defaultValue": "", - "toolTip": "Set blank for latest version, or enter the specific version you want to use.", + "toolTip": "Leave blank for latest AKS version, or enter the specific version you want to use.", "constraints": { "required": false, "regex": "", @@ -373,18 +369,39 @@ }, "visible": true }, + { + "name": "AuthenticationType", + "type": "Microsoft.Common.OptionsGroup", + "label": "Authentication and Authorization", + "defaultValue": "Local Accounts with Kubernetes RBAC", + "toolTip": "Choose among native Kubernetes RBAC managed locally or leverage Azure AD to manage identities for your Kubernetes RBAC needs. Azure RBAC for AKS is a fully managed RBAC solution providing both authentication and authorization through Azure IAM.", + "constraints": { + "allowedValues": [ + { + "label": "Local Accounts with Kubernetes RBAC", + "value": "LocalAccounts" + }, + { + "label": "Azure AD authentication with Azure RBAC", + "value": "AzureRBAC" + } + ], + "required": true + }, + "visible": true + }, { "name": "KubernetesLinuxNodeSizeSection", "type": "Microsoft.Common.Section", - "label": "Linux VM", + "label": "Linux Nodepool", "elements": [ { "name": "KubernetesLinuxNodeSize", "type": "Microsoft.Compute.SizeSelector", - "label": "Size", - "toolTip": "", + "label": "VM Size", + "toolTip": "Pick VM size for the instances in the Linux nodepool. An 's' in the size will result in use of a Premium SSD. Ex. Standard_D2s_v5 will use Premium SSD, Standard_D2_v5 will use HDD.", "recommendedSizes": [ - "Standard_D2s_v3" + "Standard_B2s" ], "constraints": { "allowedSizes": [] @@ -417,15 +434,15 @@ { "name": "KubernetesWindowsNodeSizeSection", "type": "Microsoft.Common.Section", - "label": "Windows VM", + "label": "Windows Nodepool", "elements": [ { "name": "KubernetesWindowsNodeSize", "type": "Microsoft.Compute.SizeSelector", - "label": "Size", - "toolTip": "", + "label": "VM Size", + "toolTip": "Pick VM size for the instances in the Windows nodepool. An 's' in the size will result in use of a Premium SSD. Ex. Standard_D2s_v5 will use Premium SSD, Standard_D2_v5 will use HDD.", "recommendedSizes": [ - "Standard_D4s_v3" + "Standard_B4ms" ], "constraints": { "allowedSizes": [] @@ -454,7 +471,7 @@ "subLabel": "", "defaultValue": 1, "showStepMarkers": false, - "toolTip": "", + "toolTip": "Equal to the number of server licenses for Profisee.", "constraints": { "required": false }, @@ -465,7 +482,7 @@ "type": "Microsoft.Common.OptionsGroup", "label": "Configure advanced Kubernetes networking settings?", "defaultValue": "No, use default settings", - "toolTip": "", + "toolTip": "Kubernetes might fail deploying if the default settings overlap with any vnets in your tenant. It is recommended that you configure these.", "constraints": { "allowedValues": [ { @@ -484,7 +501,7 @@ { "name": "KubernetesAdvanced", "type": "Microsoft.Common.Section", - "label": "Advanced kubernetes settings", + "label": "Advanced Kubernetes settings", "elements": [ { "name": "KubernetesVnetName", @@ -526,9 +543,9 @@ { "name": "KubernetesServiceCidr", "type": "Microsoft.Common.TextBox", - "label": "Service Cidr", - "defaultValue": "10.0.0.0/16", - "toolTip": "A CIDR notation IP range from which to assign service cluster IPs.", + "label": "Service CIDR", + "defaultValue": "10.0.0.0/24", + "toolTip": "A CIDR notation IP range from which to assign IP addresses for cluster services. This range MUST differ from the AKS subnet selected above. This range can be reused between clusters.", "constraints": { "required": false, "regex": "", @@ -541,7 +558,7 @@ "type": "Microsoft.Common.TextBox", "label": "DNS Service IP", "defaultValue": "10.0.0.10", - "toolTip": "Containers DNS server IP address.", + "toolTip": "IP address of the cluster DNS service discovery. Do not use the first IP in the address range.", "constraints": { "required": false, "regex": "", @@ -552,9 +569,9 @@ { "name": "KubernetesDockerBridgeCidr", "type": "Microsoft.Common.TextBox", - "label": "Docker Bridge Cidr", + "label": "Docker Bridge CIDR", "defaultValue": "172.17.0.1/16", - "toolTip": "A CIDR notation IP for Docker bridge.", + "toolTip": "A CIDR notation IP for Docker bridge. This is not used in Azure CNI. Leave as is.", "constraints": { "required": false, "regex": "", @@ -565,7 +582,6 @@ ], "visible": "[equals(steps('kubernetes').KubernetesAdvancedYesNo,'Yes')]" } - ] }, { @@ -575,18 +591,18 @@ { "name": "SQLServerCreateNew", "type": "Microsoft.Common.OptionsGroup", - "label": "Create a new SQL Server? ", - "defaultValue": "Yes, create a new SQL Server", + "label": "Create a new SQL Server?", + "defaultValue": "Yes, create a new SQL Server.", "toolTip": "", "constraints": { "required": true, "allowedValues": [ { - "label": "Yes, create a new SQL Server", + "label": "Yes, create a new SQL Server.", "value": "Yes" }, { - "label": "No, use an existing Azure SQL Server", + "label": "No, use an existing Azure SQL Server.", "value": "No" } ] @@ -634,9 +650,9 @@ { "name": "SQLServerUser", "type": "Microsoft.Common.TextBox", - "label": "User", + "label": "SQL Username", "defaultValue": "sqladmin", - "toolTip": "Administrator SQL login name to create with the new SQL Server or to use to connect to existing SQL Server. Your login name must not contain a SQL Identifier or a typical system name (like admin, administrator, sa, root, dbmanager, loginmanager, etc.) or a built-in database user or role (like dbo, guest, public, etc.). Your login name must not include non-alphanumeric characters. Your login name must not start with numbers or symbols", + "toolTip": "Administrator SQL login name to create with the new SQL Server OR provide the login to connect to an existing SQL Server. Your login name must not contain a SQL Identifier or a typical system name (like admin, administrator, sa, root, dbmanager, loginmanager, etc.) or a built-in database user or role (like dbo, guest, public, etc.). Your login name must not include non-alphanumeric characters. Your login name must not start with numbers or symbols.", "constraints": { "required": true, "regex": "", @@ -647,9 +663,9 @@ { "name": "SQLServerUserSecret", "type": "Microsoft.Common.TextBox", - "label": "User", - "placeholder": "SQL server username secret name in KeyVault", - "toolTip": "Administrator SQL login name to create with the new SQL Server or to use to connect to existing SQL Server. Your login name must not contain a SQL Identifier or a typical system name (like admin, administrator, sa, root, dbmanager, loginmanager, etc.) or a built-in database user or role (like dbo, guest, public, etc.). Your login name must not include non-alphanumeric characters. Your login name must not start with numbers or symbols", + "label": "SQL Username", + "placeholder": "Key Vault secret name: ex. profisee-sql-username", + "toolTip": "Administrator SQL login name to create with the new SQL Server OR provide the login to connect to existing SQL Server. Your login name must not contain a SQL Identifier or a typical system name (like admin, administrator, sa, root, dbmanager, loginmanager, etc.) or a built-in database user or role (like dbo, guest, public, etc.). Your login name must not include non-alphanumeric characters. Your login name must not start with numbers or symbols.", "constraints": { "required": true, "regex": "", @@ -661,7 +677,7 @@ "name": "SQLServerPassword", "type": "Microsoft.Common.PasswordBox", "label": { - "password": "Password", + "password": " SQL Password", "confirmPassword": "Confirm password" }, "toolTip": "", @@ -678,9 +694,9 @@ { "name": "SQLServerPasswordSecret", "type": "Microsoft.Common.TextBox", - "label": "Password", + "label": "SQL Password", "defaultValue": "", - "placeholder": "SQL server password secret name in KeyVault", + "placeholder": "Key Vault secret name: ex. profisee-sql-password", "toolTip": "", "constraints": { "required": true, @@ -702,16 +718,12 @@ }, "visible": true } - - - ] }, { "name": "storage", "label": "Storage", "elements": [ - { "name": "StorageAccountNameSection", "type": "Microsoft.Common.Section", @@ -721,7 +733,7 @@ "name": "StorageAccountName", "type": "Microsoft.Storage.StorageAccountSelector", "label": "Storage account", - "toolTip": "", + "toolTip": "Create new or pick an existing storage account.", "defaultValue": { "name": "", "type": "Standard_LRS" @@ -738,9 +750,9 @@ "visible": true }, { - "name":"GetStorageAccessKeysRestApiResponse", - "type":"Microsoft.Solutions.ArmApiControl", - "request":{ + "name": "GetStorageAccessKeysRestApiResponse", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { "method": "POST", "path": "[concat(subscription().id,'/resourceGroups/',steps('storage').StorageAccountNameSection.StorageAccountName.resourceGroup,'/providers/Microsoft.Storage/storageAccounts/',steps('storage').StorageAccountNameSection.StorageAccountName.name,'/listKeys?api-version=2019-06-01')]", "body": "" @@ -750,7 +762,7 @@ "name": "StorageAccountAccessKey", "type": "Microsoft.Common.DropDown", "label": "Access Keys", - "toolTip": "", + "toolTip": "Pick which storage account access key to use.", "constraints": { "allowedValues": "[map(steps('storage').GetStorageAccessKeysRestApiResponse.keys, (item) => parse(concat('{\"label\":\"', item.keyName, '\",\"value\":\"', item.value, '\"}')))]", "required": true @@ -758,9 +770,9 @@ "visible": "[equals(steps('storage').StorageAccountNameSection.StorageAccountName.newOrExisting, 'existing')]" }, { - "name":"GetStorageFileSharesRestApiResponse", - "type":"Microsoft.Solutions.ArmApiControl", - "request":{ + "name": "GetStorageFileSharesRestApiResponse", + "type": "Microsoft.Solutions.ArmApiControl", + "request": { "method": "GET", "path": "[concat(subscription().id,'/resourceGroups/',steps('storage').StorageAccountNameSection.StorageAccountName.resourceGroup,'/providers/Microsoft.Storage/storageAccounts/',steps('storage').StorageAccountNameSection.StorageAccountName.name,'/fileServices/default/shares?api-version=2019-06-01')]", "body": "" @@ -770,7 +782,7 @@ "name": "StorageAccountFileShareName", "type": "Microsoft.Common.DropDown", "label": "File share", - "toolTip": "", + "toolTip": "A file share must be created in the storage account.", "constraints": { "allowedValues": "[map(steps('storage').GetStorageFileSharesRestApiResponse.value, (item) => parse(concat('{\"label\":\"', item.name, '\",\"value\":\"', item.name, '\"}')))]", "required": true @@ -787,16 +799,16 @@ "name": "DNSUpdate", "type": "Microsoft.Common.OptionsGroup", "label": "Use default Azure DNS?", - "defaultValue": "Yes, use default Azure DNS and Let’s Encrypt for certificates (ex. https://[profisee name].[region].cloudapp.azure.com/profisee)", - "toolTip": "", + "defaultValue": "Yes, use default Azure DNS and Let’s Encrypt for certificates (ex. https://[profisee].[region].cloudapp.azure.com/profisee)", + "toolTip": "Profisee will configure Let's Encrypt to generate and auto-renew a TLS certificate for use with Azure hosted DNS. Ex. profisee.eastus2.cloudapp.azure.com/{web app name}.", "constraints": { "allowedValues": [ { - "label": "Yes, use default Azure DNS and Let’s Encrypt for certificates (ex. https://[profisee name].[region].cloudapp.azure.com/profisee)", + "label": "Yes, use default Azure DNS and Let’s Encrypt for certificates (ex. https://[profisee].[region].cloudapp.azure.com/profisee)", "value": "No" }, { - "label": "No, I’ll use my own DNS host name and domain", + "label": "No, I will provide my own DNS hostname and domain.", "value": "Yes" } ], @@ -812,17 +824,17 @@ { "name": "DNSUpdate2", "type": "Microsoft.Common.OptionsGroup", - "label": "Is your DNS in Azure?", - "defaultValue": "Yes, use new DNS hostname with existing domain name that is in Azure.", - "toolTip": "", + "label": "Are your domain DNS records hosted in an Azure Public DNS Zone?", + "defaultValue": "Yes, I use an Azure Public DNS zone to host my domain records.", + "toolTip": "You have an Azure DNS zone for your domain. The Name Servers of your domain at your domain registrar (ex. Google, Cloudflare, GoDaddy) are set as the Azure Public DNS zone ones.", "constraints": { "allowedValues": [ { - "label": "Yes, use new DNS hostname with existing domain name that is in Azure.", + "label": "Yes, I use an Azure Public DNS zone to host my domain records.", "value": "Yes" }, { - "label": "No, use existing DNS hostname and domain name that is outside of Azure.", + "label": "No, my domain and DNS records are hosted outside of Azure.", "value": "No" } ], @@ -835,8 +847,8 @@ "type": "Microsoft.Common.TextBox", "label": "DNS Host Name", "defaultValue": "", - "placeholder": "myprofiseehostname", - "toolTip": "", + "placeholder": "profiseemdm", + "toolTip": "This is the subdomain part of your domain. Ex. If you will access Profisee at https://profiseemdm.mydomain.com/profisee you need to enter profiseemdm in this field.", "constraints": { "required": true, "regex": "", @@ -849,8 +861,8 @@ "type": "Microsoft.Common.TextBox", "label": "DNS Domain Name", "defaultValue": "", - "placeholder":"mydomain.com", - "toolTip": "", + "placeholder": "This value is CaSe SeNSitiVe! mydomain.com", + "toolTip": "This value is CaSe SeNSitiVe!", "constraints": { "required": true, "regex": "", @@ -861,10 +873,10 @@ { "name": "DNSDomainResourceGroup", "type": "Microsoft.Common.TextBox", - "label": "DNS Domain Resource Group", + "label": "DNS Zone Resource Group", "defaultValue": "", - "placeholder": "mydnszoneresourcegroup", - "toolTip": "", + "placeholder": "This value is CaSe SeNSitiVe! mydnszoneresourcegroup", + "toolTip": "This value is CaSe SeNSitiVe! Please type the name of the Azure Resource group that contains your Azure DNS Zone. Check for case sensitivity by looking in Resource Groups in Azure vs which Resource Group the DNS zone itself belongs to.", "constraints": { "required": true, "regex": "", @@ -879,16 +891,16 @@ "name": "HttpsConfigure", "type": "Microsoft.Common.OptionsGroup", "label": "Use Let’s Encrypt?", - "defaultValue": "Yes, use Let’s Encrypt for certificates", - "toolTip": "", + "defaultValue": "Yes, use Let’s Encrypt for certificates.", + "toolTip": "If yes, Profisee will configure Let's Encrypt to generate, use and auto-renew a free TLS certificate.", "constraints": { "allowedValues": [ { - "label": "Yes, use Let’s Encrypt for certificates", + "label": "Yes, use Let’s Encrypt for certificates.", "value": "No" }, { - "label": "No, I’ll use my own certificates", + "label": "No, I will provide my certificate.", "value": "Yes" } ], @@ -899,13 +911,13 @@ { "name": "UserDefinedHTTPS", "type": "Microsoft.Common.Section", - "label": "User defined https", + "label": "User provided TLS certificate", "elements": [ { "name": "HttpsCertificate", "type": "Microsoft.Common.FileUpload", - "label": "Https Certificate", - "toolTip": "", + "label": "TLS Certificate", + "toolTip": "Please provide a certificate in either txt or crt format.", "constraints": { "required": true, "accept": ".txt,.crt" @@ -921,10 +933,10 @@ { "name": "HttpsCertificateSecret", "type": "Microsoft.Common.TextBox", - "label": "Https Certificate", + "label": "TLS Certificate", "defaultValue": "", - "placeholder": "Https Certificate name in KeyVault", - "toolTip": "", + "placeholder": "TLS Certificate name in KeyVault", + "toolTip": "Name of the certificate as stored in Key Vault. Ex. profisee-tls-certificate", "constraints": { "required": true, "regex": "", @@ -935,8 +947,8 @@ { "name": "HttpsCertificatePrivateKey", "type": "Microsoft.Common.FileUpload", - "label": "Https Certificate Private Key", - "toolTip": "", + "label": "TLS Certificate Private Key", + "toolTip": "Please provide the certificate's private key in either .txt or .key format.", "constraints": { "required": true, "accept": ".txt,.key" @@ -952,20 +964,16 @@ ], "visible": "[equals(steps('networking').HttpsConfigure,'Yes')]" } - ] - } ], "outputs": { "ManagedIdentityName": "[basics('ManagedIdentityName')]", - "ProfiseeVersion": "[steps('profisee').ProfiseeVersion]", "ProfiseeAdminUserAccount": "[steps('profisee').ProfiseeAdminUserAccount]", "ProfiseeLicense": "[if(equals(steps('profisee').UseKeyVault, 'Yes'), steps('profisee').ProfiseeLicenseSecret, steps('profisee').ProfiseeLicense)]", "ActiveDirectoryCreateApp": "[steps('profisee').ActiveDirectoryCreateApp]", "ActiveDirectoryClientId": "[steps('profisee').UserSuppliedClientyId.ActiveDirectoryClientId]", - "KubernetesClusterName": "[steps('kubernetes').KubernetesClusterName]", "KubernetesVersion": "[steps('kubernetes').KubernetesVersion]", "KubenetesInfrastructureResourceGroupName": "[steps('kubernetes').KubenetesInfrastructureResourceGroupName]", @@ -973,15 +981,13 @@ "KubernetesLinuxNodeCount": "[steps('kubernetes').KubernetesLinuxNodeCount]", "KubernetesWindowsNodeSize": "[steps('kubernetes').KubernetesWindowsNodeSizeSection.KubernetesWindowsNodeSize]", "KubernetesWindowsNodeCount": "[steps('kubernetes').KubernetesWindowsNodeCount]", - + "AuthenticationType": "[steps('kubernetes').AuthenticationType]", "KubernetesVnetName": "[steps('kubernetes').KubernetesAdvanced.KubernetesVnetName.name]", "KubernetesVnetResourceGroup": "[steps('kubernetes').KubernetesAdvanced.KubernetesVnetName.resourceGroup]", "KubernetesSubnetName": "[steps('kubernetes').KubernetesAdvanced.KubernetesVnetName.subnets.subnet1.name]", - "KubernetesServiceCidr": "[steps('kubernetes').KubernetesAdvanced.KubernetesServiceCidr]", "KubernetesDNSServiceIP": "[steps('kubernetes').KubernetesAdvanced.KubernetesDNSServiceIP]", "KubernetesDockerBridgeCidr": "[steps('kubernetes').KubernetesAdvanced.KubernetesDockerBridgeCidr]", - "SQLServerCreateNew": "[steps('sql').SQLServerCreateNew]", "SQLServerName": "[if(equals(steps('sql').SQLServerCreateNew, 'Yes'), steps('sql').SQLServerName, steps('sql').SQLServerNameExisting.name)]", "SQLServerUser": "[if(equals(steps('profisee').UseKeyVault, 'Yes'), steps('sql').SQLServerUserSecret, steps('sql').SQLServerUser)]", @@ -993,7 +999,6 @@ "StorageAccountAccessKey": "[steps('storage').StorageAccountAccessKey]", "StorageAccountType": "[steps('storage').StorageAccountNameSection.StorageAccountName.type]", "StorageAccountFileShareName": "files", - "DNSUpdate": "[if(equals(steps('networking').DNSUpdate, 'No'), 'No', steps('networking').UserDefinedDNS.DNSUpdate2)]", "DNSHostName": "[steps('networking').UserDefinedDNS.DNSHostName]", "DNSDomainName": "[steps('networking').UserDefinedDNS.DNSDomainName]", @@ -1001,16 +1006,16 @@ "HttpsConfigure": "[coalesce(steps('networking').HttpsConfigure,'No')]", "UseLetsEncrypt": "[if(equals(coalesce(steps('networking').HttpsConfigure,'No'),'No'),'Yes','No')]", "HttpsCertificate": "[if(equals(steps('profisee').UseKeyVault, 'Yes'), steps('networking').UserDefinedHTTPS.HttpsCertificateSecret, steps('networking').UserDefinedHTTPS.HttpsCertificate)]", - "HttpsCertificatePrivateKey": "[steps('networking').UserDefinedHTTPS.HttpsCertificatePrivateKey]", - "UseKeyVault":"[steps('profisee').UseKeyVault]", - "KeyVault":"[steps('profisee').KeyVault.id]", - "UsePurview":"[steps('profisee').UsePurview]", - "PurviewUrl":"[steps('profisee').GetPurviewUrlRestApiResponse.properties.endpoints.catalog]", - "PurviewClientId":"[steps('profisee').PurviewClientID]", - "PurviewClientSecret":"[steps('profisee').PurviewClientSecret]", - "PurviewAccountResourceGroup":"[last(take(split(steps('profisee').PurviewAccountName.id, '/'), 5))]", - "ProfiseeWebAppName":"[steps('profisee').ProfiseeWebAppName]" + "UseKeyVault": "[steps('profisee').UseKeyVault]", + "KeyVault": "[steps('profisee').KeyVault.id]", + "UsePurview": "[steps('profisee').UsePurview]", + "PurviewUrl": "[steps('profisee').GetPurviewUrlRestApiResponse.properties.endpoints.catalog]", + "PurviewClientId": "[steps('profisee').PurviewClientID]", + "PurviewCollectionFriendlyName": "[steps('profisee').PurviewCollectionFriendlyName]", + "PurviewClientSecret": "[steps('profisee').PurviewClientSecret]", + "PurviewAccountResourceGroup": "[last(take(split(steps('profisee').PurviewAccountName.id, '/'), 5))]", + "ProfiseeWebAppName": "[steps('profisee').ProfiseeWebAppName]" } } -} +} \ No newline at end of file diff --git a/Azure-ARM/deployprofisee.sh b/Azure-ARM/deployprofisee.sh index 9d5e4fcc..f214d3ce 100644 --- a/Azure-ARM/deployprofisee.sh +++ b/Azure-ARM/deployprofisee.sh @@ -13,7 +13,7 @@ if [ -f "$FILE" ]; then exit 1; fi -REPONAME="profiseedev" +REPONAME="profiseeadmin" REPOURL="https://raw.githubusercontent.com/$REPONAME/kubernetes/master"; HELMREPOURL="https://$REPONAME.github.io/kubernetes"; echo $"REPOURL is $REPOURL"; @@ -31,20 +31,20 @@ printenv; #az login --identity -#get the aks creds, this allows us to use kubectl commands if needed +#Get AKS credentials, this allows us to use kubectl commands, if needed. az aks get-credentials --resource-group $RESOURCEGROUPNAME --name $CLUSTERNAME --overwrite-existing; -#install dotnet core -echo $"Installing dotnet core started"; +#Install dotnet core. +echo $"Installation of dotnet core started."; curl -fsSL -o dotnet-install.sh https://dot.net/v1/dotnet-install.sh -#set permisssions +#Set permisssions for installation script. chmod 755 ./dotnet-install.sh -#install dotnet -./dotnet-install.sh -c Current -echo $"Installing dotnet core finished"; +#Install dotnet. +./dotnet-install.sh -c LTS +echo $"Installation of dotnet core finished."; -#Downloadind and extracting license reader -echo $"Downloading and extracting license reader started"; +#Downloadind and extracting Proisee license reader. +echo $"Download and extraction of Profisee license reader started."; curl -fsSL -o LicenseReader.tar.001 "$REPOURL/Utilities/LicenseReader/LicenseReader.tar.001" curl -fsSL -o LicenseReader.tar.002 "$REPOURL/Utilities/LicenseReader/LicenseReader.tar.002" curl -fsSL -o LicenseReader.tar.003 "$REPOURL/Utilities/LicenseReader/LicenseReader.tar.003" @@ -54,103 +54,127 @@ rm LicenseReader.tar.001 rm LicenseReader.tar.002 rm LicenseReader.tar.003 rm LicenseReader.tar.004 -echo $"Downloading and extracting license reader finished"; +echo $"Download and extraction of Profisee license reader finished."; -echo $"Cleaning license string to remove and unwanted characters - linebreaks, spaces, etc..."; +echo $"Clean Profisee license string of any unwanted characters such as linebreaks, spaces, etc..."; LICENSEDATA=$(echo $LICENSEDATA|tr -d '\n') -echo $"Getting values from license started"; +echo $"Search Profisee license for the fully qualified domain name value..."; EXTERNALDNSURLLICENSE=$(./LicenseReader "ExternalDnsUrl" $LICENSEDATA) -#use whats in the license otherwise use whats passed in which is a generated hostname +#Use FQDN that is in license, otherwise use the Azure generated FQDN. #EXTERNALDNSURLLICENSE=$(> a.cert; sed -e 's/^/ /' a.cert > tls.cert; -else +else echo ' NA' > tls.cert; fi rm -f a.cert -#key +#This is for the key if [ "$CONFIGUREHTTPS" = "Yes" ]; then printf '%s\n' "$TLSKEY" | sed 's/- /-\n/g; s/ -/\n-/g' | sed '/PRIVATE/! s/ /\n/g' >> a.key; sed -e 's/^/ /' a.key > tls.key; else - echo ' NA' > tls.key; + echo ' NA' > tls.key; fi rm -f a.key -#set dns +#Set the DNS record in the DNS zone. If present, remove it. if [ "$UPDATEDNS" = "Yes" ]; then - echo "Update DNS started"; - echo "Delete existing A record - started"; + echo "Update of DNS record started."; + echo "Deletion of existing A record started."; az network dns record-set a delete -g $DOMAINNAMERESOURCEGROUP -z $DNSDOMAINNAME -n $DNSHOSTNAME --yes; - echo "Delete existing A record - finished" - echo "Create new A record - started"; + echo "Deletion of existing A record finished." + echo "Creation of new A record started."; az network dns record-set a add-record -g $DOMAINNAMERESOURCEGROUP -z $DNSDOMAINNAME -n $DNSHOSTNAME -a $nginxip --ttl 5; - echo "Create new A record - finished"; - echo "Update DNS finished"; + echo "Creation of new A record finished."; + echo "Update of DNS record finished."; fi -echo $"fix tls variables finished"; +echo $"Correction of TLS variables finished."; -#install profisee platform -echo $"install profisee platform statrted"; -#set profisee helm chart settings -auth="$(echo -n "$ACRUSER:$ACRUSERPASSWORD" | base64)" +#Installation of Profisee platform +echo $"Installation of Profisee platform statrted."; +#Configure Profisee helm chart settings +auth="$(echo -n "$ACRUSER:$ACRUSERPASSWORD" | base64 -w0)" sed -i -e 's/$ACRUSER/'"$ACRUSER"'/g' Settings.yaml sed -i -e 's/$ACRPASSWORD/'"$ACRUSERPASSWORD"'/g' Settings.yaml sed -i -e 's/$ACREMAIL/'"support@profisee.com"'/g' Settings.yaml @@ -279,79 +316,107 @@ echo $"WEBAPPNAME is $WEBAPPNAME"; WEBAPPNAME="${WEBAPPNAME,,}" echo $"WEBAPPNAME is now lower $WEBAPPNAME"; -#create the azure app id (clientid) +#Create the Azure app id (clientid) azureAppReplyUrl="${EXTERNALDNSURL}/${WEBAPPNAME}/auth/signin-microsoft" if [ "$UPDATEAAD" = "Yes" ]; then - echo "Update AAD started"; + echo "Update of Azure Active Directory started. Now we will create the Azure AD Application registration."; azureClientName="${RESOURCEGROUPNAME}_${CLUSTERNAME}"; echo $"azureClientName is $azureClientName"; echo $"azureAppReplyUrl is $azureAppReplyUrl"; - echo "Creating app registration started" - CLIENTID=$(az ad app create --display-name $azureClientName --reply-urls $azureAppReplyUrl --query 'appId' -o tsv); + echo "Creation of the Azure Active Directory application registration started." + CLIENTID=$(az ad app create --display-name $azureClientName --web-redirect-uris $azureAppReplyUrl --enable-id-token-issuance --query 'appId' -o tsv); echo $"CLIENTID is $CLIENTID"; if [ -z "$CLIENTID" ]; then echo $"CLIENTID is null fetching"; CLIENTID=$(az ad app list --display-name $azureClientName --query [0].appId -o tsv) echo $"CLIENTID is $CLIENTID"; fi - echo "Creating app registration finished" - - echo "Updating app registration permissions step 1 started" - #add a Graph API permission of "Sign in and read user profile" - az ad app permission add --id $CLIENTID --api 00000003-0000-0000-c000-000000000000 --api-permissions e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope - echo "Updating app registration permissions step 1 finished" - - echo "Updating app registration permissions step 2 started" - az ad app permission grant --id $CLIENTID --api 00000003-0000-0000-c000-000000000000 + echo "Creation of the Azure Active Directory application registration finished." + echo "Sleeping for 20 seconds to wait for the app registration to be ready." + sleep 20; + + #If Azure Application Registration User.Read permission is present, skip adding it. + echo $"Let's check to see if the User.Read permission is granted, skip if has been." + appregpermissionspresent=$(az ad app permission list --id $CLIENTID --query "[].resourceAccess[].id" -o tsv) + if [ "$appregpermissionspresent" = "e1fe6dd8-ba31-4d61-89e7-88639da4683d" ]; then + echo $"User.Read permissions already present, no need to add it." + else - echo "Updating app registration permissions step 2 finished" - echo "Update AAD finished"; + echo "Update of the application registration's permissions, step 1 started." + #Add a Graph API permission to "Sign in and read user profile" + az ad app permission add --id $CLIENTID --api 00000003-0000-0000-c000-000000000000 --api-permissions e1fe6dd8-ba31-4d61-89e7-88639da4683d=Scope + echo "Creation of the service principal started." + az ad sp create --id $CLIENTID + echo "Creation of the service principal finished." + echo "Update of the application registration's permissions, step 1 finished." + + echo "Update of the application registration's permissions, step 2 started." + az ad app permission grant --id $CLIENTID --api 00000003-0000-0000-c000-000000000000 --scope User.Read + echo "Update of the application registration's permissions, step 2 finished." + echo "Update of Azure Active Directory finished."; + fi fi -#get storage account pw - if not supplied +#If not supplied, acquire storage account credentials. if [ "$FILEREPOPASSWORD" = "" ]; then - echo $"FILEREPOPASSWORD was not passed in, getting it from the storage acount." + echo $"FILEREPOPASSWORD was not passed in, acquiring credentials from the storage account." FILEREPOPASSWORD=$(az storage account keys list --resource-group $RESOURCEGROUPNAME --account-name $STORAGEACCOUNTNAME --query '[0].value'); #clean file repo password - remove quotes FILEREPOPASSWORD=$(echo "$FILEREPOPASSWORD" | tr -d '"') else - echo $"FILEREPOPASSWORD was passed in, using it." + echo $"FILEREPOPASSWORD was passed in, we'll use it." fi +echo $"Correction of TLS variables finished."; -#If creating a new sql database, create firewall rule for sql server - add outbound ip of aks cluster +#If deployment of a new SQL database has been selected, we will create a SQL firewall rule to allow traffic from the AKS cluster's egress IP. if [ "$SQLSERVERCREATENEW" = "Yes" ]; then - echo "Adding firewall rule to sql started"; + echo "Addition of a SQL firewall rule started."; #strip off .database.windows.net IFS='.' read -r -a sqlString <<< "$SQLNAME" echo "SQLNAME is $SQLNAME" sqlServerName=${sqlString[0],,}; #lowercase is the ,, echo "sqlServerName is $sqlServerName" - echo "Getting ip address from $AKSINFRARESOURCEGROUPNAME" + echo "Acquiring the IP address from $AKSINFRARESOURCEGROUPNAME" OutIP=$(az network public-ip list -g $AKSINFRARESOURCEGROUPNAME --query "[0].ipAddress" -o tsv); - echo "OutIP is $OutIP" + echo "The load balancer's egress public IP is $OutIP" az sql server firewall-rule create --resource-group $RESOURCEGROUPNAME --server $sqlServerName --name "aks lb ip" --start-ip-address $OutIP --end-ip-address $OutIP - echo "Adding firewall rule to sql finished"; + echo "Addition of the SQL firewall rule finished."; fi -echo "about to set vars in settings.yaml" -#storage vars +#Acquire the collection id from the collection name +if [ "$USEPURVIEW" = "Yes" ]; then + echo "Obtain collection id from provided collection friendly name started."; + echo "Grab a token." + purviewtoken=$(curl --location --no-progress-meter --request GET "https://login.microsoftonline.com/$TENANTID/oauth2/token" --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode "client_id=$PURVIEWCLIENTID" --data-urlencode "client_secret=$PURVIEWCLIENTSECRET" --data-urlencode 'grant_type=client_credentials' --data-urlencode 'resource=https://purview.azure.net' | jq --raw-output '.access_token'); + echo "Token acquired." + echo "Find collection Id."; + echo $"Stripping /catalog from $PURVIEWURL." + PURVIEWACCOUNTFQDN=${PURVIEWURL::-8} + echo $"Purview account name is $PURVIEWACCOUNTFQDN. Using it." + COLLECTIONTRUEID=$(curl --location --no-progress-meter --request GET "$PURVIEWACCOUNTFQDN/account/collections?api-version=2019-11-01-preview" --header "Authorization: Bearer $purviewtoken" | jq --raw-output '.value | .[] | select(.friendlyName=="'$PURVIEWCOLLECTIONID'") | .name') + echo $"Collection id is $COLLECTIONTRUEID, using that."; + echo "Obtain collection id from provided collection friendly name completed."; +fi + +echo "The variables will now be set in the Settings.yaml file" +#Setting storage related variables FILEREPOUSERNAME="Azure\\\\\\\\${STORAGEACCOUNTNAME}" FILEREPOURL="\\\\\\\\\\\\\\\\${STORAGEACCOUNTNAME}.file.core.windows.net\\\\\\\\${STORAGEACCOUNTFILESHARENAME}" -#PROFISEEVERSION looks like this profiseeplatform:2020R1.0 -#The repo is profiseeplatform or something like it, its everything to the left of the : +#PROFISEEVERSION looks like this profiseeplatform:2022R2.0 +#The repository name is profiseeplatform, it is everything to the left of the colon sign : #The label is everything to the right of the : IFS=':' read -r -a repostring <<< "$PROFISEEVERSION" #lowercase is the ,, -ACRREPONAME="${repostring[0],,}"; +ACRREPONAME="${repostring[0],,}"; ACRREPOLABEL="${repostring[1],,}" -#set values in Settings.yaml +#Setting values in the Settings.yaml sed -i -e 's/$SQLNAME/'"$SQLNAME"'/g' Settings.yaml sed -i -e 's/$SQLDBNAME/'"$SQLDBNAME"'/g' Settings.yaml sed -i -e 's/$SQLUSERNAME/'"$SQLUSERNAME"'/g' Settings.yaml @@ -372,6 +437,7 @@ sed -i -e 's/$ACRREPONAME/'"$ACRREPONAME"'/g' Settings.yaml sed -i -e 's/$ACRREPOLABEL/'"$ACRREPOLABEL"'/g' Settings.yaml sed -i -e 's~$PURVIEWURL~'"$PURVIEWURL"'~g' Settings.yaml sed -i -e 's/$PURVIEWTENANTID/'"$TENANTID"'/g' Settings.yaml +sed -i -e 's/$PURVIEWCOLLECTIONID/'"$COLLECTIONTRUEID"'/g' Settings.yaml sed -i -e 's/$PURVIEWCLIENTID/'"$PURVIEWCLIENTID"'/g' Settings.yaml sed -i -e 's/$PURVIEWCLIENTSECRET/'"$PURVIEWCLIENTSECRET"'/g' Settings.yaml sed -i -e 's/$WEBAPPNAME/'"$WEBAPPNAME"'/g' Settings.yaml @@ -393,7 +459,6 @@ if [ "$USEKEYVAULT" = "Yes" ]; then sed -i -e 's/$AZURESUBSCRIPTIONID/'"$keyVaultSubscriptionId"'/g' Settings.yaml sed -i -e 's/$AZURETENANTID/'"$TENANTID"'/g' Settings.yaml - $SUBSCRIPTIONID else sed -i -e 's/$USEKEYVAULT/'false'/g' Settings.yaml fi @@ -401,51 +466,67 @@ fi if [ "$USELETSENCRYPT" = "Yes" ]; then #################################Lets Encrypt Start ##################################### # Label the namespace to disable resource validation - echo "Lets Encrypt started"; + echo "Let's Encrypt installation started"; kubectl label namespace profisee cert-manager.io/disable-validation=true helm repo add jetstack https://charts.jetstack.io # Update your local Helm chart repository cache helm repo update + #If cert-manager is present, uninstall it. + certmgrpresent=$(helm list -n profisee -f cert-manager -o table --short) + if [ "$certmgrpresent" = "cert-manager" ]; then + helm uninstall -n profisee cert-manager; + echo $"Will sleep for 20 seconds to allow clean uninstall of cert-manager." + sleep 20; + fi # Install the cert-manager Helm chart - helm install cert-manager jetstack/cert-manager --namespace profisee --set installCRDs=true --set nodeSelector."kubernetes\.io/os"=linux --set webhook.nodeSelector."kubernetes\.io/os"=linux --set cainjector.nodeSelector."kubernetes\.io/os"=linux --set startupapicheck.nodeSelector."kubernetes\.io/os"=linux - #wait for the cert manager to be ready - echo $"Lets Encrypt, waiting for certificate manager to be ready, sleeping for 30s"; + helm install cert-manager jetstack/cert-manager -n profisee --set installCRDs=true --set nodeSelector."kubernetes\.io/os"=linux --set webhook.nodeSelector."kubernetes\.io/os"=linux --set cainjector.nodeSelector."kubernetes\.io/os"=linux --set startupapicheck.nodeSelector."kubernetes\.io/os"=linux + # Wait for the cert manager to be ready + echo $"Let's Encrypt is waiting for certificate manager to be ready, sleeping for 30 seconds."; sleep 30; sed -i -e 's/$USELETSENCRYPT/'true'/g' Settings.yaml - echo "Lets Encrypt finshed"; + echo "Let's Encrypt installation finshed"; #################################Lets Encrypt End ####################################### else sed -i -e 's/$USELETSENCRYPT/'false'/g' Settings.yaml fi -#Add settings.yaml as a secret so its always available after the deployment -kubectl delete secret profisee-settings --namespace profisee --ignore-not-found -kubectl create secret generic profisee-settings --namespace profisee --from-file=Settings.yaml +#Adding Settings.yaml as a secret generated only from the initial deployment of Profisee. Future updates, such as license changes via the profisee-license secret, or SQL credentials updates via the profisee-sql-password secret, will NOT be reflected in this secret. Proceed with caution! +kubectl delete secret profisee-settings -n profisee --ignore-not-found +kubectl create secret generic profisee-settings -n profisee --from-file=Settings.yaml #################################Install Profisee Start ####################################### -echo "Install Profisee started $(date +"%Y-%m-%d %T")"; +echo "Installation of Profisee platform started $(date +"%Y-%m-%d %T")"; helm repo add profisee $HELMREPOURL helm repo update -helm uninstall --namespace profisee profiseeplatform -helm install --namespace profisee profiseeplatform profisee/profisee-platform --values Settings.yaml -kubectl delete secret profisee-deploymentlog --namespace profisee --ignore-not-found -kubectl create secret generic profisee-deploymentlog --namespace profisee --from-file=$logfile +#If Profisee is present, uninstall it. If not, proceeed to installation. +echo "If profisee is installed, uninstall it first." +profiseepresent=$(helm list -n profisee -f profiseeplatform -o table --short) +if [ "$profiseepresent" = "profiseeplatform" ]; then + helm -n profisee uninstall profiseeplatform; + echo "Will sleep for 30 seconds to allow clean uninstall." + sleep 30; +fi + echo "Profisee is not installed, proceeding to install it." + helm -n profisee install profiseeplatform profisee/profisee-platform --values Settings.yaml + +kubectl delete secret profisee-deploymentlog -n profisee --ignore-not-found +kubectl create secret generic profisee-deploymentlog -n profisee --from-file=$logfile #Make sure it installed, if not return error -profiseeinstalledname=$(echo $(helm list --filter 'profisee+' --namespace profisee -o json)| jq '.[].name') +profiseeinstalledname=$(echo $(helm list --filter 'profisee+' -n profisee -o json)| jq '.[].name') if [ -z "$profiseeinstalledname" ]; then - echo "Profisee did not get installed. Exiting with error"; + echo "Profisee did not get installed. Exiting with error"; exit 1 else - echo "Install Profisee finished $(date +"%Y-%m-%d %T")"; + echo "Installation of Profisee finished $(date +"%Y-%m-%d %T")"; fi; #################################Install Profisee End ####################################### -#wait for pod to be ready (downloaded) +#Wait for pod to be ready (downloaded) echo "Waiting for pod to be downloaded and be ready..$(date +"%Y-%m-%d %T")"; sleep 30; -kubectl wait --timeout=1800s --for=condition=ready pod/profisee-0 --namespace profisee +kubectl wait --timeout=1800s --for=condition=ready pod/profisee-0 -n profisee echo $"Profisee deploymented finished $(date +"%Y-%m-%d %T")"; @@ -463,8 +544,16 @@ result="{\"Result\":[\ ]}" echo $result - -kubectl delete secret profisee-deploymentlog --namespace profisee --ignore-not-found -kubectl create secret generic profisee-deploymentlog --namespace profisee --from-file=$logfile +kubectl delete secret profisee-deploymentlog -n profisee --ignore-not-found +kubectl create secret generic profisee-deploymentlog -n profisee --from-file=$logfile +echo $"AuthenticationType is $AUTHENTICATIONTYPE"; +echo $"Resourcegroup is $RESOURCEGROUPNAME"; +echo $"clustername is $CLUSTERNAME"; +if [ "$AUTHENTICATIONTYPE" = "AzureRBAC" ]; then + az aks update -g $RESOURCEGROUPNAME -n $CLUSTERNAME --enable-aad --enable-azure-rbac --disable-local-accounts + ObjectId="$(az ad user show --id $ADMINACCOUNTNAME --query id -o tsv)" + echo $"ObjectId of ADMIN is $ObjectId"; + az role assignment create --role "Azure Kubernetes Service RBAC Cluster Admin" --assignee-object-id $ObjectId --assignee-principal-type User --scope /subscriptions/$SUBSCRIPTIONID/resourcegroups/$RESOURCEGROUPNAME +fi; echo $result > $AZ_SCRIPTS_OUTPUT_PATH diff --git a/Azure-ARM/nginxSettings.yaml b/Azure-ARM/nginxSettings.yaml index ae3a5028..eb780f45 100644 --- a/Azure-ARM/nginxSettings.yaml +++ b/Azure-ARM/nginxSettings.yaml @@ -1,29 +1,28 @@ controller: - extraArgs: - default-ssl-certificate: profisee/profisee-tls-ingress - nodeSelector: - kubernetes.io/os: linux - replicaCount: 1 admissionWebhooks: patch: nodeSelector: kubernetes.io/os: linux config: + client-header-buffer-size: 512k + client_body_buffer_size: 512k + http2-max-field-size: 16k + http2-max-header-size: 512k + large-client-header-buffers: 32 512k + proxy-buffer-size: 512k proxy-buffering: "off" - proxy-buffer-size: "512k" + proxy-buffers: 32 512k + proxy-busy-buffers-size: 512k proxy-connect-timeout: "5400" - proxy-send-timeout: "5400" - proxy-read-timeout: "5400" proxy-next-upstream: "off" + proxy-read-timeout: "5400" proxy-request-buffering: "off" - proxy-buffers: "32 512k" - proxy-busy-buffers-size: "512k" - client_body_buffer_size: "512k" - client-header-buffer-size: "512k" - http2-max-field-size: "16k" - http2-max-header-size: "512k" - large-client-header-buffers: "32 512k" - + proxy-send-timeout: "5400" + extraArgs: + default-ssl-certificate: profisee/profisee-tls-ingress + nodeSelector: + kubernetes.io/os: linux + replicaCount: 1 defaultBackend: nodeSelector: kubernetes.io/os: linux diff --git a/Azure-ARM/prereqcheck.sh b/Azure-ARM/prereqcheck.sh index 2fe30985..53e09d28 100644 --- a/Azure-ARM/prereqcheck.sh +++ b/Azure-ARM/prereqcheck.sh @@ -28,7 +28,7 @@ function set_resultAndReturn () { echo $result > $AZ_SCRIPTS_OUTPUT_PATH exit 1 } - +echo $"DNSDOMAINNAME is $DNSDOMAINNAME" echo $"RESOURCEGROUPNAME is $RESOURCEGROUPNAME" echo $"SUBSCRIPTIONID is $SUBSCRIPTIONID" echo $"DOMAINNAMERESOURCEGROUP is $DOMAINNAMERESOURCEGROUP" @@ -38,52 +38,55 @@ echo $"USEKEYVAULT is $USEKEYVAULT" echo $"KEYVAULT is $KEYVAULT" echo $"USEPURVIEW is $USEPURVIEW" echo $"PURVIEWURL is $PURVIEWURL" +echo $"PURVIEWCOLLECTIONID is $PURVIEWCOLLECTIONID" echo $"PURVIEWCLIENTID is $PURVIEWCLIENTID" +echo $"PURVIEWCLIENTSECRET is $PURVIEWCLIENTSECRET" +echo $"TENANTID is $TENANTID" IFS='/' read -r -a miparts <<< "$AZ_SCRIPTS_USER_ASSIGNED_IDENTITY" #splits the mi on slashes mirg=${miparts[4]} miname=${miparts[8]} -#remove white space +#Remove white space miname=$(echo $miname | xargs) -#get the id of the current user (MI) +#Get the ID of the current user (MI) echo "Running az identity show -g $mirg -n $miname --query principalId -o tsv" currentIdentityId=$(az identity show -g $mirg -n $miname --query principalId -o tsv) if [ -z "$currentIdentityId" ]; then - err="Unable to query Managed Identity to get principal id. Exiting with error." + err="Unable to query the Deployment Managed Identity to get principal id. Exiting with error. IF the Deployment Managed Identity has just been created, this issue is most likely intermittent. Please retry your deployment." echo $err set_resultAndReturn; fi -#Check to make sure you have effective contributor access to the resource group. at RG or sub levl -#check subscription level +#Check to make sure you have effective Contributor access at either Resource group or Subscription level. +#Checking Subscription level first. -echo "Checking contributor level for subscription" +echo "Is the Deployment Managed Identity assigned the Contributor Role at the Subscription or at the Resource Group level?" subscriptionContributor=$(az role assignment list --all --assignee $currentIdentityId --output json --include-inherited --query "[?roleDefinitionName=='Contributor' && scope=='/subscriptions/$SUBSCRIPTIONID'].roleDefinitionName" --output tsv) if [ -z "$subscriptionContributor" ]; then - echo "Managed Identity is NOT contributor at subscription level, checking resource group" - #not subscription level, check resource group level + echo "Role is NOT assigned at Subscription level, checking Resource Group level assignment now. Please bear in mind that if you plan to have the Deployment Managed Identity create the Resource Group for you, then you will need to grant it Contributor role at Subscription level." + #Deployment MAnaged Identity is not granted Contributor at Subscription level, checking Resource Group level. rgContributor=$(az role assignment list --all --assignee $currentIdentityId --output json --include-inherited --query "[?roleDefinitionName=='Contributor' && scope=='/subscriptions/$SUBSCRIPTIONID/resourceGroups/$RESOURCEGROUPNAME'].roleDefinitionName" --output tsv) if [ -z "$rgContributor" ]; then - err="Managed Identity is not Contributor to resource group. Exiting with error." + err="Role is NOT assigned at either Subscription or Resource Group level. Exiting with error. Please assign the Contributor role to the Deployment Managed Identity at either Subscription or Resource Group level. Please visit https://support.profisee.com/wikis/2022_r2_support/planning_your_managed_identity_configuration for more information." echo $err set_resultAndReturn; else - echo "Managed Identity is Contributor to resource group." + echo "Role is assigned at Resource level. Continuing checks." fi - #If updating dns, check to make sure you have effective contributor access to the dns resource group + #If updating DNS, check to make sure you have effective contributor access to the DNS zone itself. if [ "$UPDATEDNS" = "Yes" ]; then - echo "Checking contributor for DNS resource group" - dnsrgContributor=$(az role assignment list --all --assignee $currentIdentityId --output json --include-inherited --query "[?roleDefinitionName=='Contributor' && scope=='/subscriptions/$SUBSCRIPTIONID/resourceGroups/$DOMAINNAMERESOURCEGROUP'].roleDefinitionName" --output tsv) - if [ -z "$dnsrgContributor" ]; then - err="Managed Identity is not Contributor to DNS resource group. Exiting with error." + echo "Is the Deployment Managed Identity assigned the DNS Zone Contributor role to the DNS zone itself?" + dnsznContributor=$(az role assignment list --all --assignee $currentIdentityId --output json --include-inherited --query "[?roleDefinitionName=='DNS Zone Contributor' && scope=='/subscriptions/$SUBSCRIPTIONID/resourceGroups/$DOMAINNAMERESOURCEGROUP/providers/Microsoft.Network/dnszones/$DNSDOMAINNAME'].roleDefinitionName" --output tsv) + if [ -z "$dnsznContributor" ]; then + err="Role is NOT assigned. Exiting with error. Please assign the DNS Zone Contributor role to the Deployment Managed Identity for the DNS zone you want updated. Please visit https://support.profisee.com/wikis/2022_r2_support/planning_your_managed_identity_configuration for more information." echo $err set_resultAndReturn; else - echo "Managed Identity is Contributor to DNS resource group." + echo "Role is assigned. Continuing checks." fi fi @@ -102,71 +105,84 @@ if [ -z "$subscriptionContributor" ]; then # fi else - echo "Managed Identity is Contributor at subscription level." + echo "Role is assigned at Subsciption level. Continuing checks." fi # If using Purview, check for the following: -# 1. For the Purview client to have the Data Curator role. If not, error out. -# 2. That the Purview client has proper permissions. If not, output warnings and continue. +# 1. Has the Purview Application Registration been added to the Data Curators role in the Purview account. If not, exit with error. +# 2. Does the Purview Application Registartion have the proper permissions. If not, output warnings and continue. if [ "$USEPURVIEW" = "Yes" ]; then purviewClientPermissions=$(az ad app permission list --id $PURVIEWCLIENTID --output tsv --query [].resourceAccess[].id) - #User.Read + #Check if User.Read permission has been granted to the Purview specific Azure Application Registration. if [[ $purviewClientPermissions != *"e1fe6dd8-ba31-4d61-89e7-88639da4683d"* ]]; then - echo "Missing User.Read application permission. Some governance features may not function until this permission is added." + echo "The Purview Azure AD application registration is missing the Microsoft Graph API User.Read delegated permission. Some governance features may not function until this permission is granted. This permission might require an Azure AD Global Admin consent. Please visit https://support.profisee.com/wikis/2022_r2_support/prerequisites_for_integrating_with_purview for more information. " fi - #User.Read.All + #Check if User.Read.All permission has been granted to the Purview specific Azure Application Registration. if [[ $purviewClientPermissions != *"df021288-bdef-4463-88db-98f22de89214"* ]]; then - echo "Missing User.Read.All application permission. Some governance features may not function until this permission is added." + echo "The Purview Azure AD application registration is missing the Microsoft Graph API User.Read.All application permission. Some governance features will not function until this permission is granted. This permission requires an Azure AD Global Admin consent. Please visit https://support.profisee.com/wikis/2022_r2_support/prerequisites_for_integrating_with_purview for more information." fi - #Group.Read.All + #Check if Group.Read.All permission has been granted to the Purview specific Azure Application Registration. if [[ $purviewClientPermissions != *"5b567255-7703-4780-807c-7be8301ae99b"* ]]; then - echo "Missing Group.Read.All application permission. Some governance features may not function until this permission is added." + echo "The Purview Azure AD application registration is missing the Microsoft Graph API Group.Read.All application permission. Some governance features will not function until this permission is granted. This permission requires an Azure AD Global Admin consent. Please visit https://support.profisee.com/wikis/2022_r2_support/prerequisites_for_integrating_with_purview for more information." fi - #GroupMember.Read.All + #Check if GroupMember.Read.All permission has been granted to the Purview specific Azure Application Registration. if [[ $purviewClientPermissions != *"98830695-27a2-44f7-8c18-0c3ebc9698f6"* ]]; then - echo "Missing GroupMember.Read.All application permission. Some governance features may not function until this permission is added." + echo "The Purview Azure AD application registration is missing the Microsoft Graph API GroupMember.Read.All application permission. Some governance features will not function until this permission is granted. This permission requires an Azure AD Global Admin consent. Please visit https://support.profisee.com/wikis/2022_r2_support/prerequisites_for_integrating_with_purview for more information." + fi + #Check if the provided Purview Collection name exists. + #Acquire token + echo "Checking if provided Purview collection friendly name exists." + purviewtoken=$(curl --location --no-progress-meter --request GET "https://login.microsoftonline.com/$TENANTID/oauth2/token" --header 'Content-Type: application/x-www-form-urlencoded' --data-urlencode "client_id=$PURVIEWCLIENTID" --data-urlencode "client_secret=$PURVIEWCLIENTSECRET" --data-urlencode 'grant_type=client_credentials' --data-urlencode 'resource=https://purview.azure.net' | jq --raw-output '.access_token'); + #Strip /catalog from end of Purview URL + PURVIEWACCOUNTFQDN=${PURVIEWURL::-8} + collectionnamenotfound=$(curl --location --no-progress-meter --request GET "$PURVIEWACCOUNTFQDN/account/collections?api-version=2019-11-01-preview" --header "Authorization: Bearer $purviewtoken" | jq --raw-output '.value | .[] | select(.friendlyName=="'$PURVIEWCOLLECTIONID'") | .name'); + if [ -z "$collectionnamenotfound" ]; then + err=$"The "$PURVIEWCOLLECTIONID" collection name provided could NOT be found. Exiting with error." + echo $err + set_resultAndReturn; + else + echo $"The "$PURVIEWCOLLECTIONID" collection name provided was found. Continuing checks." fi fi -#If using keyvault, check to make sure you have Managed Identity Contributor role AND User Access Administrator +#If using Key Vault, checks to make sure that the Deployment Managed Identity has been assigned the Managed Identity Contributor role AND User Access Administrator as Subscription level. if [ "$USEKEYVAULT" = "Yes" ]; then - echo "In KeyVault checks" - echo "Checking Managed Identity Contributor at subscription level." + echo "Is the Deployment Managed Identity assigned the Managed Identity Contributor role at the Subscription level?" subscriptionMIContributor=$(az role assignment list --all --assignee $currentIdentityId --output json --include-inherited --query "[?roleDefinitionName=='Managed Identity Contributor' && scope=='/subscriptions/$SUBSCRIPTIONID'].roleDefinitionName" --output tsv) if [ -z "$subscriptionMIContributor" ]; then - err="Managed Identity is not Managed Identity Contributor at subscription level. Exiting with error." + err="Role is NOT assigned. Exiting with error. If using Key Vault, this role is required so that the Deployment Managed Identity can create the Managed Identity that will be used to communicated with Key Vault." echo $err set_resultAndReturn; else - echo "Managed Identity is Managed Identity Contributor at subscription level." + echo "Role is assigned. Continuing checks." fi - echo "Checking User Access Administrator at subscription level." + echo "Is the Deployment Managed Identity assigned the User Access Administrator role at Subscription level?" subscriptionUAAContributor=$(az role assignment list --all --assignee $currentIdentityId --output json --include-inherited --query "[?roleDefinitionName=='User Access Administrator' && scope=='/subscriptions/$SUBSCRIPTIONID'].roleDefinitionName" --output tsv) if [ -z "$subscriptionUAAContributor" ]; then - err="Managed Identity is not User Access Administrator at subscription level. Exiting with error." + err="The Deployment Managed Identity is NOT assigned the User Access Administrator at subscription level. Exiting with error. If using Key Vault, this role is required so that the Deployment Managed Identity can assign the Key Vault Secrets User role, if using RBAC KV, OR the Get policies, if using policy based KV, to the Key Vault Specific Managed Identity." echo $err set_resultAndReturn; else - echo "Managed Identity is User Access Administrator at subscription level." + echo "Role is assigned. Continuing checks." fi fi -#If updating AAD, make sure you have Application Administrator role +#If Deployment Managed Identity will be creating the Azure AD application registration, make sure that the Application Administrator role is assigned to it. if [ "$UPDATEAAD" = "Yes" ]; then - echo "Checking Application Administrator Role" - appDevRoleId=$(az rest --method get --url https://graph.microsoft.com/v1.0/directoryRoles/ | jq -r '.value[] | select(.displayName | contains("Application Administrator")).id') + echo "Is the Deployment Managed Identity assigned the Application Administrator Role in Azure Active Directory?" + appDevRoleId=$(az rest --method get --url https://graph.microsoft.com/v1.0/directoryRoles/ | jq -r '.value[] | select(.displayName == "Application Administrator").id') minameinrole=$(az rest --method GET --uri "https://graph.microsoft.com/beta/directoryRoles/$appDevRoleId/members" | jq -r '.value[] | select(.displayName | contains("'"$miname"'")).displayName') if [ -z "$minameinrole" ]; then - err="Managed Identity is not in Application Administrator role. Exiting with error." + err="The Deployment Managed Identity is NOT assigned the Application Administrator role in Azure Active Directory. Exiting with error. This role is required so that the Deployment Managed Identity can create the Azure AD Application registration. For more information please visit https://support.profisee.com/wikis/2022_r2_support/planning_your_managed_identity_configuration." echo $err set_resultAndReturn; else - echo "Managed Identity is in Application Administrator role." + echo "Role is assigned. All checks completed." fi fi @@ -177,4 +193,4 @@ echo $"Profisee pre-req check finished $(date +"%Y-%m-%d %T")"; result="{\"Result\":[\ {\"SUCCESS\":\"$success\"} ]}" -echo $result > $AZ_SCRIPTS_OUTPUT_PATH +echo $result > $AZ_SCRIPTS_OUTPUT_PATH \ No newline at end of file diff --git a/README.md b/README.md index f09fc78c..7c99a98e 100644 --- a/README.md +++ b/README.md @@ -4,16 +4,16 @@ This repository contains all the ways to deploy the Profisee platform to Kuberne ## AWS-ELS-CLI -[Home](https://github.com/profiseedev/kubernetes/tree/master/AWS-EKS-CLI#deploy-profisee-platform-on-to-aws-elastic-kubernetes-services-eks) for all the scripts needed to deploy Profisee Platform to AWS EKS (Elastic Kubernetes services) via the aws cli. +[Home](https://github.com/profiseeadmin/kubernetes/tree/master/AWS-EKS-CLI#deploy-profisee-platform-on-to-aws-elastic-kubernetes-services-eks) for all the scripts needed to deploy Profisee Platform to AWS EKS (Elastic Kubernetes services) via the aws cli. ## Azure-ARM -[Home](https://github.com/profiseedev/kubernetes/blob/master/Azure-ARM/README.md#deploy-profisee-platform-on-to-aks-using-arm-template) for all the templates to deploy Profisee Platform to AKS via ARM templates. +[Home](https://github.com/profiseeadmin/kubernetes/blob/master/Azure-ARM/README.md#deploy-profisee-platform-on-to-aks-using-arm-template) for all the templates to deploy Profisee Platform to AKS via ARM templates. ## Azure-Powershell -[Home](https://github.com/profiseedev/kubernetes/tree/master/Azure-Powershell#deploy-profisee-platform-to-aks-using-powershell) for all the scripts needed to deploy Profisee Platform to AKS via Azure Powershell. +[Home](https://github.com/profiseeadmin/kubernetes/tree/master/Azure-Powershell#deploy-profisee-platform-to-aks-using-powershell) for all the scripts needed to deploy Profisee Platform to AKS via Azure Powershell. ## GCP-CLI -[Home](https://github.com/profiseedev/kubernetes/tree/master/GCP-CLI#deploy-profisee-platform-on-to-google-cloud-platform-gcp-kubernetes) for all the scripts needed to deploy Profisee Platform to Google Cloud Platform (GCP) Kubernetes via the gcp cli. +[Home](https://github.com/profiseeadmin/kubernetes/tree/master/GCP-CLI#deploy-profisee-platform-on-to-google-cloud-platform-gcp-kubernetes) for all the scripts needed to deploy Profisee Platform to Google Cloud Platform (GCP) Kubernetes via the gcp cli. diff --git a/index.yaml b/index.yaml index 5fcb4681..18898c49 100644 --- a/index.yaml +++ b/index.yaml @@ -9,6 +9,6 @@ entries: name: profisee-platform type: application urls: - - https://profiseedev.github.io/kubernetes/profisee-platform-0.1.19.tgz - version: 0.1.19 + - https://profiseeadmin.github.io/kubernetes/profisee-platform-0.1.25.tgz + version: 0.1.25 generated: "2022-06-30T00:00:00.0-05:00" diff --git a/profisee-platform-0.1.19.tgz b/profisee-platform-0.1.19.tgz deleted file mode 100644 index 2ed46adc..00000000 Binary files a/profisee-platform-0.1.19.tgz and /dev/null differ diff --git a/profisee-platform-0.1.24.tgz b/profisee-platform-0.1.24.tgz new file mode 100644 index 00000000..0af87b8e Binary files /dev/null and b/profisee-platform-0.1.24.tgz differ diff --git a/profisee-platform-0.1.25.tgz b/profisee-platform-0.1.25.tgz new file mode 100644 index 00000000..5a4d9e5b Binary files /dev/null and b/profisee-platform-0.1.25.tgz differ diff --git a/profisee-platform/Chart.yaml b/profisee-platform/Chart.yaml index d52a9401..2040123f 100644 --- a/profisee-platform/Chart.yaml +++ b/profisee-platform/Chart.yaml @@ -3,4 +3,4 @@ appVersion: 1.16.0 description: A Helm chart for Profisee Platform on Kubernetes name: profisee-platform type: application -version: 0.1.19 +version: 0.1.25 diff --git a/profisee-platform/package.ps1 b/profisee-platform/package.ps1 index daaed667..3f3de3ae 100644 --- a/profisee-platform/package.ps1 +++ b/profisee-platform/package.ps1 @@ -1,6 +1,6 @@ #update chart.yaml to increment the number 0.1.x #to create the tgz - helm chart to upload -Set-Location profisee-platform +#Set-Location profisee-platform helm package . -d ..\ #now upload the in profisee-platform-x.x.x.tgz to github site diff --git a/profisee-platform/templates/azuresecretproviderclass-profisee.yaml b/profisee-platform/templates/azuresecretproviderclass-profisee.yaml index 16db5f5d..3ee7ade7 100644 --- a/profisee-platform/templates/azuresecretproviderclass-profisee.yaml +++ b/profisee-platform/templates/azuresecretproviderclass-profisee.yaml @@ -1,5 +1,5 @@ {{- if .Values.cloud.azure.useKeyVault -}} -apiVersion: secrets-store.csi.x-k8s.io/v1alpha1 +apiVersion: secrets-store.csi.x-k8s.io/v1 kind: SecretProviderClass metadata: name: azure-kvname @@ -59,4 +59,4 @@ spec: resourceGroup: {{.Values.cloud.azure.keyVault.resourceGroup }} subscriptionId: {{.Values.cloud.azure.keyVault.subscriptionId }} tenantId: {{.Values.cloud.azure.keyVault.tenantId }} -{{- end }} \ No newline at end of file +{{- end }} diff --git a/profisee-platform/templates/configmap-profisee.yaml b/profisee-platform/templates/configmap-profisee.yaml index de5b31d0..7f7b7a3b 100644 --- a/profisee-platform/templates/configmap-profisee.yaml +++ b/profisee-platform/templates/configmap-profisee.yaml @@ -25,4 +25,4 @@ data: ProfiseeOidcFirstNameClaim: {{.Values.profiseeRunTime.oidc.firstNameClaim|quote}} ProfiseeOidcLastNameClaim: {{.Values.profiseeRunTime.oidc.lastNameClaim|quote}} ProfiseeOidcEmailClaim: {{.Values.profiseeRunTime.oidc.emailClaim|quote}} - COMPlus_gcServer: '0 /m' \ No newline at end of file + ProfiseeOidcGroupsClaim: {{.Values.profiseeRunTime.oidc.groupsClaim|quote}} diff --git a/profisee-platform/templates/deployment-keyvault.yaml b/profisee-platform/templates/deployment-keyvault.yaml index 8164ee6d..179ba524 100644 --- a/profisee-platform/templates/deployment-keyvault.yaml +++ b/profisee-platform/templates/deployment-keyvault.yaml @@ -19,7 +19,7 @@ spec: "kubernetes.io/os": linux containers: - name: profisee-keyvault - image: docker.io/library/alpine:3.7 + image: docker.io/library/alpine:latest imagePullPolicy: Always command: - /bin/sh diff --git a/profisee-platform/templates/secret-purview.yaml b/profisee-platform/templates/secret-purview.yaml index 1eb87ffe..2009a38c 100644 --- a/profisee-platform/templates/secret-purview.yaml +++ b/profisee-platform/templates/secret-purview.yaml @@ -5,8 +5,9 @@ type: Opaque metadata: name: profisee-purview data: - ProfiseePurviewUrl: {{.Values.cloud.azure.purview.url | b64enc | quote}} ProfiseePurviewTenantId: {{.Values.cloud.azure.purview.tenantId | b64enc | quote}} + ProfiseePurviewUrl: {{.Values.cloud.azure.purview.url | b64enc | quote}} + ProfiseePurviewCollectionId: {{.Values.cloud.azure.purview.collectionId | b64enc | quote}} ProfiseePurviewClientId: {{.Values.cloud.azure.purview.clientId | b64enc | quote}} ProfiseePurviewClientSecret: {{.Values.cloud.azure.purview.clientSecret | b64enc | quote}} {{- end }} diff --git a/profisee-platform/templates/statefullset-profisee.yaml b/profisee-platform/templates/statefullset-profisee.yaml index 5311e67a..03816505 100644 --- a/profisee-platform/templates/statefullset-profisee.yaml +++ b/profisee-platform/templates/statefullset-profisee.yaml @@ -21,7 +21,7 @@ spec: spec: terminationGracePeriodSeconds: 60 nodeSelector: - "kubernetes.io/os": windows + "kubernetes.io/os": windows volumes: - name: data-volume projected: @@ -32,7 +32,7 @@ spec: name: profisee-oidcproviders - name: initscripts secret: - secretName: profisee-initscripts + secretName: profisee-initscripts {{- if .Values.cloud.azure.isProvider }} - name: fileshare csi: @@ -59,13 +59,13 @@ spec: containers: - name: profisee image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag }}" - imagePullPolicy: Always + imagePullPolicy: Always livenessProbe: exec: command: - powershell - >- - if((Get-Service profisee).Status -eq 'Running'){return + if((Get-Service profisee).Status -ne 'Stopped'){return 0}else{throw 'Profisee service is down'} initialDelaySeconds: 600 timeoutSeconds: 5 @@ -128,6 +128,11 @@ spec: secretKeyRef: name: profisee-purview key: ProfiseePurviewUrl + - name: ProfiseePurviewCollectionId + valueFrom: + secretKeyRef: + name: profisee-purview + key: ProfiseePurviewCollectionId - name: ProfiseePurviewTenantId valueFrom: secretKeyRef: diff --git a/profisee-platform/values.yaml b/profisee-platform/values.yaml index f24f355d..2a8158e5 100644 --- a/profisee-platform/values.yaml +++ b/profisee-platform/values.yaml @@ -28,6 +28,7 @@ profiseeRunTime: firstNameClaim: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/givenname" lastNameClaim: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/surname" emailClaim: "http://schemas.xmlsoap.org/ws/2005/05/identity/claims/name" + groupsClaim: "groups" clusterNodeCount: 1 clusterNode: limits: @@ -84,11 +85,11 @@ cloud: name: "" clientId: "" purview: - tenantId: "$AZURETENANTID" - clientId: "$CLIENTID" - clientSecret: "$OIDCCLIENTSECRET" - instanceName: "$PURVIEWINSTANCENAME" - baseUrl: "$PURVIEWBASEURL" + tenantId: "$PURVIEWTENANTID" + url: "$PURVIEWURL" + collectionId: "$PURVIEWCOLLECTIONID" + clientId: "$PURVIEWCLIENTID" + clientSecret: "$PURVIEWCLIENTSECRET" aws: isProvider: false ebsVolumeId: ""