Ejemplo n.º 1
0
        protected async Task CreateAzureResourcesAsync(
            CancellationToken cancellationToken = default
            )
        {
            // Create Virtual Network
            NetworkSecurityGroupInner networkSecurityGroup;
            //RouteTableInner routeTable;
            VirtualNetworkInner virtualNetwork;
            SubnetInner         virtualNetworkAksSubnet;

            //PublicIPAddressInner publicIPAddress;
            //NetworkInterfaceInner networkInterface;

            networkSecurityGroup = await _networkManagementClient
                                   .CreateNetworkSecurityGroupAsync(
                _resourceGroup,
                _networkSecurityGroupName,
                _defaultTagsDict,
                cancellationToken
                );

            //routeTable = _networkManagementClient
            //    .CreateRouteTableAsync(
            //        _resourceGroup,
            //        _routTableName,
            //        networkInterfacePrivateIPAddress,
            //        _defaultTagsDict,
            //        cancellationToken
            //    ).Result;

            virtualNetwork = await _networkManagementClient
                             .CreateVirtualNetworkAsync(
                _resourceGroup,
                networkSecurityGroup,
                _virtualNetworkName,
                null,
                _defaultTagsDict,
                cancellationToken
                );

            virtualNetworkAksSubnet = _networkManagementClient.GetAksSubnet(virtualNetwork);

            //publicIPAddress = _networkManagementClient
            //    .CreatePublicIPAddressAsync(
            //        _resourceGroup,
            //        _publicIPAddressName,
            //        _domainNameLabel,
            //        _defaultTagsDict,
            //        cancellationToken
            //    )
            //    .Result;

            //networkInterface = _networkManagementClient
            //    .CreateNetworkInterfaceAsync(
            //        _resourceGroup,
            //        networkSecurityGroup,
            //        virtualNetworkAksSubnet,
            //        _networkInterfaceName,
            //        networkInterfacePrivateIPAddress,
            //        _defaultTagsDict,
            //        cancellationToken
            //    )
            //    .Result;

            // Create Azure KeyVault
            VaultInner keyVault;

            var keyVaultParameters = _keyVaultManagementClient
                                     .GetCreationParameters(
                _authConf.TenantId,
                _resourceGroup,
                _applicationsManager.GetServiceApplicationSP(),
                _owner
                );

            keyVault = await _keyVaultManagementClient
                       .CreateAsync(
                _resourceGroup,
                _keyVaultName,
                keyVaultParameters,
                cancellationToken
                );

            // Add certificates to KeyVault
            var keyVaultAuthenticationCallback = new IIoTKeyVaultClient.AuthenticationCallback(
                async(authority, resource, scope) => {
                // Fetch AccessToken from cache.
                var authenticationResult = await _authenticationManager
                                           .AcquireKeyVaultAuthenticationResultAsync(cancellationToken);

                return(authenticationResult.AccessToken);
            }
                );

            using (var iiotKeyVaultClient = new IIoTKeyVaultClient(keyVaultAuthenticationCallback, keyVault)) {
                await iiotKeyVaultClient.CreateCertificateAsync(
                    IIoTKeyVaultClient.WEB_APP_CERT_NAME,
                    kWEB_APP_CN,
                    _defaultTagsDict,
                    cancellationToken
                    );

                _webAppX509Certificate = await iiotKeyVaultClient.GetSecretAsync(
                    IIoTKeyVaultClient.WEB_APP_CERT_NAME,
                    cancellationToken
                    );

                await iiotKeyVaultClient.CreateCertificateAsync(
                    IIoTKeyVaultClient.AKS_CLUSTER_CERT_NAME,
                    kAKS_CLUSTER_CN,
                    _defaultTagsDict,
                    cancellationToken
                    );

                _aksClusterX509Certificate = await iiotKeyVaultClient.GetCertificateAsync(
                    IIoTKeyVaultClient.AKS_CLUSTER_CERT_NAME,
                    cancellationToken
                    );
            }

            // Create Operational Insights workspace.
            var operationalInsightsWorkspaceCreationTask = _operationalInsightsManagementClient
                                                           .CreateOperationalInsightsWorkspaceAsync(
                _resourceGroup,
                _operationalInsightsWorkspaceName,
                _defaultTagsDict,
                cancellationToken
                );

            // Create Application Insights components.
            var applicationInsightsComponentCreationTask = _applicationInsightsManagementClient
                                                           .CreateApplicationInsightsComponentAsync(
                _resourceGroup,
                _applicationInsightsName,
                _defaultTagsDict,
                cancellationToken
                );

            // Create AKS cluster
            var operationalInsightsWorkspace = operationalInsightsWorkspaceCreationTask.Result;

            var clusterDefinition = _aksManagementClient.GetClusterDefinition(
                _resourceGroup,
                _applicationsManager.GetAKSApplication(),
                _applicationsManager.GetAKSApplicationRbacSecret(),
                _aksClusterName,
                _aksClusterX509Certificate,
                virtualNetworkAksSubnet,
                operationalInsightsWorkspace,
                _defaultTagsDict
                );

            var aksClusterCreationTask = _aksManagementClient
                                         .CreateClusterAsync(
                _resourceGroup,
                _aksClusterName,
                clusterDefinition,
                cancellationToken
                );

            // Create Storage Account
            StorageAccountInner storageAccount;
            string storageAccountConectionString;

            storageAccount = await _storageManagementClient
                             .CreateStorageAccountAsync(
                _resourceGroup,
                _storageAccountName,
                _defaultTagsDict,
                cancellationToken
                );

            storageAccountConectionString = await _storageManagementClient
                                            .GetStorageAccountConectionStringAsync(
                _resourceGroup,
                storageAccount,
                cancellationToken
                );

            await _storageManagementClient
            .CreateBlobContainerAsync(
                _resourceGroup,
                storageAccount,
                StorageMgmtClient.STORAGE_ACCOUNT_IOT_HUB_CONTAINER_NAME,
                PublicAccess.None,
                _defaultTagsDict,
                cancellationToken
                );

            // Create IoT Hub
            IotHubDescription iotHub;

            iotHub = await _iotHubManagementClient
                     .CreateIotHubAsync(
                _resourceGroup,
                _iotHubName,
                IotHubMgmtClient.IOT_HUB_EVENT_HUB_PARTITIONS_COUNT,
                storageAccountConectionString,
                StorageMgmtClient.STORAGE_ACCOUNT_IOT_HUB_CONTAINER_NAME,
                _defaultTagsDict,
                cancellationToken
                );

            await _iotHubManagementClient
            .CreateEventHubConsumerGroupAsync(
                _resourceGroup,
                iotHub,
                IotHubMgmtClient.IOT_HUB_EVENT_HUB_ONBOARDING_ENDPOINT_NAME,
                IotHubMgmtClient.IOT_HUB_EVENT_HUB_ONBOARDING_CONSUMER_GROUP_NAME,
                cancellationToken
                );

            // Create CosmosDB account
            var cosmosDBAccountCreationTask = _cosmosDBManagementClient
                                              .CreateDatabaseAccountAsync(
                _resourceGroup,
                _cosmosDBAccountName,
                _defaultTagsDict,
                cancellationToken
                );

            // Create Service Bus Namespace
            var serviceBusNamespaceCreationTask = _serviceBusManagementClient
                                                  .CreateServiceBusNamespaceAsync(
                _resourceGroup,
                _serviceBusNamespaceName,
                _defaultTagsDict,
                cancellationToken
                );

            // Create Azure Event Hub Namespace and Azure Event Hub
            EHNamespaceInner eventHubNamespace;
            EventhubInner    eventHub;

            // Create Azure Event Hub Namespace
            eventHubNamespace = await _eventHubManagementClient
                                .CreateEventHubNamespaceAsync(
                _resourceGroup,
                _eventHubNamespaceName,
                _defaultTagsDict,
                cancellationToken
                );

            // Create Azure Event Hub
            eventHub = await _eventHubManagementClient
                       .CreateEventHubAsync(
                _resourceGroup,
                eventHubNamespace,
                _eventHubName,
                _defaultTagsDict,
                cancellationToken
                );

            // Create AppService Plan to host the Application Gateway Web App
            var appServicePlan = await _webSiteManagementClient
                                 .CreateAppServicePlanAsync(
                _resourceGroup,
                _appServicePlanName,
                _defaultTagsDict,
                cancellationToken
                );

            // This will point to PublicIP address of Ingress.
            var emptyRemoteEndpoint = "";

            var webSiteCreationTask = _webSiteManagementClient
                                      .CreateSiteAsync(
                _resourceGroup,
                appServicePlan,
                _azureWebsiteName,
                emptyRemoteEndpoint,
                _webAppX509Certificate,
                _defaultTagsDict,
                cancellationToken
                );

            // SignalR
            var signalRCreationTask = _signalRManagementClient
                                      .CreateAsync(
                _resourceGroup,
                _signalRName,
                _defaultTagsDict,
                cancellationToken
                );

            // Collect all necessary environment variables for IIoT services.
            var iotHubOwnerConnectionString = await _iotHubManagementClient
                                              .GetIotHubConnectionStringAsync(
                _resourceGroup,
                iotHub,
                IotHubMgmtClient.IOT_HUB_OWNER_KEY_NAME,
                cancellationToken
                );

            var cosmosDBAccount = cosmosDBAccountCreationTask.Result;
            var cosmosDBAccountConnectionString = await _cosmosDBManagementClient
                                                  .GetCosmosDBAccountConnectionStringAsync(
                _resourceGroup,
                cosmosDBAccount,
                cancellationToken
                );

            var eventHubNamespaceConnectionString = await _eventHubManagementClient
                                                    .GetEventHubNamespaceConnectionStringAsync(
                _resourceGroup,
                eventHubNamespace,
                cancellationToken
                );

            var serviceBusNamespace = serviceBusNamespaceCreationTask.Result;
            var serviceBusNamespaceConnectionString = await _serviceBusManagementClient
                                                      .GetServiceBusNamespaceConnectionStringAsync(
                _resourceGroup,
                serviceBusNamespace,
                cancellationToken
                );

            var storageAccountKey = await _storageManagementClient
                                    .GetStorageAccountKeyAsync(
                _resourceGroup,
                storageAccount,
                cancellationToken
                );

            var signalR = signalRCreationTask.Result;
            var signalRConnectionString = await _signalRManagementClient
                                          .GetConnectionStringAsync(
                _resourceGroup,
                signalR,
                cancellationToken
                );

            var applicationInsightsComponent = applicationInsightsComponentCreationTask.Result;
            var webSite = webSiteCreationTask.Result;

            var iiotEnvironment = new IIoTEnvironment(
                _authConf.AzureEnvironment,
                _authConf.TenantId,
                iotHub,
                iotHubOwnerConnectionString,
                IotHubMgmtClient.IOT_HUB_EVENT_HUB_ONBOARDING_CONSUMER_GROUP_NAME,
                IotHubMgmtClient.IOT_HUB_EVENT_HUB_PARTITIONS_COUNT,
                cosmosDBAccountConnectionString,
                storageAccount,
                storageAccountKey,
                eventHub,
                eventHubNamespaceConnectionString,
                serviceBusNamespaceConnectionString,
                signalRConnectionString,
                keyVault,
                operationalInsightsWorkspace,
                applicationInsightsComponent,
                webSite,
                _applicationsManager.GetServiceApplication(),
                _applicationsManager.GetClientApplication()
                );

            // Deploy IIoT services to AKS cluster

            // Generate default SSL certificate for NGINX Ingress
            var webAppPemCertificate = X509CertificateHelper.GetPemCertificate(_webAppX509Certificate);
            //var webAppPemPublicKey = X509CertificateHelper.GetPemPublicKey(webAppX509Certificate);
            var webAppPemPrivateKey = X509CertificateHelper.GetPemPrivateKey(_webAppX509Certificate);

            // Get KubeConfig
            var aksCluster    = aksClusterCreationTask.Result;
            var aksKubeConfig = await _aksManagementClient
                                .GetClusterAdminCredentialsAsync(
                _resourceGroup,
                aksCluster.Name,
                cancellationToken
                );

            var iiotK8SClient = new IIoTK8SClient(aksKubeConfig);

            // industrial-iot namespace
            iiotK8SClient.CreateIIoTNamespaceAsync(cancellationToken).Wait();
            iiotK8SClient.SetupIIoTServiceAccountAsync(cancellationToken).Wait();
            iiotK8SClient.CreateIIoTEnvSecretAsync(iiotEnvironment.Dict, cancellationToken).Wait();
            iiotK8SClient.DeployIIoTServicesAsync(cancellationToken).Wait();

            // We will add default SSL certificate for Ingress
            // NGINX controler to industrial-iot namespace
            iiotK8SClient
            .CreateNGINXDefaultSSLCertificateSecretAsync(
                webAppPemCertificate,
                webAppPemPrivateKey,
                cancellationToken
                )
            .Wait();

            // ingress-nginx namespace
            iiotK8SClient.CreateNGINXNamespaceAsync(cancellationToken).Wait();
            iiotK8SClient.SetupNGINXServiceAccountAsync(cancellationToken).Wait();
            iiotK8SClient.DeployNGINXIngressControllerAsync(cancellationToken).Wait();

            // After we have NGINX Ingress controller we can create Ingress
            // for our Industrial IoT services and wait for IP address of
            // its LoadBalancer.
            var iiotIngress = await iiotK8SClient.CreateIIoTIngressAsync(cancellationToken);

            var iiotIngressIPAddresses = await iiotK8SClient.WaitForIngressIPAsync(iiotIngress, cancellationToken);

            var iiotIngressIPAdress = iiotIngressIPAddresses.FirstOrDefault().Ip;

            // Update remote endpoint and certificate thumbprint application settings
            // of App Servise.
            var iiotIngressRemoteEndpoint = $"https://{iiotIngressIPAdress}";
            await _webSiteManagementClient
            .UpdateSiteApplicationSettingsAsync(
                _resourceGroup,
                webSite,
                iiotIngressRemoteEndpoint,
                _webAppX509Certificate,
                cancellationToken
                );

            // Deploy reverse proxy to App Service. It will consume values of remote
            // endpoint and certificate thumbprint application settings of App Service.
            var proxySiteSourceControl = await _webSiteManagementClient
                                         .DeployProxyAsync(
                _resourceGroup,
                webSite,
                _defaultTagsDict,
                cancellationToken
                );

            // After we have deployed proxy to App Service, we will update
            // client application to have redirect URIs for App Service.
            // This will be performed in UpdateClientApplicationRedirectUrisAsync() call.
            _applicationURL = webSite.DefaultHostName;

            // Check if we want to save environment to .env file
            try {
                if (_configurationProvider.IfSaveEnvFile())
                {
                    iiotEnvironment.WriteToFile(ENV_FILE_PATH);
                }
            }
            catch (Exception) {
                Log.Warning("Skipping environment file generation.");
            }
        }