297 lines
11 KiB
C#
297 lines
11 KiB
C#
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using Pulumi;
|
|
using Aws = Pulumi.Aws;
|
|
|
|
class MyStack : Stack
|
|
{
|
|
public MyStack()
|
|
{
|
|
var dict = Output.Create(Initialize());
|
|
this.ClusterName = dict.Apply(dict => dict["clusterName"]);
|
|
this.Kubeconfig = dict.Apply(dict => dict["kubeconfig"]);
|
|
}
|
|
|
|
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 },
|
|
};
|
|
}
|
|
|
|
[Output("clusterName")]
|
|
public Output<string> ClusterName { get; set; }
|
|
[Output("kubeconfig")]
|
|
public Output<string> Kubeconfig { get; set; }
|
|
}
|