Example #1
0
 public MyStack()
 {
     var config         = new Config();
     var clusterName    = config.Get("clusterName") ?? "example";
     var exampleCluster = new Aws.Eks.Cluster("exampleCluster", new Aws.Eks.ClusterArgs
     {
         EnabledClusterLogTypes =
         {
             "api",
             "audit",
         },
     }, new CustomResourceOptions
     {
         DependsOn =
         {
             "aws_cloudwatch_log_group.example",
         },
     });
     var exampleLogGroup = new Aws.CloudWatch.LogGroup("exampleLogGroup", new Aws.CloudWatch.LogGroupArgs
     {
         RetentionInDays = 7,
     });
 }
Example #2
0
    public EksStack()
    {
        // Read back the default VPC and public subnets, which we will use.
        var vpc = Output.Create(Ec2.GetVpc.InvokeAsync(new Ec2.GetVpcArgs {
            Default = true
        }));
        var vpcId  = vpc.Apply(vpc => vpc.Id);
        var subnet = vpcId.Apply(id => Ec2.GetSubnetIds.InvokeAsync(new Ec2.GetSubnetIdsArgs {
            VpcId = id
        }));
        var subnetIds = subnet.Apply(s => s.Ids);

        // Create an IAM role that can be used by our service's task.
        var eksRole = new Iam.Role("eks-iam-eksRole", new Iam.RoleArgs
        {
            AssumeRolePolicy = @"{
""Version"": ""2008-10-17"",
""Statement"": [{
    ""Sid"": """",
    ""Effect"": ""Allow"",
    ""Principal"": {
        ""Service"": ""eks.amazonaws.com""
    },
    ""Action"": ""sts:AssumeRole""
}]
}"
        });

        var eksPolicies = new Dictionary <string, string>
        {
            { "service-policy", "arn:aws:iam::aws:policy/AmazonEKSServicePolicy" },
            { "cluster-policy", "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" }
        };

        foreach (var(name, policy) in eksPolicies)
        {
            var taskExecAttach = new Iam.RolePolicyAttachment($"rpa-{name}",
                                                              new Iam.RolePolicyAttachmentArgs
            {
                Role      = eksRole.Name,
                PolicyArn = policy,
            });
        }

        // Create an IAM role that can be used by our service's task.
        var nodeGroupRole = new Iam.Role("nodegroup-iam-role", new Iam.RoleArgs
        {
            AssumeRolePolicy = @"{
""Version"": ""2008-10-17"",
""Statement"": [{
    ""Sid"": """",
    ""Effect"": ""Allow"",
    ""Principal"": {
        ""Service"": ""ec2.amazonaws.com""
    },
    ""Action"": ""sts:AssumeRole""
}]
}"
        });

        var nodeGroupPolicies = new Dictionary <string, string>
        {
            { "worker", "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" },
            { "cni", "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" },
            { "registry", "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" }
        };

        foreach (var(name, policy) in nodeGroupPolicies)
        {
            var taskExecAttach = new Iam.RolePolicyAttachment($"ngpa-{name}",
                                                              new Iam.RolePolicyAttachmentArgs
            {
                Role      = nodeGroupRole.Name,
                PolicyArn = policy,
            });
        }

        var clusterSg = new Ec2.SecurityGroup("cluster-sg", new Ec2.SecurityGroupArgs
        {
            VpcId  = vpcId,
            Egress =
            {
                new Ec2.Inputs.SecurityGroupEgressArgs
                {
                    Protocol   = "-1",
                    FromPort   = 0,
                    ToPort     = 0,
                    CidrBlocks ={ "0.0.0.0/0"                  }
                }
            },
            Ingress =
            {
                new Ec2.Inputs.SecurityGroupIngressArgs
                {
                    Protocol   = "tcp",
                    FromPort   = 80,
                    ToPort     = 80,
                    CidrBlocks ={ "0.0.0.0/0"                  }
                }
            }
        });

        var cluster = new Eks.Cluster("eks-cluster", new Eks.ClusterArgs
        {
            RoleArn   = eksRole.Arn,
            VpcConfig = new ClusterVpcConfigArgs
            {
                PublicAccessCidrs =
                {
                    "0.0.0.0/0",
                },
                SecurityGroupIds =
                {
                    clusterSg.Id,
                },
                SubnetIds = subnetIds,
            },
        });

        var nodeGroup = new Eks.NodeGroup("node-group", new Eks.NodeGroupArgs
        {
            ClusterName   = cluster.Name,
            NodeGroupName = "demo-eks-nodegroup",
            NodeRoleArn   = nodeGroupRole.Arn,
            SubnetIds     = subnetIds,
            ScalingConfig = new NodeGroupScalingConfigArgs
            {
                DesiredSize = 2,
                MaxSize     = 2,
                MinSize     = 2
            },
        });

        this.Kubeconfig = GenerateKubeconfig(cluster.Endpoint,
                                             cluster.CertificateAuthority.Apply(x => x.Data),
                                             cluster.Name);

        var k8sProvider = new K8s.Provider("k8s-provider", new K8s.ProviderArgs
        {
            KubeConfig = this.Kubeconfig
        }, new CustomResourceOptions
        {
            DependsOn = { nodeGroup },
        });

        var appNamespace = new CoreV1.Namespace("app-ns", new NamespaceArgs
        {
            Metadata = new ObjectMetaArgs
            {
                Name = "joe-duffy",
            },
        }, new CustomResourceOptions
        {
            Provider = k8sProvider,
        });

        var appLabels = new InputMap <string>
        {
            { "app", "iac-workshop" }
        };
        var deployment = new AppsV1.Deployment("app-dep", new DeploymentArgs
        {
            Metadata = new ObjectMetaArgs
            {
                Namespace = appNamespace.Metadata.Apply(x => x.Name),
            },
            Spec = new DeploymentSpecArgs
            {
                Selector = new LabelSelectorArgs
                {
                    MatchLabels = appLabels
                },
                Replicas = 1,
                Template = new PodTemplateSpecArgs
                {
                    Metadata = new ObjectMetaArgs
                    {
                        Labels = appLabels
                    },
                    Spec = new PodSpecArgs
                    {
                        Containers =
                        {
                            new ContainerArgs
                            {
                                Name  = "iac-workshop",
                                Image = "jocatalin/kubernetes-bootcamp:v2",
                            }
                        }
                    }
                }
            },
        }, new CustomResourceOptions
        {
            Provider = k8sProvider,
        });

        var service = new CoreV1.Service("app-service", new ServiceArgs
        {
            Metadata = new ObjectMetaArgs
            {
                Namespace = appNamespace.Metadata.Apply(x => x.Name),
                Labels    = deployment.Spec.Apply(spec => spec.Template.Metadata.Labels),
            },
            Spec = new ServiceSpecArgs
            {
                Type  = "LoadBalancer",
                Ports =
                {
                    new ServicePortArgs
                    {
                        Port       = 80,
                        TargetPort = 8080
                    },
                },
                Selector = deployment.Spec.Apply(spec => spec.Template.Metadata.Labels)
            },
        }, new CustomResourceOptions
        {
            Provider = k8sProvider,
        });

        this.Url = service.Status.Apply(status => status.LoadBalancer.Ingress[0].Hostname);
    }
    public MyStack()
    {
        // Read back the default VPC and public subnets, which we will use.
        var vpc = Output.Create(Ec2.GetVpc.InvokeAsync(new Ec2.GetVpcArgs {
            Default = true
        }));
        var vpcId  = vpc.Apply(vpc => vpc.Id);
        var subnet = vpcId.Apply(id => Ec2.GetSubnetIds.InvokeAsync(new Ec2.GetSubnetIdsArgs {
            VpcId = id
        }));
        var subnetIds = subnet.Apply(s => s.Ids);

        // Create an IAM role that can be used by our service's task.
        var eksRole = new Iam.Role("eks-iam-eksRole", new Iam.RoleArgs
        {
            AssumeRolePolicy = @"{
""Version"": ""2008-10-17"",
""Statement"": [{
    ""Sid"": """",
    ""Effect"": ""Allow"",
    ""Principal"": {
        ""Service"": ""eks.amazonaws.com""
    },
    ""Action"": ""sts:AssumeRole""
}]
}"
        });

        var eksPolicies = new Dictionary <string, string>
        {
            { "service-policy", "arn:aws:iam::aws:policy/AmazonEKSServicePolicy" },
            { "cluster-policy", "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy" }
        };

        foreach (var(name, policy) in eksPolicies)
        {
            var taskExecAttach = new Iam.RolePolicyAttachment($"rpa-{name}",
                                                              new Iam.RolePolicyAttachmentArgs
            {
                Role      = eksRole.Name,
                PolicyArn = policy,
            });
        }

        // Create an IAM role that can be used by our service's task.
        var nodeGroupRole = new Iam.Role("nodegroup-iam-role", new Iam.RoleArgs
        {
            AssumeRolePolicy = @"{
""Version"": ""2008-10-17"",
""Statement"": [{
    ""Sid"": """",
    ""Effect"": ""Allow"",
    ""Principal"": {
        ""Service"": ""ec2.amazonaws.com""
    },
    ""Action"": ""sts:AssumeRole""
}]
}"
        });

        var nodeGroupPolicies = new Dictionary <string, string>
        {
            { "worker", "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy" },
            { "cni", "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy" },
            { "registry", "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" }
        };

        foreach (var(name, policy) in nodeGroupPolicies)
        {
            var taskExecAttach = new Iam.RolePolicyAttachment($"ngpa-{name}",
                                                              new Iam.RolePolicyAttachmentArgs
            {
                Role      = nodeGroupRole.Name,
                PolicyArn = policy,
            });
        }

        var clusterSg = new Ec2.SecurityGroup("cluster-sg", new Ec2.SecurityGroupArgs
        {
            VpcId  = vpcId,
            Egress =
            {
                new Ec2.Inputs.SecurityGroupEgressArgs
                {
                    Protocol   = "-1",
                    FromPort   = 0,
                    ToPort     = 0,
                    CidrBlocks ={ "0.0.0.0/0"                  }
                }
            },
            Ingress =
            {
                new Ec2.Inputs.SecurityGroupIngressArgs
                {
                    Protocol   = "tcp",
                    FromPort   = 80,
                    ToPort     = 80,
                    CidrBlocks ={ "0.0.0.0/0"                  }
                }
            }
        });

        var cluster = new Eks.Cluster("eks-cluster", new Eks.ClusterArgs
        {
            RoleArn   = eksRole.Arn,
            VpcConfig = new ClusterVpcConfigArgs
            {
                PublicAccessCidrs =
                {
                    "0.0.0.0/0",
                },
                SecurityGroupIds =
                {
                    clusterSg.Id,
                },
                SubnetIds = subnetIds,
            },
        });

        var nodeGroup = new Eks.NodeGroup("node-group", new Eks.NodeGroupArgs
        {
            ClusterName   = cluster.Name,
            NodeGroupName = "demo-eks-nodegroup",
            NodeRoleArn   = nodeGroupRole.Arn,
            SubnetIds     = subnetIds,
            ScalingConfig = new NodeGroupScalingConfigArgs
            {
                DesiredSize = 2,
                MaxSize     = 2,
                MinSize     = 2
            },
        });

        this.Kubeconfig = GenerateKubeconfig(cluster.Endpoint,
                                             cluster.CertificateAuthority.Apply(x => x.Data),
                                             cluster.Name);
    }
Example #4
0
    private async Task <IDictionary <string, Output <string> > > Initialize()
    {
        // VPC
        var eksVpc = new Aws.Ec2.Vpc("eksVpc", new Aws.Ec2.VpcArgs
        {
            CidrBlock          = "10.100.0.0/16",
            InstanceTenancy    = "default",
            EnableDnsHostnames = true,
            EnableDnsSupport   = true,
            Tags =
            {
                { "Name", "pulumi-eks-vpc" },
            },
        });
        var eksIgw = new Aws.Ec2.InternetGateway("eksIgw", new Aws.Ec2.InternetGatewayArgs
        {
            VpcId = eksVpc.Id,
            Tags  =
            {
                { "Name", "pulumi-vpc-ig" },
            },
        });
        var eksRouteTable = new Aws.Ec2.RouteTable("eksRouteTable", new Aws.Ec2.RouteTableArgs
        {
            VpcId  = eksVpc.Id,
            Routes =
            {
                new Aws.Ec2.Inputs.RouteTableRouteArgs
                {
                    CidrBlock = "0.0.0.0/0",
                    GatewayId = eksIgw.Id,
                },
            },
            Tags =
            {
                { "Name", "pulumi-vpc-rt" },
            },
        });
        // Subnets, one for each AZ in a region
        var zones = await Aws.GetAvailabilityZones.InvokeAsync();

        var vpcSubnet = new List <Aws.Ec2.Subnet>();

        foreach (var range in zones.Names.Select((v, k) => new { Key = k, Value = v }))
        {
            vpcSubnet.Add(new Aws.Ec2.Subnet($"vpcSubnet-{range.Key}", new Aws.Ec2.SubnetArgs
            {
                AssignIpv6AddressOnCreation = false,
                VpcId = eksVpc.Id,
                MapPublicIpOnLaunch = true,
                CidrBlock           = $"10.100.{range.Key}.0/24",
                AvailabilityZone    = range.Value,
                Tags =
                {
                    { "Name", $"pulumi-sn-{range.Value}" },
                },
            }));
        }
        var rta = new List <Aws.Ec2.RouteTableAssociation>();

        foreach (var range in zones.Names.Select((v, k) => new { Key = k, Value = v }))
        {
            rta.Add(new Aws.Ec2.RouteTableAssociation($"rta-{range.Key}", new Aws.Ec2.RouteTableAssociationArgs
            {
                RouteTableId = eksRouteTable.Id,
                SubnetId     = vpcSubnet[range.Key].Id,
            }));
        }
        var subnetIds        = vpcSubnet.Select(__item => __item.Id).ToList();
        var eksSecurityGroup = new Aws.Ec2.SecurityGroup("eksSecurityGroup", new Aws.Ec2.SecurityGroupArgs
        {
            VpcId       = eksVpc.Id,
            Description = "Allow all HTTP(s) traffic to EKS Cluster",
            Tags        =
            {
                { "Name", "pulumi-cluster-sg" },
            },
            Ingress =
            {
                new Aws.Ec2.Inputs.SecurityGroupIngressArgs
                {
                    CidrBlocks =
                    {
                        "0.0.0.0/0",
                    },
                    FromPort    = 443,
                    ToPort      = 443,
                    Protocol    = "tcp",
                    Description = "Allow pods to communicate with the cluster API Server.",
                },
                new Aws.Ec2.Inputs.SecurityGroupIngressArgs
                {
                    CidrBlocks =
                    {
                        "0.0.0.0/0",
                    },
                    FromPort    = 80,
                    ToPort      = 80,
                    Protocol    = "tcp",
                    Description = "Allow internet access to pods",
                },
            },
        });
        // EKS Cluster Role
        var eksRole = new Aws.Iam.Role("eksRole", new Aws.Iam.RoleArgs
        {
            AssumeRolePolicy = JsonSerializer.Serialize(new Dictionary <string, object?>
            {
                { "Version", "2012-10-17" },
                { "Statement", new[]
                  {
                      new Dictionary <string, object?>
                      {
                          { "Action", "sts:AssumeRole" },
                          { "Principal", new Dictionary <string, object?>
                            {
                                { "Service", "eks.amazonaws.com" },
                            } },
                          { "Effect", "Allow" },
                          { "Sid", "" },
                      },
                  } },
            }),
        });
        var servicePolicyAttachment = new Aws.Iam.RolePolicyAttachment("servicePolicyAttachment", new Aws.Iam.RolePolicyAttachmentArgs
        {
            Role      = eksRole.Id,
            PolicyArn = "arn:aws:iam::aws:policy/AmazonEKSServicePolicy",
        });
        var clusterPolicyAttachment = new Aws.Iam.RolePolicyAttachment("clusterPolicyAttachment", new Aws.Iam.RolePolicyAttachmentArgs
        {
            Role      = eksRole.Id,
            PolicyArn = "arn:aws:iam::aws:policy/AmazonEKSClusterPolicy",
        });
        // EC2 NodeGroup Role
        var ec2Role = new Aws.Iam.Role("ec2Role", new Aws.Iam.RoleArgs
        {
            AssumeRolePolicy = JsonSerializer.Serialize(new Dictionary <string, object?>
            {
                { "Version", "2012-10-17" },
                { "Statement", new[]
                  {
                      new Dictionary <string, object?>
                      {
                          { "Action", "sts:AssumeRole" },
                          { "Principal", new Dictionary <string, object?>
                            {
                                { "Service", "ec2.amazonaws.com" },
                            } },
                          { "Effect", "Allow" },
                          { "Sid", "" },
                      },
                  } },
            }),
        });
        var workerNodePolicyAttachment = new Aws.Iam.RolePolicyAttachment("workerNodePolicyAttachment", new Aws.Iam.RolePolicyAttachmentArgs
        {
            Role      = ec2Role.Id,
            PolicyArn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy",
        });
        var cniPolicyAttachment = new Aws.Iam.RolePolicyAttachment("cniPolicyAttachment", new Aws.Iam.RolePolicyAttachmentArgs
        {
            Role      = ec2Role.Id,
            PolicyArn = "arn:aws:iam::aws:policy/AmazonEKSCNIPolicy",
        });
        var registryPolicyAttachment = new Aws.Iam.RolePolicyAttachment("registryPolicyAttachment", new Aws.Iam.RolePolicyAttachmentArgs
        {
            Role      = ec2Role.Id,
            PolicyArn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly",
        });
        // EKS Cluster
        var eksCluster = new Aws.Eks.Cluster("eksCluster", new Aws.Eks.ClusterArgs
        {
            RoleArn = eksRole.Arn,
            Tags    =
            {
                { "Name", "pulumi-eks-cluster" },
            },
            VpcConfig = new Aws.Eks.Inputs.ClusterVpcConfigArgs
            {
                PublicAccessCidrs =
                {
                    "0.0.0.0/0",
                },
                SecurityGroupIds =
                {
                    eksSecurityGroup.Id,
                },
                SubnetIds = subnetIds,
            },
        });
        var nodeGroup = new Aws.Eks.NodeGroup("nodeGroup", new Aws.Eks.NodeGroupArgs
        {
            ClusterName   = eksCluster.Name,
            NodeGroupName = "pulumi-eks-nodegroup",
            NodeRoleArn   = ec2Role.Arn,
            SubnetIds     = subnetIds,
            Tags          =
            {
                { "Name", "pulumi-cluster-nodeGroup" },
            },
            ScalingConfig = new Aws.Eks.Inputs.NodeGroupScalingConfigArgs
            {
                DesiredSize = 2,
                MaxSize     = 2,
                MinSize     = 1,
            },
        });
        var clusterName = eksCluster.Name;
        var kubeconfig  = Output.Tuple(eksCluster.Endpoint, eksCluster.CertificateAuthority, eksCluster.Name).Apply(values =>
        {
            var endpoint             = values.Item1;
            var certificateAuthority = values.Item2;
            var name = values.Item3;
            return(JsonSerializer.Serialize(new Dictionary <string, object?>
            {
                { "apiVersion", "v1" },
                { "clusters", new[]
                  {
                      new Dictionary <string, object?>
                      {
                          { "cluster", new Dictionary <string, object?>
                            {
                                { "server", endpoint },
                                { "certificate-authority-data", certificateAuthority.Data },
                            } },
                          { "name", "kubernetes" },
                      },
                  } },
                { "contexts", new[]
                  {
                      new Dictionary <string, object?>
                      {
                          { "contest", new Dictionary <string, object?>
                            {
                                { "cluster", "kubernetes" },
                                { "user", "aws" },
                            } },
                      },
                  } },
                { "current-context", "aws" },
                { "kind", "Config" },
                { "users", new[]
                  {
                      new Dictionary <string, object?>
                      {
                          { "name", "aws" },
                          { "user", new Dictionary <string, object?>
                            {
                                { "exec", new Dictionary <string, object?>
                                    {
                                        { "apiVersion", "client.authentication.k8s.io/v1alpha1" },
                                        { "command", "aws-iam-authenticator" },
                                    } },
                                { "args", new[]
                                    {
                                        "token",
                                        "-i",
                                        name,
                                    } },
                            } },
                      },
                  } },
            }));
        });

        return(new Dictionary <string, Output <string> >
        {
            { "clusterName", clusterName },
            { "kubeconfig", kubeconfig },
        });
    }