public Task <KubernetesClusterReportCard> UpdateKubernetesCluster(KubernetesCluster cluster)
 {
     if (string.IsNullOrEmpty(cluster.Name))
     {
         throw new ArgumentException("Cluster must have a name to update - did you mean to add instead?");
     }
     return(PutAsync <KubernetesClusterReportCard>($"clusters/{cluster.Name}", cluster, SOC));
 }
        public void GetIngresses_WithInvalidLineInData_ShouldReturnExpectedValidResponses()
        {
            _mockShell.Setup(mock => mock.Execute(Kubectl, GetIngress)).Returns(BadExampleResponse);
            var cluster = new KubernetesCluster(_mockShell.Object);

            var responses = cluster.GetIngresses();

            Assert.Equal(2, responses.Count());
        }
        public void GetIngresses_WhenAllLinesAreValid_ShouldReturnExpectedValidResponses()
        {
            _mockShell.Setup(mock => mock.Execute(Kubectl, GetIngress)).Returns(ExampleResponse);
            var cluster = new KubernetesCluster(_mockShell.Object);

            var responses = cluster.GetIngresses();

            Assert.Equal(3, responses.Count());
        }
        public void GetIngresses_ShouldExecuteKubectlCommand()
        {
            _mockShell.Setup(mock => mock.Execute(Kubectl, GetIngress)).Returns("");
            var cluster = new KubernetesCluster(_mockShell.Object);

            cluster.GetIngresses();

            _mockShell.Verify(mock => mock.Execute(Kubectl, GetIngress), Times.Once);
        }
        void WriteTargetCreationServiceMessage(KubernetesCluster cluster, TargetMatchResult matchResult, TargetDiscoveryScope scope)
        {
            var parameters = new Dictionary <string, string> {
                { "name", cluster.Name },
                { "clusterName", cluster.ClusterName },
                { "clusterUrl", cluster.Endpoint },
                { "clusterResourceGroup", cluster.ResourceGroupName },
                { "clusterAdminLogin", null },
                { "namespace", null },
                { "skipTlsVerification", bool.TrueString },
                { "octopusDefaultWorkerPoolIdOrName", cluster.WorkerPool ?? scope.WorkerPoolId },
                { "octopusAccountIdOrName", cluster.AccountId },
                { "octopusClientCertificateIdOrName", null },
                { "octopusServerCertificateIdOrName", null },
                { "octopusRoles", matchResult.Role },
                { "healthCheckContainerImageFeedIdOrName", null },
                { "healthCheckContainerImage", null },
                { "updateIfExisting", bool.TrueString },
                { "isDynamic", bool.TrueString },
                { "clusterProject", null },
                { "clusterRegion", null },
                { "clusterZone", null },
                { "clusterImpersonateServiceAccount", null },
                { "clusterServiceAccountEmails", null },
                { "clusterUseVmServiceAccount", null },
                { "awsUseWorkerCredentials", cluster.AwsUseWorkerCredentials.ToString() },
                { "awsAssumeRole", (cluster.AwsAssumeRole != null).ToString() },
                { "awsAssumeRoleArn", cluster.AwsAssumeRole?.Arn },
                { "awsAssumeRoleSession", cluster.AwsAssumeRole?.Session },
                { "awsAssumeRoleSessionDurationSeconds", cluster.AwsAssumeRole?.SessionDuration?.ToString() },
                { "awsAssumeRoleExternalId", cluster.AwsAssumeRole?.ExternalId }
            };

            var serviceMessage = new ServiceMessage(
                CreateKubernetesTargetServiceMessageName,
                parameters.Where(p => p.Value != null)
                .ToDictionary(p => p.Key, p => p.Value));

            log.WriteServiceMessage(serviceMessage);
        }
Exemple #6
0
        public async Task CreateKubernetesCluster()
        {
            using (var session = await StartSession())
            {
                var client = await session.GetClient(ApiPortals.SOC);

                var newCluster = new KubernetesCluster()
                {
                    AuthenticationMode = "BasicAuth",
                    GatewayHostnames   = "K8SPUBLIC787K01",
                    CloudId            = 1,
                    Name     = "k8spublic",
                    Url      = "https://K8SPUBLIC787K01:6443",
                    Username = "******",
                    Password = "******"
                };
                var addition = client.AddKubernetesCluster(newCluster).Result;

                var addedCluster = client.GetKubernetesCluser("k8spublic").Result;
                Assert.Equal(newCluster.Name, addedCluster.Name);
            }
        }
        public override IEnumerable <KubernetesCluster> DiscoverClusters(string contextJson)
        {
            if (!TryGetDiscoveryContext <AccountAuthenticationDetails <ServicePrincipalAccount> >(contextJson, out var authenticationDetails, out _))
            {
                return(Enumerable.Empty <KubernetesCluster>());
            }

            var account = authenticationDetails.AccountDetails;

            Log.Verbose("Looking for Kubernetes clusters in Azure using:");
            Log.Verbose($"  Subscription ID: {account.SubscriptionNumber}");
            Log.Verbose($"  Tenant ID: {account.TenantId}");
            Log.Verbose($"  Client ID: {account.ClientId}");
            var azureClient = account.CreateAzureClient();

            return(azureClient.KubernetesClusters.List()
                   .Select(c => KubernetesCluster.CreateForAks(
                               $"aks/{account.SubscriptionNumber}/{c.ResourceGroupName}/{c.Name}",
                               c.Name,
                               c.ResourceGroupName,
                               authenticationDetails.AccountId,
                               c.Tags.ToTargetTags())));
        }
Exemple #8
0
    public WorkloadStack()
    {
        var baseStack   = new StackReference("evgenyb/iac-base/lab");
        var config      = new Config();
        var environment = Deployment.Instance.StackName;

        // Create an Azure Resource Group
        var resourceGroup = new ResourceGroup("rg", new ResourceGroupArgs
        {
            Name = NamingConvention.GetResourceGroupName(environment),
            Tags =
            {
                { "owner",       Constants.TeamPlatform },
                { "environment", environment            }
            }
        });

        var vnet = new VirtualNetwork("vnet", new VirtualNetworkArgs
        {
            Name = NamingConvention.GetVNetName(environment),
            ResourceGroupName = resourceGroup.Name,
            AddressSpaces     =
            {
                config.Require("vnet.addressSpaces")
            },
            Tags =
            {
                { "owner",       Constants.TeamPlatform },
                { "environment", environment            }
            }
        });

        // Create a Subnet for the cluster
        var aksSubnet = new Subnet("aks-net", new SubnetArgs
        {
            Name = "aks-net",
            ResourceGroupName  = resourceGroup.Name,
            VirtualNetworkName = vnet.Name,
            AddressPrefixes    =
            {
                config.Require("vnet.subnets.aks.addressPrefixes")
            },
        });

        var agwSubnet = new Subnet("agw-net", new SubnetArgs
        {
            Name = "agw-net",
            ResourceGroupName  = resourceGroup.Name,
            VirtualNetworkName = vnet.Name,
            AddressPrefixes    =
            {
                config.Require("vnet.subnets.agw.addressPrefixes")
            },
        });

        // var agwName = NamingConvention.GetAGWName("api", environment);
        // var agwPublicIp = new PublicIp("agw-api-pip", new PublicIpArgs
        // {
        //     Name = NamingConvention.GetPublicIpName("agw-api", environment),
        //     ResourceGroupName = resourceGroup.Name,
        //     Sku = "Standard",
        //     AllocationMethod = "Static",
        //     DomainNameLabel = agwName
        // });
        //
        // var agwMI = new UserAssignedIdentity("agw-mi", new UserAssignedIdentityArgs
        // {
        //     Name = NamingConvention.GetManagedIdentityName("agw", environment),
        //     ResourceGroupName = resourceGroup.Name
        // });
        //
        // var apiAgw = new ApplicationGateway("agw-api", new ApplicationGatewayArgs
        // {
        //     Name = agwName,
        //     ResourceGroupName = resourceGroup.Name,
        //     Identity = new ApplicationGatewayIdentityArgs
        //     {
        //         Type = "UserAssigned",
        //         IdentityIds = agwMI.Id
        //     },
        //     Sku = new ApplicationGatewaySkuArgs
        //     {
        //         Name = "WAF_v2",
        //         Tier = "WAF_v2",
        //         Capacity = 1
        //     },
        //     SslCertificates = new []
        //     {
        //         new ApplicationGatewaySslCertificateArgs
        //         {
        //             Name = "gateway-listener",
        //             KeyVaultSecretId = config.Require("keyVaultSecretId")
        //         }
        //     },
        //     FrontendPorts = new []
        //     {
        //         new ApplicationGatewayFrontendPortArgs
        //         {
        //             Name = "port443",
        //             Port = 443
        //         },
        //         new ApplicationGatewayFrontendPortArgs
        //         {
        //             Name = "port80",
        //             Port = 80
        //         }
        //     },
        //     GatewayIpConfigurations = new []
        //     {
        //         new ApplicationGatewayGatewayIpConfigurationArgs
        //         {
        //             Name = "appGatewayIpConfig",
        //             SubnetId = agwSubnet.Id
        //         }
        //     },
        //     FrontendIpConfigurations = new []
        //     {
        //         new ApplicationGatewayFrontendIpConfigurationArgs
        //         {
        //             Name = "appGatewayFrontendIP",
        //             PublicIpAddressId = agwPublicIp.Id
        //         }
        //     },
        //     HttpListeners = new []
        //     {
        //         new ApplicationGatewayHttpListenerArgs
        //         {
        //             Name = "gateway-listener",
        //             FrontendIpConfigurationName = "appGatewayFrontendIP",
        //             FrontendPortName = "port443",
        //             Protocol = "Https",
        //             HostName = "iac-lab-api.iac-labs.com",
        //             RequireSni = true,
        //             SslCertificateName = "gateway-listener"
        //         },
        //         new ApplicationGatewayHttpListenerArgs
        //         {
        //             Name = "management-listener",
        //             FrontendIpConfigurationName = "appGatewayFrontendIP",
        //             FrontendPortName = "port443",
        //             Protocol = "Https",
        //             HostName = "iac-lab-management.iac-labs.com",
        //             RequireSni = true,
        //             SslCertificateName = "gateway-listener"
        //         },
        //         new ApplicationGatewayHttpListenerArgs
        //         {
        //             Name = "portal-listener",
        //             FrontendIpConfigurationName = "appGatewayFrontendIP",
        //             FrontendPortName = "port443",
        //             Protocol = "Https",
        //             HostName = "iac-lab-portal.iac-labs.com",
        //             RequireSni = true,
        //             SslCertificateName = "gateway-listener"
        //         }
        //     },
        //     BackendAddressPools = new[]
        //     {
        //         new ApplicationGatewayBackendAddressPoolArgs
        //         {
        //             Name = "apim-backend-pool",
        //             IpAddresses = config.RequireSecret("apim.backend.ip")
        //         }
        //     },
        //     Probes = new[]
        //     {
        //         new ApplicationGatewayProbeArgs
        //         {
        //             Name = "apim-probe",
        //             Protocol = "Https",
        //             Path = "/status-0123456789abcdef",
        //             Host = "iac-lab-api.iac-labs.com",
        //             Interval = 30,
        //             Timeout = 120,
        //             UnhealthyThreshold = 8,
        //             PickHostNameFromBackendHttpSettings = false,
        //             MinimumServers = 0
        //         }
        //     },
        //     BackendHttpSettings = new []
        //     {
        //         new ApplicationGatewayBackendHttpSettingArgs
        //         {
        //             Name = "apim-settings",
        //             Port = 443,
        //             Protocol = "Https",
        //             CookieBasedAffinity = "Disabled",
        //             PickHostNameFromBackendAddress = false,
        //             RequestTimeout = 30,
        //             ProbeName = "apim-probe"
        //         }
        //     },
        //     RequestRoutingRules = new[]
        //     {
        //         new ApplicationGatewayRequestRoutingRuleArgs
        //         {
        //             Name = "gateway",
        //             RuleType = "Basic",
        //             HttpListenerName = "gateway-listener",
        //             BackendAddressPoolName = "apim-backend-pool",
        //             BackendHttpSettingsName = "apim-settings"
        //         },
        //         new ApplicationGatewayRequestRoutingRuleArgs
        //         {
        //             Name = "management",
        //             RuleType = "Basic",
        //             HttpListenerName = "management-listener",
        //             BackendAddressPoolName = "apim-backend-pool",
        //             BackendHttpSettingsName = "apim-settings"
        //         },
        //         new ApplicationGatewayRequestRoutingRuleArgs
        //         {
        //             Name = "portal",
        //             RuleType = "Basic",
        //             HttpListenerName = "portal-listener",
        //             BackendAddressPoolName = "apim-backend-pool",
        //             BackendHttpSettingsName = "apim-settings"
        //         },
        //     }
        // });
        //
        // var appInsight = new Insights("ai", new InsightsArgs
        // {
        //     Name = NamingConvention.GetAppInsightName(environment),
        //     ResourceGroupName = resourceGroup.Name,
        //     Location = resourceGroup.Location,
        //     ApplicationType = "web",
        //
        // });

        // var la = new AnalyticsWorkspace("la", new AnalyticsWorkspaceArgs
        // {
        //     Name = NamingConvention.GetLogAnalyticsName(environment),
        //     ResourceGroupName = resourceGroup.Name,
        //     Location = resourceGroup.Location,
        //     Sku = "PerGB2018"
        // });

        var aksEgressPublicIp = new PublicIp("aks-egress-pip", new PublicIpArgs
        {
            Name = NamingConvention.GetPublicIpName("aks-egress", environment),
            ResourceGroupName = resourceGroup.Name,
            Sku = "Standard",
            AllocationMethod = "Static"
        });

        var logAnalyticsWorkspaceId = baseStack.RequireOutput("LogAnalyticsWorkspaceId").Apply(x => x.ToString());
        var aks = new KubernetesCluster("aks", new KubernetesClusterArgs
        {
            Name = NamingConvention.GetAksName(environment),
            ResourceGroupName = resourceGroup.Name,
            Location          = resourceGroup.Location,
            Identity          = new KubernetesClusterIdentityArgs
            {
                Type = "SystemAssigned"
            },
            DefaultNodePool = new KubernetesClusterDefaultNodePoolArgs
            {
                Name         = "aksagentpool",
                NodeCount    = 1,
                VmSize       = "Standard_B2s",
                OsDiskSizeGb = 30,
                VnetSubnetId = aksSubnet.Id
            },
            DnsPrefix = "iacpulumiaks",
            RoleBasedAccessControl = new KubernetesClusterRoleBasedAccessControlArgs
            {
                Enabled = true,
                AzureActiveDirectory = new KubernetesClusterRoleBasedAccessControlAzureActiveDirectoryArgs
                {
                    AdminGroupObjectIds = config.RequireSecret("teamPlatformAADId"),
                    TenantId            = config.RequireSecret("tenantId"),
                    Managed             = true
                }
            },
            NetworkProfile = new KubernetesClusterNetworkProfileArgs
            {
                NetworkPlugin       = "azure",
                NetworkPolicy       = "calico",
                DnsServiceIp        = "10.2.2.254",
                ServiceCidr         = "10.2.2.0/24",
                DockerBridgeCidr    = "172.17.0.1/16",
                LoadBalancerProfile = new KubernetesClusterNetworkProfileLoadBalancerProfileArgs
                {
                    OutboundIpAddressIds = new []
                    {
                        aksEgressPublicIp.Id
                    }
                }
            },
            AddonProfile = new KubernetesClusterAddonProfileArgs
            {
                OmsAgent = new KubernetesClusterAddonProfileOmsAgentArgs
                {
                    Enabled = true,
                    LogAnalyticsWorkspaceId = logAnalyticsWorkspaceId
                },
                KubeDashboard = new KubernetesClusterAddonProfileKubeDashboardArgs
                {
                    Enabled = false
                }
            }
        });

        var pool = new KubernetesClusterNodePool("workload-pool", new KubernetesClusterNodePoolArgs
        {
            Name = "workload",
            KubernetesClusterId = aks.Id,
            Mode         = "User",
            NodeCount    = 1,
            VmSize       = "Standard_B2s",
            OsDiskSizeGb = 30,
            VnetSubnetId = aksSubnet.Id,
            NodeLabels   =
            {
                { "disk", "ssd"      },
                { "type", "workload" }
            }
        });

        this.KubeConfig = aks.KubeConfigRaw;
    }
Exemple #9
0
    static Task <int> Main()
    {
        return(Deployment.RunAsync(() => {
            var resourceGroup = new ResourceGroup("aks-rg");

            var password = new RandomPassword("password", new RandomPasswordArgs
            {
                Length = 20,
                Special = true,
            }).Result;

            var sshPublicKey = new PrivateKey("ssh-key", new PrivateKeyArgs
            {
                Algorithm = "RSA",
                RsaBits = 4096,
            }).PublicKeyOpenssh;

            // Create the AD service principal for the K8s cluster.
            var adApp = new Application("aks");
            var adSp = new ServicePrincipal("aksSp", new ServicePrincipalArgs {
                ApplicationId = adApp.ApplicationId
            });
            var adSpPassword = new ServicePrincipalPassword("aksSpPassword", new ServicePrincipalPasswordArgs
            {
                ServicePrincipalId = adSp.Id,
                Value = password,
                EndDate = "2099-01-01T00:00:00Z",
            });

            // Create a Virtual Network for the cluster
            var vnet = new VirtualNetwork("vnet", new VirtualNetworkArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AddressSpaces = { "10.2.0.0/16" },
            });

            // Create a Subnet for the cluster
            var subnet = new Subnet("subnet", new SubnetArgs
            {
                ResourceGroupName = resourceGroup.Name,
                VirtualNetworkName = vnet.Name,
                AddressPrefix = "10.2.1.0/24",
            });

            // Now allocate an AKS cluster.
            var cluster = new KubernetesCluster("aksCluster", new KubernetesClusterArgs
            {
                ResourceGroupName = resourceGroup.Name,
                AgentPoolProfiles =
                {
                    new KubernetesClusterAgentPoolProfilesArgs
                    {
                        Name = "aksagentpool",
                        Count = 3,
                        VmSize = "Standard_B2s",
                        OsType = "Linux",
                        OsDiskSizeGb = 30,
                        VnetSubnetId = subnet.Id,
                    }
                },
                DnsPrefix = "sampleaks",
                LinuxProfile = new KubernetesClusterLinuxProfileArgs
                {
                    AdminUsername = "******",
                    SshKey = new KubernetesClusterLinuxProfileSshKeyArgs
                    {
                        KeyData = sshPublicKey,
                    },
                },
                ServicePrincipal = new KubernetesClusterServicePrincipalArgs
                {
                    ClientId = adApp.ApplicationId,
                    ClientSecret = adSpPassword.Value,
                },
                KubernetesVersion = "1.15.4",
                RoleBasedAccessControl = new KubernetesClusterRoleBasedAccessControlArgs {
                    Enabled = true
                },
                NetworkProfile = new KubernetesClusterNetworkProfileArgs
                {
                    NetworkPlugin = "azure",
                    DnsServiceIp = "10.2.2.254",
                    ServiceCidr = "10.2.2.0/24",
                    DockerBridgeCidr = "172.17.0.1/16",
                },
            });

            return new Dictionary <string, object>
            {
                { "kubeconfig", cluster.KubeConfigRaw },
            };
        }));
    }
Exemple #10
0
    static Task <int> Main()
    {
        return(Deployment.RunAsync(() => {
            var config = new Config();
            var nodeCount = config.GetInt32("nodeCount") ?? 2;
            var appReplicaCount = config.GetInt32("appReplicaCount") ?? 5;
            var domainName = config.Get("domainName");

            var cluster = new KubernetesCluster("do-cluser", new KubernetesClusterArgs {
                Region = "sfo2",
                Version = "latest",
                NodePool = new KubernetesClusterNodePoolArgs {
                    Name = "default",
                    Size = "s-2vcpu-2gb",
                    NodeCount = nodeCount
                }
            });

            var k8sProvider = new Provider("do-k8s", new ProviderArgs {
                KubeConfig = cluster.KubeConfigs.Apply(array => array[0].RawConfig)
            });

            var app = new Pulumi.Kubernetes.Apps.V1.Deployment("do-app-dep", new DeploymentArgs {
                Spec = new DeploymentSpecArgs {
                    Selector = new LabelSelectorArgs {
                        MatchLabels =
                        {
                            { "app", "app-nginx" }
                        }
                    },
                    Replicas = appReplicaCount,
                    Template = new PodTemplateSpecArgs {
                        Metadata = new ObjectMetaArgs {
                            Labels =
                            {
                                { "app", "app-nginx" }
                            }
                        },
                        Spec = new PodSpecArgs {
                            Containers = new ContainerArgs {
                                Name = "nginx",
                                Image = "nginx"
                            }
                        }
                    }
                }
            }, new CustomResourceOptions {
                Provider = k8sProvider
            });

            var appService = new Service("do-app-svc", new ServiceArgs {
                Spec = new ServiceSpecArgs {
                    Type = "LoadBalancer",
                    Selector = app.Spec.Apply(spec => spec.Template.Metadata.Labels),
                    Ports = new ServicePortArgs {
                        Port = 80
                    }
                }
            }, new CustomResourceOptions {
                Provider = k8sProvider
            });

            var ingressIp = appService.Status.Apply(status => status.LoadBalancer.Ingress[0].Ip);

            if (!string.IsNullOrWhiteSpace(domainName))
            {
                var domain = new Domain("do-domain", new DomainArgs {
                    Name = domainName,
                    IpAddress = ingressIp
                });

                var cnameRecord = new DnsRecord("do-domain-cname", new DnsRecordArgs {
                    Domain = domain.Name,
                    Type = "CNAME",
                    Name = "www",
                    Value = "@"
                });
            }

            return new Dictionary <string, object?> {
                { "ingressIp", ingressIp }
            };
        }));
    }
Exemple #11
0
    public AksStack()
    {
        var config            = new Pulumi.Config();
        var kubernetesVersion = config.Get("kubernetesVersion") ?? "1.19.3";

        var resourceGroup = new ResourceGroup("aks-rg");

        var password = new RandomPassword("password", new RandomPasswordArgs
        {
            Length  = 20,
            Special = true,
        }).Result;

        var sshPublicKey = new PrivateKey("ssh-key", new PrivateKeyArgs
        {
            Algorithm = "RSA",
            RsaBits   = 4096,
        }).PublicKeyOpenssh;

        // Create the AD service principal for the K8s cluster.
        var adApp = new Application("aks");
        var adSp  = new ServicePrincipal("aksSp", new ServicePrincipalArgs {
            ApplicationId = adApp.ApplicationId
        });
        var adSpPassword = new ServicePrincipalPassword("aksSpPassword", new ServicePrincipalPasswordArgs
        {
            ServicePrincipalId = adSp.Id,
            Value   = password,
            EndDate = "2099-01-01T00:00:00Z",
        });

        // Grant networking permissions to the SP (needed e.g. to provision Load Balancers)
        var assignment = new Assignment("role-assignment", new AssignmentArgs
        {
            PrincipalId        = adSp.Id,
            Scope              = resourceGroup.Id,
            RoleDefinitionName = "Network Contributor"
        });

        // Create a Virtual Network for the cluster
        var vnet = new VirtualNetwork("vnet", new VirtualNetworkArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AddressSpaces     = { "10.2.0.0/16" },
        });

        // Create a Subnet for the cluster
        var subnet = new Subnet("subnet", new SubnetArgs
        {
            ResourceGroupName  = resourceGroup.Name,
            VirtualNetworkName = vnet.Name,
            AddressPrefixes    = { "10.2.1.0/24" },
        });

        // Now allocate an AKS cluster.
        var cluster = new KubernetesCluster("aksCluster", new KubernetesClusterArgs
        {
            ResourceGroupName = resourceGroup.Name,
            DefaultNodePool   = new KubernetesClusterDefaultNodePoolArgs
            {
                Name         = "aksagentpool",
                NodeCount    = 3,
                VmSize       = "Standard_B2s",
                OsDiskSizeGb = 30,
                VnetSubnetId = subnet.Id,
            },
            DnsPrefix    = "aksdemo",
            LinuxProfile = new KubernetesClusterLinuxProfileArgs
            {
                AdminUsername = "******",
                SshKey        = new KubernetesClusterLinuxProfileSshKeyArgs
                {
                    KeyData = sshPublicKey,
                },
            },
            ServicePrincipal = new KubernetesClusterServicePrincipalArgs
            {
                ClientId     = adApp.ApplicationId,
                ClientSecret = adSpPassword.Value,
            },
            KubernetesVersion      = kubernetesVersion,
            RoleBasedAccessControl = new KubernetesClusterRoleBasedAccessControlArgs {
                Enabled = true
            },
            NetworkProfile = new KubernetesClusterNetworkProfileArgs
            {
                NetworkPlugin    = "azure",
                DnsServiceIp     = "10.2.2.254",
                ServiceCidr      = "10.2.2.0/24",
                DockerBridgeCidr = "172.17.0.1/16",
            },
        });

        this.KubeConfig = cluster.KubeConfigRaw;
    }
Exemple #12
0
    public AksStack()
    {
        var resourceGroup = new ResourceGroup("aks-rg");

        var randomPassword = new RandomPassword("password", new RandomPasswordArgs
        {
            Length  = 20,
            Special = true,
        }).Result;

        var sshPublicKey = new PrivateKey("ssh-key", new PrivateKeyArgs
        {
            Algorithm = "RSA",
            RsaBits   = 4096,
        }).PublicKeyOpenssh;

        // Create the AD service principal for the K8s cluster.
        var adApp = new Application("aks");
        var adSp  = new ServicePrincipal("aksSp", new ServicePrincipalArgs {
            ApplicationId = adApp.ApplicationId
        });
        var adSpPassword = new ServicePrincipalPassword("aksSpPassword", new ServicePrincipalPasswordArgs
        {
            ServicePrincipalId = adSp.Id,
            Value   = randomPassword,
            EndDate = "2099-01-01T00:00:00Z",
        });

        // Grant networking permissions to the SP (needed e.g. to provision Load Balancers).
        var assignment = new Assignment("role-assignment", new AssignmentArgs
        {
            PrincipalId        = adSp.Id,
            Scope              = resourceGroup.Id,
            RoleDefinitionName = "Network Contributor"
        });

        // Create a Virtual Network for the cluster.
        var vnet = new VirtualNetwork("vnet", new VirtualNetworkArgs
        {
            ResourceGroupName = resourceGroup.Name,
            AddressSpaces     = { "10.2.0.0/16" },
        });

        // Create a Subnet for the cluster.
        var subnet = new Subnet("subnet", new SubnetArgs
        {
            ResourceGroupName  = resourceGroup.Name,
            VirtualNetworkName = vnet.Name,
            AddressPrefix      = "10.2.1.0/24",
        });

        // Now allocate an AKS cluster.
        var cluster = new KubernetesCluster("aksCluster", new KubernetesClusterArgs
        {
            ResourceGroupName = resourceGroup.Name,
            DefaultNodePool   = new KubernetesClusterDefaultNodePoolArgs
            {
                Name         = "aksagentpool",
                NodeCount    = 3,
                VmSize       = "Standard_B2s",
                OsDiskSizeGb = 30,
                VnetSubnetId = subnet.Id
            },
            DnsPrefix    = "sampleaks",
            LinuxProfile = new KubernetesClusterLinuxProfileArgs
            {
                AdminUsername = "******",
                SshKey        = new KubernetesClusterLinuxProfileSshKeyArgs
                {
                    KeyData = sshPublicKey,
                },
            },
            ServicePrincipal = new KubernetesClusterServicePrincipalArgs
            {
                ClientId     = adApp.ApplicationId,
                ClientSecret = adSpPassword.Value,
            },
            KubernetesVersion      = "1.16.9",
            RoleBasedAccessControl = new KubernetesClusterRoleBasedAccessControlArgs {
                Enabled = true
            },
            NetworkProfile = new KubernetesClusterNetworkProfileArgs
            {
                NetworkPlugin    = "azure",
                DnsServiceIp     = "10.2.2.254",
                ServiceCidr      = "10.2.2.0/24",
                DockerBridgeCidr = "172.17.0.1/16",
            },
        });

        // Create a k8s provider pointing to the kubeconfig.
        var k8sProvider = new Pulumi.Kubernetes.Provider("k8s", new Pulumi.Kubernetes.ProviderArgs
        {
            KubeConfig = cluster.KubeConfigRaw
        });

        var customResourceOptions = new CustomResourceOptions
        {
            Provider = k8sProvider
        };

        // Create a Container Registry.
        var registry = new Registry("acregistry", new RegistryArgs
        {
            ResourceGroupName = resourceGroup.Name,
            Sku          = "Basic",
            AdminEnabled = true
        });

        // Build & push the sample application to the registry.
        var applicationName = "sample-application";
        var imageName       = registry.LoginServer.Apply(value => $"{value}/{applicationName}");

        var image = new Image(applicationName, new ImageArgs
        {
            Build    = "./SampleApplication",
            Registry = new ImageRegistry
            {
                Server   = registry.LoginServer,
                Username = registry.AdminUsername,
                Password = registry.AdminPassword
            },
            ImageName = imageName
        }, new ComponentResourceOptions
        {
            Provider = k8sProvider
        });

        // Create a k8s secret for use when pulling images from the container registry when deploying the sample application.
        var dockerCfg = Output.All <string>(registry.LoginServer, registry.AdminUsername, registry.AdminPassword).Apply(
            values =>
        {
            var r        = new Dictionary <string, object>();
            var server   = values[0];
            var username = values[1];
            var password = values[2];

            r[server] = new
            {
                email = "*****@*****.**",
                username,
                password
            };

            return(r);
        });

        var dockerCfgString = dockerCfg.Apply(x =>
                                              Convert.ToBase64String(Encoding.UTF8.GetBytes(System.Text.Json.JsonSerializer.Serialize(x))));

        var dockerCfgSecretName = "dockercfg-secret";

        var dockerCfgSecret = new Pulumi.Kubernetes.Core.V1.Secret(dockerCfgSecretName, new SecretArgs
        {
            Data =
            {
                { ".dockercfg", dockerCfgString }
            },
            Type     = "kubernetes.io/dockercfg",
            Metadata = new ObjectMetaArgs
            {
                Name = dockerCfgSecretName,
            }
        }, customResourceOptions);

        // Deploy the sample application to the cluster.
        var labels = new InputMap <string>
        {
            { "app", $"app-{applicationName}" },
        };

        var deployment = new Pulumi.Kubernetes.Apps.V1.Deployment(applicationName, new DeploymentArgs
        {
            Spec = new DeploymentSpecArgs
            {
                Selector = new LabelSelectorArgs
                {
                    MatchLabels = labels,
                },
                Replicas = 1,
                Template = new PodTemplateSpecArgs
                {
                    Metadata = new ObjectMetaArgs
                    {
                        Labels = labels,
                        Name   = applicationName
                    },
                    Spec = new PodSpecArgs
                    {
                        Containers = new List <ContainerArgs>
                        {
                            new ContainerArgs
                            {
                                Name  = applicationName,
                                Image = image.ImageName,
                            }
                        },
                        ImagePullSecrets = new LocalObjectReferenceArgs
                        {
                            Name = dockerCfgSecretName
                        }
                    }
                }
            }
        }, customResourceOptions);

        // Create a new service.
        var service = new Pulumi.Kubernetes.Core.V1.Service(applicationName, new ServiceArgs
        {
            Metadata = new ObjectMetaArgs
            {
                Name   = applicationName,
                Labels = labels
            },
            Spec = new ServiceSpecArgs
            {
                Type     = "LoadBalancer",
                Selector = deployment.Spec.Apply(x => x.Template.Metadata.Labels),
                Ports    = new ServicePortArgs
                {
                    Port = 80
                }
            }
        }, customResourceOptions);

        this.KubeConfig          = cluster.KubeConfigRaw;
        this.DockercfgSecretName = dockerCfgSecret.Metadata.Apply(x => x.Name);
    }
        private static AzureResourceBag CreateBaseAzureInfrastructure(Config config)
        {
            var location = config.Require("azure-location");

            var environment = config.Require("azure-tags-environment");
            var owner       = config.Require("azure-tags-owner");
            var createdBy   = config.Require("azure-tags-createdby");

            var kubernetesVersion   = config.Require("kubernetes-version");
            var kubernetesNodeCount = config.RequireInt32("kubernetes-scaling-nodecount");

            var sqlUser     = config.RequireSecret("azure-sqlserver-username");
            var sqlPassword = config.RequireSecret("azure-sqlserver-password");

            var tags = new InputMap <string>
            {
                { "Environment", environment },
                { "CreatedBy", createdBy },
                { "Owner", owner }
            };

            var resourceGroup = new ResourceGroup("pet-doctor-resource-group", new ResourceGroupArgs
            {
                Name     = "pet-doctor",
                Location = location,
                Tags     = tags
            });

            var vnet = new VirtualNetwork("pet-doctor-vnet", new VirtualNetworkArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name          = "petdoctorvnet",
                AddressSpaces = { "10.0.0.0/8" },
                Tags          = tags
            });

            var subnet = new Subnet("pet-doctor-subnet", new SubnetArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name               = "petdoctorsubet",
                AddressPrefixes    = { "10.240.0.0/16" },
                VirtualNetworkName = vnet.Name,
                ServiceEndpoints   = new InputList <string> {
                    "Microsoft.KeyVault", "Microsoft.Sql"
                }
            });

            var registry = new Registry("pet-doctor-acr", new RegistryArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name         = "petdoctoracr",
                Sku          = "Standard",
                AdminEnabled = true,
                Tags         = tags
            });

            var aksServicePrincipalPassword = new RandomPassword("pet-doctor-aks-ad-sp-password", new RandomPasswordArgs
            {
                Length  = 20,
                Special = true,
            }).Result;

            var clusterAdApp = new Application("pet-doctor-aks-ad-app", new ApplicationArgs
            {
                Name = "petdoctoraks"
            });

            var clusterAdServicePrincipal = new ServicePrincipal("aks-app-sp", new ServicePrincipalArgs
            {
                ApplicationId = clusterAdApp.ApplicationId
            });

            var clusterAdServicePrincipalPassword = new ServicePrincipalPassword("aks-app-sp-pwd", new ServicePrincipalPasswordArgs
            {
                ServicePrincipalId = clusterAdServicePrincipal.ObjectId,
                EndDate            = "2099-01-01T00:00:00Z",
                Value = aksServicePrincipalPassword
            });

            // Grant networking permissions to the SP (needed e.g. to provision Load Balancers)
            var subnetAssignment = new Assignment("pet-doctor-aks-sp-subnet-assignment", new AssignmentArgs
            {
                PrincipalId        = clusterAdServicePrincipal.Id,
                RoleDefinitionName = "Network Contributor",
                Scope = subnet.Id
            });

            var acrAssignment = new Assignment("pet-doctor-aks-sp-acr-assignment", new AssignmentArgs
            {
                PrincipalId        = clusterAdServicePrincipal.Id,
                RoleDefinitionName = "AcrPull",
                Scope = registry.Id
            });

            var logAnalyticsWorkspace = new AnalyticsWorkspace("pet-doctor-aks-log-analytics", new AnalyticsWorkspaceArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name = "petdoctorloganalytics",
                Sku  = "PerGB2018",
                Tags = tags
            });

            var logAnalyticsSolution = new AnalyticsSolution("pet-doctor-aks-analytics-solution", new AnalyticsSolutionArgs
            {
                ResourceGroupName   = resourceGroup.Name,
                SolutionName        = "ContainerInsights",
                WorkspaceName       = logAnalyticsWorkspace.Name,
                WorkspaceResourceId = logAnalyticsWorkspace.Id,
                Plan = new AnalyticsSolutionPlanArgs
                {
                    Product   = "OMSGallery/ContainerInsights",
                    Publisher = "Microsoft"
                }
            });

            var sshPublicKey = new PrivateKey("ssh-key", new PrivateKeyArgs
            {
                Algorithm = "RSA",
                RsaBits   = 4096,
            });

            var cluster = new KubernetesCluster("pet-doctor-aks", new KubernetesClusterArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name              = "petdoctoraks",
                DnsPrefix         = "dns",
                KubernetesVersion = kubernetesVersion,
                DefaultNodePool   = new KubernetesClusterDefaultNodePoolArgs
                {
                    Name         = "aksagentpool",
                    NodeCount    = kubernetesNodeCount,
                    VmSize       = "Standard_D2_v2",
                    OsDiskSizeGb = 30,
                    VnetSubnetId = subnet.Id
                },
                LinuxProfile = new KubernetesClusterLinuxProfileArgs
                {
                    AdminUsername = "******",
                    SshKey        = new KubernetesClusterLinuxProfileSshKeyArgs
                    {
                        KeyData = sshPublicKey.PublicKeyOpenssh
                    }
                },
                ServicePrincipal = new KubernetesClusterServicePrincipalArgs
                {
                    ClientId     = clusterAdApp.ApplicationId,
                    ClientSecret = clusterAdServicePrincipalPassword.Value
                },
                RoleBasedAccessControl = new KubernetesClusterRoleBasedAccessControlArgs
                {
                    Enabled = true
                },
                NetworkProfile = new KubernetesClusterNetworkProfileArgs
                {
                    NetworkPlugin    = "azure",
                    ServiceCidr      = "10.2.0.0/24",
                    DnsServiceIp     = "10.2.0.10",
                    DockerBridgeCidr = "172.17.0.1/16"
                },
                AddonProfile = new KubernetesClusterAddonProfileArgs
                {
                    OmsAgent = new KubernetesClusterAddonProfileOmsAgentArgs
                    {
                        Enabled = true,
                        LogAnalyticsWorkspaceId = logAnalyticsWorkspace.Id
                    }
                },
                Tags = tags
            });

            var sqlServer = new SqlServer("pet-doctor-sql", new SqlServerArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name                       = "petdoctorsql",
                Tags                       = tags,
                Version                    = "12.0",
                AdministratorLogin         = sqlUser,
                AdministratorLoginPassword = sqlPassword
            });

            var sqlvnetrule = new VirtualNetworkRule("pet-doctor-sql", new VirtualNetworkRuleArgs
            {
                ResourceGroupName = resourceGroup.Name,
                Name       = "petdoctorsql",
                ServerName = sqlServer.Name,
                SubnetId   = subnet.Id,
            });

            var appInsights = new Insights("pet-doctor-ai", new InsightsArgs
            {
                ApplicationType   = "web",
                Name              = "petdoctor",
                ResourceGroupName = resourceGroup.Name,
                Tags              = tags
            });

            var provider = new Provider("pet-doctor-aks-provider", new ProviderArgs
            {
                KubeConfig = cluster.KubeConfigRaw
            });

            return(new AzureResourceBag
            {
                ResourceGroup = resourceGroup,
                SqlServer = sqlServer,
                Cluster = cluster,
                ClusterProvider = provider,
                AppInsights = appInsights,
                AksServicePrincipal = clusterAdServicePrincipal,
                Subnet = subnet,
                Registry = registry,
                Tags = tags
            });
        }
Exemple #14
0
        public override IEnumerable <KubernetesCluster> DiscoverClusters(string contextJson)
        {
            if (!TryGetDiscoveryContext <AwsAuthenticationDetails>(contextJson, out var authenticationDetails, out var workerPoolId))
            {
                yield break;
            }

            var accessKeyOrWorkerCredentials = authenticationDetails.Credentials.Type == "account"
                ? $"Access Key: {authenticationDetails.Credentials.Account.AccessKey}"
                : $"Using Worker Credentials on Worker Pool: {workerPoolId}";

            Log.Verbose("Looking for Kubernetes clusters in AWS using:");
            Log.Verbose($"  Regions: [{string.Join(",",authenticationDetails.Regions)}]");

            Log.Verbose("  Account:");
            Log.Verbose($"    {accessKeyOrWorkerCredentials}");

            if (authenticationDetails.Role.Type == "assumeRole")
            {
                Log.Verbose("  Role:");
                Log.Verbose($"    ARN: {authenticationDetails.Role.Arn}");
                if (!authenticationDetails.Role.SessionName.IsNullOrEmpty())
                {
                    Log.Verbose($"    Session Name: {authenticationDetails.Role.SessionName}");
                }
                if (authenticationDetails.Role.SessionDuration != null)
                {
                    Log.Verbose($"    Session Duration: {authenticationDetails.Role.SessionDuration}");
                }
                if (!authenticationDetails.Role.ExternalId.IsNullOrEmpty())
                {
                    Log.Verbose($"    External Id: {authenticationDetails.Role.ExternalId}");
                }
            }
            else
            {
                Log.Verbose("  Role: No IAM Role provided.");
            }

            if (!authenticationDetails.TryGetCredentials(Log, out var credentials))
            {
                yield break;
            }

            foreach (var region in authenticationDetails.Regions)
            {
                var client = new AmazonEKSClient(credentials,
                                                 RegionEndpoint.GetBySystemName(region));

                var clusters = client.ListClustersAsync(new ListClustersRequest()).GetAwaiter().GetResult();

                foreach (var cluster in clusters.Clusters.Select(c =>
                                                                 client.DescribeClusterAsync(new DescribeClusterRequest {
                    Name = c
                }).GetAwaiter().GetResult().Cluster))
                {
                    var credentialsRole = authenticationDetails.Role;
                    var assumedRole     = credentialsRole.Type == "assumeRole"
                        ? new AwsAssumeRole(credentialsRole.Arn,
                                            credentialsRole.SessionName,
                                            credentialsRole.SessionDuration,
                                            credentialsRole.ExternalId)
                        : null;

                    yield return(KubernetesCluster.CreateForEks(cluster.Arn,
                                                                cluster.Name,
                                                                cluster.Endpoint,
                                                                authenticationDetails.Credentials.AccountId,
                                                                assumedRole,
                                                                workerPoolId,
                                                                cluster.Tags.ToTargetTags()));
                }
            }
        }
 public Task <KubernetesClusterReportCard> AddKubernetesCluster(KubernetesCluster cluster)
 {
     return(PostAsync <KubernetesClusterReportCard>("clusters", cluster, SOC));
 }