Merge pull request #7066 from rifelpet/mixed-instances-spot-price

Add support for SpotPrice and Mixed Instance ASGs
This commit is contained in:
Kubernetes Prow Robot 2019-06-11 06:30:20 -07:00 committed by GitHub
commit 825b0db73e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 6562 additions and 57 deletions

View File

@ -52,20 +52,20 @@ const updateClusterTestBase = "../../tests/integration/update_cluster/"
// TestMinimal runs the test on a minimum configuration, similar to kops create cluster minimal.example.com --zones us-west-1a
func TestMinimal(t *testing.T) {
runTestAWS(t, "minimal.example.com", "minimal", "v1alpha0", false, 1, true, nil)
runTestAWS(t, "minimal.example.com", "minimal", "v1alpha1", false, 1, true, nil)
runTestAWS(t, "minimal.example.com", "minimal", "v1alpha2", false, 1, true, nil)
runTestAWS(t, "minimal.example.com", "minimal", "v1alpha0", false, 1, true, false, nil)
runTestAWS(t, "minimal.example.com", "minimal", "v1alpha1", false, 1, true, false, nil)
runTestAWS(t, "minimal.example.com", "minimal", "v1alpha2", false, 1, true, false, nil)
}
// TestRestrictAccess runs the test on a simple SG configuration, similar to kops create cluster minimal.example.com --ssh-access=$(IPS) --admin-access=$(IPS) --master-count=3
func TestRestrictAccess(t *testing.T) {
runTestAWS(t, "restrictaccess.example.com", "restrict_access", "v1alpha2", false, 1, true, nil)
runTestAWS(t, "restrictaccess.example.com", "restrict_access", "v1alpha2", false, 1, true, false, nil)
}
// TestHA runs the test on a simple HA configuration, similar to kops create cluster minimal.example.com --zones us-west-1a,us-west-1b,us-west-1c --master-count=3
func TestHA(t *testing.T) {
runTestAWS(t, "ha.example.com", "ha", "v1alpha1", false, 3, true, nil)
runTestAWS(t, "ha.example.com", "ha", "v1alpha2", false, 3, true, nil)
runTestAWS(t, "ha.example.com", "ha", "v1alpha1", false, 3, true, false, nil)
runTestAWS(t, "ha.example.com", "ha", "v1alpha2", false, 3, true, false, nil)
}
// TestHighAvailabilityGCE runs the test on a simple HA GCE configuration, similar to kops create cluster ha-gce.example.com
@ -76,8 +76,8 @@ func TestHighAvailabilityGCE(t *testing.T) {
// TestComplex runs the test on a more complex configuration, intended to hit more of the edge cases
func TestComplex(t *testing.T) {
runTestAWS(t, "complex.example.com", "complex", "v1alpha2", false, 1, true, nil)
runTestAWS(t, "complex.example.com", "complex", "legacy-v1alpha2", false, 1, true, nil)
runTestAWS(t, "complex.example.com", "complex", "v1alpha2", false, 1, true, false, nil)
runTestAWS(t, "complex.example.com", "complex", "legacy-v1alpha2", false, 1, true, false, nil)
}
// TestMinimalCloudformation runs the test on a minimum configuration, similar to kops create cluster minimal.example.com --zones us-west-1a
@ -95,7 +95,7 @@ func TestExistingIAMCloudformation(t *testing.T) {
func TestExistingSG(t *testing.T) {
lifecycleOverrides := []string{"SecurityGroup=ExistsAndWarnIfChanges", "SecurityGroupRule=ExistsAndWarnIfChanges"}
lifecycleOverrides = nil
runTestAWS(t, "existingsg.example.com", "existing_sg", "v1alpha2", false, 3, true, lifecycleOverrides)
runTestAWS(t, "existingsg.example.com", "existing_sg", "v1alpha2", false, 3, true, false, lifecycleOverrides)
}
// TestAdditionalUserData runs the test on passing additional user-data to an instance at bootstrap.
@ -105,82 +105,82 @@ func TestAdditionalUserData(t *testing.T) {
// TestBastionAdditionalUserData runs the test on passing additional user-data to a bastion instance group
func TestBastionAdditionalUserData(t *testing.T) {
runTestAWS(t, "bastionuserdata.example.com", "bastionadditional_user-data", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "bastionuserdata.example.com", "bastionadditional_user-data", "v1alpha2", true, 1, true, false, nil)
}
// TestMinimal_141 runs the test on a configuration from 1.4.1 release
func TestMinimal_141(t *testing.T) {
runTestAWS(t, "minimal-141.example.com", "minimal-141", "v1alpha0", false, 1, true, nil)
runTestAWS(t, "minimal-141.example.com", "minimal-141", "v1alpha0", false, 1, true, false, nil)
}
// TestPrivateWeave runs the test on a configuration with private topology, weave networking
func TestPrivateWeave(t *testing.T) {
runTestAWS(t, "privateweave.example.com", "privateweave", "v1alpha1", true, 1, true, nil)
runTestAWS(t, "privateweave.example.com", "privateweave", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "privateweave.example.com", "privateweave", "v1alpha1", true, 1, true, false, nil)
runTestAWS(t, "privateweave.example.com", "privateweave", "v1alpha2", true, 1, true, false, nil)
}
// TestPrivateFlannel runs the test on a configuration with private topology, flannel networking
func TestPrivateFlannel(t *testing.T) {
runTestAWS(t, "privateflannel.example.com", "privateflannel", "v1alpha1", true, 1, true, nil)
runTestAWS(t, "privateflannel.example.com", "privateflannel", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "privateflannel.example.com", "privateflannel", "v1alpha1", true, 1, true, false, nil)
runTestAWS(t, "privateflannel.example.com", "privateflannel", "v1alpha2", true, 1, true, false, nil)
}
// TestPrivateCalico runs the test on a configuration with private topology, calico networking
func TestPrivateCalico(t *testing.T) {
runTestAWS(t, "privatecalico.example.com", "privatecalico", "v1alpha1", true, 1, true, nil)
runTestAWS(t, "privatecalico.example.com", "privatecalico", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "privatecalico.example.com", "privatecalico", "v1alpha1", true, 1, true, false, nil)
runTestAWS(t, "privatecalico.example.com", "privatecalico", "v1alpha2", true, 1, true, false, nil)
}
// TestPrivateCanal runs the test on a configuration with private topology, canal networking
func TestPrivateCanal(t *testing.T) {
runTestAWS(t, "privatecanal.example.com", "privatecanal", "v1alpha1", true, 1, true, nil)
runTestAWS(t, "privatecanal.example.com", "privatecanal", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "privatecanal.example.com", "privatecanal", "v1alpha1", true, 1, true, false, nil)
runTestAWS(t, "privatecanal.example.com", "privatecanal", "v1alpha2", true, 1, true, false, nil)
}
// TestPrivateKopeio runs the test on a configuration with private topology, kopeio networking
func TestPrivateKopeio(t *testing.T) {
runTestAWS(t, "privatekopeio.example.com", "privatekopeio", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "privatekopeio.example.com", "privatekopeio", "v1alpha2", true, 1, true, false, nil)
}
// TestUnmanaged is a test where all the subnets opt-out of route management
func TestUnmanaged(t *testing.T) {
runTestAWS(t, "unmanaged.example.com", "unmanaged", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "unmanaged.example.com", "unmanaged", "v1alpha2", true, 1, true, false, nil)
}
// TestPrivateSharedSubnet runs the test on a configuration with private topology & shared subnets
func TestPrivateSharedSubnet(t *testing.T) {
runTestAWS(t, "private-shared-subnet.example.com", "private-shared-subnet", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "private-shared-subnet.example.com", "private-shared-subnet", "v1alpha2", true, 1, true, false, nil)
}
// TestPrivateDns1 runs the test on a configuration with private topology, private dns
func TestPrivateDns1(t *testing.T) {
runTestAWS(t, "privatedns1.example.com", "privatedns1", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "privatedns1.example.com", "privatedns1", "v1alpha2", true, 1, true, false, nil)
}
// TestPrivateDns2 runs the test on a configuration with private topology, private dns, extant vpc
func TestPrivateDns2(t *testing.T) {
runTestAWS(t, "privatedns2.example.com", "privatedns2", "v1alpha2", true, 1, true, nil)
runTestAWS(t, "privatedns2.example.com", "privatedns2", "v1alpha2", true, 1, true, false, nil)
}
// TestSharedSubnet runs the test on a configuration with a shared subnet (and VPC)
func TestSharedSubnet(t *testing.T) {
runTestAWS(t, "sharedsubnet.example.com", "shared_subnet", "v1alpha2", false, 1, true, nil)
runTestAWS(t, "sharedsubnet.example.com", "shared_subnet", "v1alpha2", false, 1, true, false, nil)
}
// TestSharedVPC runs the test on a configuration with a shared VPC
func TestSharedVPC(t *testing.T) {
runTestAWS(t, "sharedvpc.example.com", "shared_vpc", "v1alpha2", false, 1, true, nil)
runTestAWS(t, "sharedvpc.example.com", "shared_vpc", "v1alpha2", false, 1, true, false, nil)
}
// TestExistingIAM runs the test on a configuration with existing IAM instance profiles
func TestExistingIAM(t *testing.T) {
lifecycleOverrides := []string{"IAMRole=ExistsAndWarnIfChanges", "IAMRolePolicy=ExistsAndWarnIfChanges", "IAMInstanceProfileRole=ExistsAndWarnIfChanges"}
runTestAWS(t, "existing-iam.example.com", "existing_iam", "v1alpha2", false, 3, false, lifecycleOverrides)
runTestAWS(t, "existing-iam.example.com", "existing_iam", "v1alpha2", false, 3, false, false, lifecycleOverrides)
}
// TestAdditionalCIDR runs the test on a configuration with a shared VPC
func TestAdditionalCIDR(t *testing.T) {
runTestAWS(t, "additionalcidr.example.com", "additional_cidr", "v1alpha3", false, 3, true, nil)
runTestAWS(t, "additionalcidr.example.com", "additional_cidr", "v1alpha3", false, 3, true, false, nil)
runTestCloudformation(t, "additionalcidr.example.com", "additional_cidr", "v1alpha2", false, nil)
}
@ -190,7 +190,7 @@ func TestPhaseNetwork(t *testing.T) {
}
func TestExternalLoadBalancer(t *testing.T) {
runTestAWS(t, "externallb.example.com", "externallb", "v1alpha2", false, 1, true, nil)
runTestAWS(t, "externallb.example.com", "externallb", "v1alpha2", false, 1, true, false, nil)
runTestCloudformation(t, "externallb.example.com", "externallb", "v1alpha2", false, nil)
}
@ -207,6 +207,18 @@ func TestPhaseCluster(t *testing.T) {
runTestPhase(t, "lifecyclephases.example.com", "lifecycle_phases", "v1alpha2", true, 1, cloudup.PhaseCluster)
}
// TestMixedInstancesASG tests ASGs using a mixed instance policy
func TestMixedInstancesASG(t *testing.T) {
runTestAWS(t, "mixedinstances.example.com", "mixed_instances", "v1alpha2", false, 3, true, true, nil)
runTestCloudformation(t, "mixedinstances.example.com", "mixed_instances", "v1alpha2", false, nil)
}
// TestMixedInstancesSpotASG tests ASGs using a mixed instance policy and spot instances
func TestMixedInstancesSpotASG(t *testing.T) {
runTestAWS(t, "mixedinstances.example.com", "mixed_instances_spot", "v1alpha2", false, 3, true, true, nil)
runTestCloudformation(t, "mixedinstances.example.com", "mixed_instances_spot", "v1alpha2", false, nil)
}
func runTest(t *testing.T, h *testutils.IntegrationTestHarness, clusterName string, srcDir string, version string, private bool, zones int, expectedDataFilenames []string, tfFileName string, phase *cloudup.Phase, lifecycleOverrides []string) {
var stdout bytes.Buffer
@ -374,7 +386,7 @@ func runTest(t *testing.T, h *testutils.IntegrationTestHarness, clusterName stri
}
}
func runTestAWS(t *testing.T, clusterName string, srcDir string, version string, private bool, zones int, expectPolicies bool, lifecycleOverrides []string) {
func runTestAWS(t *testing.T, clusterName string, srcDir string, version string, private bool, zones int, expectPolicies bool, launchTemplate bool, lifecycleOverrides []string) {
h := testutils.NewIntegrationTestHarness(t)
defer h.Close()
@ -383,7 +395,11 @@ func runTestAWS(t *testing.T, clusterName string, srcDir string, version string,
expectedFilenames := []string{
"aws_key_pair_kubernetes." + clusterName + "-c4a6ed9aa889b9e2c39cd663eb9c7157_public_key",
"aws_launch_configuration_nodes." + clusterName + "_user_data",
}
if launchTemplate {
expectedFilenames = append(expectedFilenames, "aws_launch_template_nodes."+clusterName+"_user_data")
} else {
expectedFilenames = append(expectedFilenames, "aws_launch_configuration_nodes."+clusterName+"_user_data")
}
for i := 0; i < zones; i++ {

View File

@ -98,7 +98,7 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.ModelBuilde
// @TODO check if there any a better way of doing this .. initially I had a type LaunchTemplate which included
// LaunchConfiguration as an anonymous field, bit given up the task dependency walker works this caused issues, due
// to the creation of a implicit dependency
return &awstasks.LaunchTemplate{
lt := &awstasks.LaunchTemplate{
Name: fi.String(name),
Lifecycle: b.Lifecycle,
AssociatePublicIP: lc.AssociatePublicIP,
@ -113,10 +113,17 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchTemplateTask(c *fi.ModelBuilde
RootVolumeType: lc.RootVolumeType,
SSHKey: lc.SSHKey,
SecurityGroups: lc.SecurityGroups,
SpotPrice: lc.SpotPrice,
Tenancy: lc.Tenancy,
UserData: lc.UserData,
}, nil
}
// When using a MixedInstances ASG, AWS requires the SpotPrice be defined on the ASG
// rather than the LaunchTemplate or else it returns this error:
// You cannot use a launch template that is set to request Spot Instances (InstanceMarketOptions)
// when you configure an Auto Scaling group with a mixed instances policy.
if ig.Spec.MixedInstancesPolicy == nil {
lt.SpotPrice = lc.SpotPrice
}
return lt, nil
}
// buildLaunchConfigurationTask is responsible for building a launch configuration task into the model
@ -223,7 +230,7 @@ func (b *AutoscalingGroupModelBuilder) buildLaunchConfigurationTask(c *fi.ModelB
return nil, err
}
// @step: set up instnce spot pricing
// @step: set up instance spot pricing
if fi.StringValue(ig.Spec.MaxPrice) != "" {
spotPrice := fi.StringValue(ig.Spec.MaxPrice)
t.SpotPrice = spotPrice
@ -318,6 +325,7 @@ func (b *AutoscalingGroupModelBuilder) buildAutoScalingGroupTask(c *fi.ModelBuil
t.MixedOnDemandBase = spec.OnDemandBase
t.MixedSpotAllocationStrategy = spec.SpotAllocationStrategy
t.MixedSpotInstancePools = spec.SpotInstancePools
t.MixedSpotMaxPrice = ig.Spec.MaxPrice
}
return t, nil

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCtWu40XQo8dczLsCq0OWV+hxm9uV3WxeH9Kgh4sMzQxNtoU1pvW0XdjpkBesRKGoolfWeCLXWxpyQb1IaiMkKoz7MdhQ/6UKjMjP66aFWWp3pwD0uj0HuJ7tq4gKHKRYGTaZIRWpzUiANBrjugVgA+Sd7E/mYwc/DMXkIyRZbvhQ==

View File

@ -0,0 +1,135 @@
apiVersion: kops.k8s.io/v1alpha2
kind: Cluster
metadata:
creationTimestamp: "2016-12-10T22:42:27Z"
name: mixedinstances.example.com
spec:
kubernetesApiAccess:
- 0.0.0.0/0
channel: stable
cloudProvider: aws
configBase: memfs://clusters.example.com/mixedinstances.example.com
etcdClusters:
- etcdMembers:
- instanceGroup: master-us-test-1a
name: us-test-1a
- instanceGroup: master-us-test-1b
name: us-test-1b
- instanceGroup: master-us-test-1c
name: us-test-1c
name: main
- etcdMembers:
- instanceGroup: master-us-test-1a
name: us-test-1a
- instanceGroup: master-us-test-1b
name: us-test-1b
- instanceGroup: master-us-test-1c
name: us-test-1c
name: events
kubernetesVersion: v1.12.9
masterInternalName: api.internal.mixedinstances.example.com
masterPublicName: api.mixedinstances.example.com
networkCIDR: 10.0.0.0/16
networking:
kubenet: {}
nonMasqueradeCIDR: 100.64.0.0/10
sshAccess:
- 0.0.0.0/0
topology:
masters: public
nodes: public
subnets:
- cidr: 10.0.1.0/24
name: us-test-1a
type: Public
zone: us-test-1a
- cidr: 10.0.2.0/24
name: us-test-1b
type: Public
zone: us-test-1b
- cidr: 10.0.3.0/24
name: us-test-1c
type: Public
zone: us-test-1c
---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2016-12-10T22:42:28Z"
name: nodes
labels:
kops.k8s.io/cluster: mixedinstances.example.com
spec:
associatePublicIp: true
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
machineType: t2.medium
maxSize: 2
minSize: 2
role: Node
subnets:
- us-test-1b
mixedInstancesPolicy:
instances:
- m5.large
- m5.xlarge
- t2.medium
onDemandAboveBase: 5
spotInstancePools: 3
---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2016-12-10T22:42:28Z"
name: master-us-test-1a
labels:
kops.k8s.io/cluster: mixedinstances.example.com
spec:
associatePublicIp: true
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
machineType: m3.medium
maxSize: 1
minSize: 1
role: Master
subnets:
- us-test-1a
---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2016-12-10T22:42:28Z"
name: master-us-test-1b
labels:
kops.k8s.io/cluster: mixedinstances.example.com
spec:
associatePublicIp: true
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
machineType: m3.medium
maxSize: 1
minSize: 1
role: Master
subnets:
- us-test-1b
---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2016-12-10T22:42:28Z"
name: master-us-test-1c
labels:
kops.k8s.io/cluster: mixedinstances.example.com
spec:
associatePublicIp: true
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
machineType: m3.medium
maxSize: 1
minSize: 1
role: Master
subnets:
- us-test-1c

View File

@ -0,0 +1,726 @@
locals = {
cluster_name = "mixedinstances.example.com"
master_autoscaling_group_ids = ["${aws_autoscaling_group.master-us-test-1a-masters-mixedinstances-example-com.id}", "${aws_autoscaling_group.master-us-test-1b-masters-mixedinstances-example-com.id}", "${aws_autoscaling_group.master-us-test-1c-masters-mixedinstances-example-com.id}"]
master_security_group_ids = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
masters_role_arn = "${aws_iam_role.masters-mixedinstances-example-com.arn}"
masters_role_name = "${aws_iam_role.masters-mixedinstances-example-com.name}"
node_autoscaling_group_ids = ["${aws_autoscaling_group.nodes-mixedinstances-example-com.id}"]
node_security_group_ids = ["${aws_security_group.nodes-mixedinstances-example-com.id}"]
node_subnet_ids = ["${aws_subnet.us-test-1b-mixedinstances-example-com.id}"]
nodes_role_arn = "${aws_iam_role.nodes-mixedinstances-example-com.arn}"
nodes_role_name = "${aws_iam_role.nodes-mixedinstances-example-com.name}"
region = "us-test-1"
route_table_public_id = "${aws_route_table.mixedinstances-example-com.id}"
subnet_us-test-1a_id = "${aws_subnet.us-test-1a-mixedinstances-example-com.id}"
subnet_us-test-1b_id = "${aws_subnet.us-test-1b-mixedinstances-example-com.id}"
subnet_us-test-1c_id = "${aws_subnet.us-test-1c-mixedinstances-example-com.id}"
vpc_cidr_block = "${aws_vpc.mixedinstances-example-com.cidr_block}"
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
}
output "cluster_name" {
value = "mixedinstances.example.com"
}
output "master_autoscaling_group_ids" {
value = ["${aws_autoscaling_group.master-us-test-1a-masters-mixedinstances-example-com.id}", "${aws_autoscaling_group.master-us-test-1b-masters-mixedinstances-example-com.id}", "${aws_autoscaling_group.master-us-test-1c-masters-mixedinstances-example-com.id}"]
}
output "master_security_group_ids" {
value = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
}
output "masters_role_arn" {
value = "${aws_iam_role.masters-mixedinstances-example-com.arn}"
}
output "masters_role_name" {
value = "${aws_iam_role.masters-mixedinstances-example-com.name}"
}
output "node_autoscaling_group_ids" {
value = ["${aws_autoscaling_group.nodes-mixedinstances-example-com.id}"]
}
output "node_security_group_ids" {
value = ["${aws_security_group.nodes-mixedinstances-example-com.id}"]
}
output "node_subnet_ids" {
value = ["${aws_subnet.us-test-1b-mixedinstances-example-com.id}"]
}
output "nodes_role_arn" {
value = "${aws_iam_role.nodes-mixedinstances-example-com.arn}"
}
output "nodes_role_name" {
value = "${aws_iam_role.nodes-mixedinstances-example-com.name}"
}
output "region" {
value = "us-test-1"
}
output "route_table_public_id" {
value = "${aws_route_table.mixedinstances-example-com.id}"
}
output "subnet_us-test-1a_id" {
value = "${aws_subnet.us-test-1a-mixedinstances-example-com.id}"
}
output "subnet_us-test-1b_id" {
value = "${aws_subnet.us-test-1b-mixedinstances-example-com.id}"
}
output "subnet_us-test-1c_id" {
value = "${aws_subnet.us-test-1c-mixedinstances-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.mixedinstances-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.mixedinstances-example-com.id}"
}
provider "aws" {
region = "us-test-1"
}
resource "aws_autoscaling_group" "master-us-test-1a-masters-mixedinstances-example-com" {
name = "master-us-test-1a.masters.mixedinstances.example.com"
launch_configuration = "${aws_launch_configuration.master-us-test-1a-masters-mixedinstances-example-com.id}"
max_size = 1
min_size = 1
vpc_zone_identifier = ["${aws_subnet.us-test-1a-mixedinstances-example-com.id}"]
tag = {
key = "KubernetesCluster"
value = "mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "Name"
value = "master-us-test-1a.masters.mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "k8s.io/role/master"
value = "1"
propagate_at_launch = true
}
metrics_granularity = "1Minute"
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
}
resource "aws_autoscaling_group" "master-us-test-1b-masters-mixedinstances-example-com" {
name = "master-us-test-1b.masters.mixedinstances.example.com"
launch_configuration = "${aws_launch_configuration.master-us-test-1b-masters-mixedinstances-example-com.id}"
max_size = 1
min_size = 1
vpc_zone_identifier = ["${aws_subnet.us-test-1b-mixedinstances-example-com.id}"]
tag = {
key = "KubernetesCluster"
value = "mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "Name"
value = "master-us-test-1b.masters.mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "k8s.io/role/master"
value = "1"
propagate_at_launch = true
}
metrics_granularity = "1Minute"
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
}
resource "aws_autoscaling_group" "master-us-test-1c-masters-mixedinstances-example-com" {
name = "master-us-test-1c.masters.mixedinstances.example.com"
launch_configuration = "${aws_launch_configuration.master-us-test-1c-masters-mixedinstances-example-com.id}"
max_size = 1
min_size = 1
vpc_zone_identifier = ["${aws_subnet.us-test-1c-mixedinstances-example-com.id}"]
tag = {
key = "KubernetesCluster"
value = "mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "Name"
value = "master-us-test-1c.masters.mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "k8s.io/role/master"
value = "1"
propagate_at_launch = true
}
metrics_granularity = "1Minute"
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
}
resource "aws_autoscaling_group" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
max_size = 2
min_size = 2
mixed_instances_policy = {
launch_template = {
launch_template_specification = {
launch_template_id = "${aws_launch_template.nodes-mixedinstances-example-com.id}"
version = "${aws_launch_template.nodes-mixedinstances-example-com.latest_version}"
}
override = {
instance_type = "m5.large"
}
override = {
instance_type = "m5.xlarge"
}
override = {
instance_type = "t2.medium"
}
}
instances_distribution = {
on_demand_percentage_above_base_capacity = 5
spot_instance_pools = 3
}
}
vpc_zone_identifier = ["${aws_subnet.us-test-1b-mixedinstances-example-com.id}"]
tag = {
key = "KubernetesCluster"
value = "mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "Name"
value = "nodes.mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "k8s.io/role/node"
value = "1"
propagate_at_launch = true
}
metrics_granularity = "1Minute"
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
}
resource "aws_ebs_volume" "us-test-1a-etcd-events-mixedinstances-example-com" {
availability_zone = "us-test-1a"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1a.etcd-events.mixedinstances.example.com"
"k8s.io/etcd/events" = "us-test-1a/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1a-etcd-main-mixedinstances-example-com" {
availability_zone = "us-test-1a"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1a.etcd-main.mixedinstances.example.com"
"k8s.io/etcd/main" = "us-test-1a/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1b-etcd-events-mixedinstances-example-com" {
availability_zone = "us-test-1b"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1b.etcd-events.mixedinstances.example.com"
"k8s.io/etcd/events" = "us-test-1b/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1b-etcd-main-mixedinstances-example-com" {
availability_zone = "us-test-1b"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1b.etcd-main.mixedinstances.example.com"
"k8s.io/etcd/main" = "us-test-1b/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1c-etcd-events-mixedinstances-example-com" {
availability_zone = "us-test-1c"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1c.etcd-events.mixedinstances.example.com"
"k8s.io/etcd/events" = "us-test-1c/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1c-etcd-main-mixedinstances-example-com" {
availability_zone = "us-test-1c"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1c.etcd-main.mixedinstances.example.com"
"k8s.io/etcd/main" = "us-test-1c/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_iam_instance_profile" "masters-mixedinstances-example-com" {
name = "masters.mixedinstances.example.com"
role = "${aws_iam_role.masters-mixedinstances-example-com.name}"
}
resource "aws_iam_instance_profile" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
role = "${aws_iam_role.nodes-mixedinstances-example-com.name}"
}
resource "aws_iam_role" "masters-mixedinstances-example-com" {
name = "masters.mixedinstances.example.com"
assume_role_policy = "${file("${path.module}/data/aws_iam_role_masters.mixedinstances.example.com_policy")}"
}
resource "aws_iam_role" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
assume_role_policy = "${file("${path.module}/data/aws_iam_role_nodes.mixedinstances.example.com_policy")}"
}
resource "aws_iam_role_policy" "masters-mixedinstances-example-com" {
name = "masters.mixedinstances.example.com"
role = "${aws_iam_role.masters-mixedinstances-example-com.name}"
policy = "${file("${path.module}/data/aws_iam_role_policy_masters.mixedinstances.example.com_policy")}"
}
resource "aws_iam_role_policy" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
role = "${aws_iam_role.nodes-mixedinstances-example-com.name}"
policy = "${file("${path.module}/data/aws_iam_role_policy_nodes.mixedinstances.example.com_policy")}"
}
resource "aws_internet_gateway" "mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_key_pair" "kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157" {
key_name = "kubernetes.mixedinstances.example.com-c4:a6:ed:9a:a8:89:b9:e2:c3:9c:d6:63:eb:9c:71:57"
public_key = "${file("${path.module}/data/aws_key_pair_kubernetes.mixedinstances.example.com-c4a6ed9aa889b9e2c39cd663eb9c7157_public_key")}"
}
resource "aws_launch_configuration" "master-us-test-1a-masters-mixedinstances-example-com" {
name_prefix = "master-us-test-1a.masters.mixedinstances.example.com-"
image_id = "ami-12345678"
instance_type = "m3.medium"
key_name = "${aws_key_pair.kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
iam_instance_profile = "${aws_iam_instance_profile.masters-mixedinstances-example-com.id}"
security_groups = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
associate_public_ip_address = true
user_data = "${file("${path.module}/data/aws_launch_configuration_master-us-test-1a.masters.mixedinstances.example.com_user_data")}"
root_block_device = {
volume_type = "gp2"
volume_size = 64
delete_on_termination = true
}
ephemeral_block_device = {
device_name = "/dev/sdc"
virtual_name = "ephemeral0"
}
lifecycle = {
create_before_destroy = true
}
enable_monitoring = false
}
resource "aws_launch_configuration" "master-us-test-1b-masters-mixedinstances-example-com" {
name_prefix = "master-us-test-1b.masters.mixedinstances.example.com-"
image_id = "ami-12345678"
instance_type = "m3.medium"
key_name = "${aws_key_pair.kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
iam_instance_profile = "${aws_iam_instance_profile.masters-mixedinstances-example-com.id}"
security_groups = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
associate_public_ip_address = true
user_data = "${file("${path.module}/data/aws_launch_configuration_master-us-test-1b.masters.mixedinstances.example.com_user_data")}"
root_block_device = {
volume_type = "gp2"
volume_size = 64
delete_on_termination = true
}
ephemeral_block_device = {
device_name = "/dev/sdc"
virtual_name = "ephemeral0"
}
lifecycle = {
create_before_destroy = true
}
enable_monitoring = false
}
resource "aws_launch_configuration" "master-us-test-1c-masters-mixedinstances-example-com" {
name_prefix = "master-us-test-1c.masters.mixedinstances.example.com-"
image_id = "ami-12345678"
instance_type = "m3.medium"
key_name = "${aws_key_pair.kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
iam_instance_profile = "${aws_iam_instance_profile.masters-mixedinstances-example-com.id}"
security_groups = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
associate_public_ip_address = true
user_data = "${file("${path.module}/data/aws_launch_configuration_master-us-test-1c.masters.mixedinstances.example.com_user_data")}"
root_block_device = {
volume_type = "gp2"
volume_size = 64
delete_on_termination = true
}
ephemeral_block_device = {
device_name = "/dev/sdc"
virtual_name = "ephemeral0"
}
lifecycle = {
create_before_destroy = true
}
enable_monitoring = false
}
resource "aws_launch_template" "nodes-mixedinstances-example-com" {
name_prefix = "nodes.mixedinstances.example.com-"
lifecycle = {
create_before_destroy = true
}
block_device_mappings = {
device_name = "/dev/xvda"
ebs = {
volume_type = "gp2"
volume_size = 128
delete_on_termination = true
}
}
iam_instance_profile = {
name = "${aws_iam_instance_profile.nodes-mixedinstances-example-com.id}"
}
image_id = "ami-12345678"
instance_type = "t2.medium"
key_name = "${aws_key_pair.kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
network_interfaces = {
associate_public_ip_address = true
delete_on_termination = true
security_groups = ["${aws_security_group.nodes-mixedinstances-example-com.id}"]
}
user_data = "${file("${path.module}/data/aws_launch_template_nodes.mixedinstances.example.com_user_data")}"
}
resource "aws_route" "0-0-0-0--0" {
route_table_id = "${aws_route_table.mixedinstances-example-com.id}"
destination_cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.mixedinstances-example-com.id}"
}
resource "aws_route_table" "mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
"kubernetes.io/kops/role" = "public"
}
}
resource "aws_route_table_association" "us-test-1a-mixedinstances-example-com" {
subnet_id = "${aws_subnet.us-test-1a-mixedinstances-example-com.id}"
route_table_id = "${aws_route_table.mixedinstances-example-com.id}"
}
resource "aws_route_table_association" "us-test-1b-mixedinstances-example-com" {
subnet_id = "${aws_subnet.us-test-1b-mixedinstances-example-com.id}"
route_table_id = "${aws_route_table.mixedinstances-example-com.id}"
}
resource "aws_route_table_association" "us-test-1c-mixedinstances-example-com" {
subnet_id = "${aws_subnet.us-test-1c-mixedinstances-example-com.id}"
route_table_id = "${aws_route_table.mixedinstances-example-com.id}"
}
resource "aws_security_group" "masters-mixedinstances-example-com" {
name = "masters.mixedinstances.example.com"
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
description = "Security group for masters"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "masters.mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_security_group" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
description = "Security group for nodes"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "nodes.mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_security_group_rule" "all-master-to-master" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
}
resource "aws_security_group_rule" "all-master-to-node" {
type = "ingress"
security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
}
resource "aws_security_group_rule" "all-node-to-node" {
type = "ingress"
security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
}
resource "aws_security_group_rule" "https-external-to-master-0-0-0-0--0" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "master-egress" {
type = "egress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "node-egress" {
type = "egress"
security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "node-to-master-tcp-1-2379" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 1
to_port = 2379
protocol = "tcp"
}
resource "aws_security_group_rule" "node-to-master-tcp-2382-4000" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 2382
to_port = 4000
protocol = "tcp"
}
resource "aws_security_group_rule" "node-to-master-tcp-4003-65535" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 4003
to_port = 65535
protocol = "tcp"
}
resource "aws_security_group_rule" "node-to-master-udp-1-65535" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 1
to_port = 65535
protocol = "udp"
}
resource "aws_security_group_rule" "ssh-external-to-master-0-0-0-0--0" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "ssh-external-to-node-0-0-0-0--0" {
type = "ingress"
security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_subnet" "us-test-1a-mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
cidr_block = "10.0.1.0/24"
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1a.mixedinstances.example.com"
SubnetType = "Public"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
"kubernetes.io/role/elb" = "1"
}
}
resource "aws_subnet" "us-test-1b-mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
cidr_block = "10.0.2.0/24"
availability_zone = "us-test-1b"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1b.mixedinstances.example.com"
SubnetType = "Public"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
"kubernetes.io/role/elb" = "1"
}
}
resource "aws_subnet" "us-test-1c-mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
cidr_block = "10.0.3.0/24"
availability_zone = "us-test-1c"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1c.mixedinstances.example.com"
SubnetType = "Public"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
"kubernetes.io/role/elb" = "1"
}
}
resource "aws_vpc" "mixedinstances-example-com" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_vpc_dhcp_options" "mixedinstances-example-com" {
domain_name = "us-test-1.compute.internal"
domain_name_servers = ["AmazonProvidedDNS"]
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_vpc_dhcp_options_association" "mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
dhcp_options_id = "${aws_vpc_dhcp_options.mixedinstances-example-com.id}"
}
terraform = {
required_version = ">= 0.9.3"
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAAAgQCtWu40XQo8dczLsCq0OWV+hxm9uV3WxeH9Kgh4sMzQxNtoU1pvW0XdjpkBesRKGoolfWeCLXWxpyQb1IaiMkKoz7MdhQ/6UKjMjP66aFWWp3pwD0uj0HuJ7tq4gKHKRYGTaZIRWpzUiANBrjugVgA+Sd7E/mYwc/DMXkIyRZbvhQ==

View File

@ -0,0 +1,136 @@
apiVersion: kops.k8s.io/v1alpha2
kind: Cluster
metadata:
creationTimestamp: "2016-12-10T22:42:27Z"
name: mixedinstances.example.com
spec:
kubernetesApiAccess:
- 0.0.0.0/0
channel: stable
cloudProvider: aws
configBase: memfs://clusters.example.com/mixedinstances.example.com
etcdClusters:
- etcdMembers:
- instanceGroup: master-us-test-1a
name: us-test-1a
- instanceGroup: master-us-test-1b
name: us-test-1b
- instanceGroup: master-us-test-1c
name: us-test-1c
name: main
- etcdMembers:
- instanceGroup: master-us-test-1a
name: us-test-1a
- instanceGroup: master-us-test-1b
name: us-test-1b
- instanceGroup: master-us-test-1c
name: us-test-1c
name: events
kubernetesVersion: v1.12.9
masterInternalName: api.internal.mixedinstances.example.com
masterPublicName: api.mixedinstances.example.com
networkCIDR: 10.0.0.0/16
networking:
kubenet: {}
nonMasqueradeCIDR: 100.64.0.0/10
sshAccess:
- 0.0.0.0/0
topology:
masters: public
nodes: public
subnets:
- cidr: 10.0.1.0/24
name: us-test-1a
type: Public
zone: us-test-1a
- cidr: 10.0.2.0/24
name: us-test-1b
type: Public
zone: us-test-1b
- cidr: 10.0.3.0/24
name: us-test-1c
type: Public
zone: us-test-1c
---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2016-12-10T22:42:28Z"
name: nodes
labels:
kops.k8s.io/cluster: mixedinstances.example.com
spec:
associatePublicIp: true
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
machineType: t2.medium
maxSize: 2
minSize: 2
role: Node
subnets:
- us-test-1b
maxPrice: "0.1"
mixedInstancesPolicy:
instances:
- m5.large
- m5.xlarge
- t2.medium
onDemandAboveBase: 5
spotInstancePools: 3
---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2016-12-10T22:42:28Z"
name: master-us-test-1a
labels:
kops.k8s.io/cluster: mixedinstances.example.com
spec:
associatePublicIp: true
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
machineType: m3.medium
maxSize: 1
minSize: 1
role: Master
subnets:
- us-test-1a
---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2016-12-10T22:42:28Z"
name: master-us-test-1b
labels:
kops.k8s.io/cluster: mixedinstances.example.com
spec:
associatePublicIp: true
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
machineType: m3.medium
maxSize: 1
minSize: 1
role: Master
subnets:
- us-test-1b
---
apiVersion: kops.k8s.io/v1alpha2
kind: InstanceGroup
metadata:
creationTimestamp: "2016-12-10T22:42:28Z"
name: master-us-test-1c
labels:
kops.k8s.io/cluster: mixedinstances.example.com
spec:
associatePublicIp: true
image: kope.io/k8s-1.4-debian-jessie-amd64-hvm-ebs-2016-10-21
machineType: m3.medium
maxSize: 1
minSize: 1
role: Master
subnets:
- us-test-1c

View File

@ -0,0 +1,727 @@
locals = {
cluster_name = "mixedinstances.example.com"
master_autoscaling_group_ids = ["${aws_autoscaling_group.master-us-test-1a-masters-mixedinstances-example-com.id}", "${aws_autoscaling_group.master-us-test-1b-masters-mixedinstances-example-com.id}", "${aws_autoscaling_group.master-us-test-1c-masters-mixedinstances-example-com.id}"]
master_security_group_ids = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
masters_role_arn = "${aws_iam_role.masters-mixedinstances-example-com.arn}"
masters_role_name = "${aws_iam_role.masters-mixedinstances-example-com.name}"
node_autoscaling_group_ids = ["${aws_autoscaling_group.nodes-mixedinstances-example-com.id}"]
node_security_group_ids = ["${aws_security_group.nodes-mixedinstances-example-com.id}"]
node_subnet_ids = ["${aws_subnet.us-test-1b-mixedinstances-example-com.id}"]
nodes_role_arn = "${aws_iam_role.nodes-mixedinstances-example-com.arn}"
nodes_role_name = "${aws_iam_role.nodes-mixedinstances-example-com.name}"
region = "us-test-1"
route_table_public_id = "${aws_route_table.mixedinstances-example-com.id}"
subnet_us-test-1a_id = "${aws_subnet.us-test-1a-mixedinstances-example-com.id}"
subnet_us-test-1b_id = "${aws_subnet.us-test-1b-mixedinstances-example-com.id}"
subnet_us-test-1c_id = "${aws_subnet.us-test-1c-mixedinstances-example-com.id}"
vpc_cidr_block = "${aws_vpc.mixedinstances-example-com.cidr_block}"
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
}
output "cluster_name" {
value = "mixedinstances.example.com"
}
output "master_autoscaling_group_ids" {
value = ["${aws_autoscaling_group.master-us-test-1a-masters-mixedinstances-example-com.id}", "${aws_autoscaling_group.master-us-test-1b-masters-mixedinstances-example-com.id}", "${aws_autoscaling_group.master-us-test-1c-masters-mixedinstances-example-com.id}"]
}
output "master_security_group_ids" {
value = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
}
output "masters_role_arn" {
value = "${aws_iam_role.masters-mixedinstances-example-com.arn}"
}
output "masters_role_name" {
value = "${aws_iam_role.masters-mixedinstances-example-com.name}"
}
output "node_autoscaling_group_ids" {
value = ["${aws_autoscaling_group.nodes-mixedinstances-example-com.id}"]
}
output "node_security_group_ids" {
value = ["${aws_security_group.nodes-mixedinstances-example-com.id}"]
}
output "node_subnet_ids" {
value = ["${aws_subnet.us-test-1b-mixedinstances-example-com.id}"]
}
output "nodes_role_arn" {
value = "${aws_iam_role.nodes-mixedinstances-example-com.arn}"
}
output "nodes_role_name" {
value = "${aws_iam_role.nodes-mixedinstances-example-com.name}"
}
output "region" {
value = "us-test-1"
}
output "route_table_public_id" {
value = "${aws_route_table.mixedinstances-example-com.id}"
}
output "subnet_us-test-1a_id" {
value = "${aws_subnet.us-test-1a-mixedinstances-example-com.id}"
}
output "subnet_us-test-1b_id" {
value = "${aws_subnet.us-test-1b-mixedinstances-example-com.id}"
}
output "subnet_us-test-1c_id" {
value = "${aws_subnet.us-test-1c-mixedinstances-example-com.id}"
}
output "vpc_cidr_block" {
value = "${aws_vpc.mixedinstances-example-com.cidr_block}"
}
output "vpc_id" {
value = "${aws_vpc.mixedinstances-example-com.id}"
}
provider "aws" {
region = "us-test-1"
}
resource "aws_autoscaling_group" "master-us-test-1a-masters-mixedinstances-example-com" {
name = "master-us-test-1a.masters.mixedinstances.example.com"
launch_configuration = "${aws_launch_configuration.master-us-test-1a-masters-mixedinstances-example-com.id}"
max_size = 1
min_size = 1
vpc_zone_identifier = ["${aws_subnet.us-test-1a-mixedinstances-example-com.id}"]
tag = {
key = "KubernetesCluster"
value = "mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "Name"
value = "master-us-test-1a.masters.mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "k8s.io/role/master"
value = "1"
propagate_at_launch = true
}
metrics_granularity = "1Minute"
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
}
resource "aws_autoscaling_group" "master-us-test-1b-masters-mixedinstances-example-com" {
name = "master-us-test-1b.masters.mixedinstances.example.com"
launch_configuration = "${aws_launch_configuration.master-us-test-1b-masters-mixedinstances-example-com.id}"
max_size = 1
min_size = 1
vpc_zone_identifier = ["${aws_subnet.us-test-1b-mixedinstances-example-com.id}"]
tag = {
key = "KubernetesCluster"
value = "mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "Name"
value = "master-us-test-1b.masters.mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "k8s.io/role/master"
value = "1"
propagate_at_launch = true
}
metrics_granularity = "1Minute"
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
}
resource "aws_autoscaling_group" "master-us-test-1c-masters-mixedinstances-example-com" {
name = "master-us-test-1c.masters.mixedinstances.example.com"
launch_configuration = "${aws_launch_configuration.master-us-test-1c-masters-mixedinstances-example-com.id}"
max_size = 1
min_size = 1
vpc_zone_identifier = ["${aws_subnet.us-test-1c-mixedinstances-example-com.id}"]
tag = {
key = "KubernetesCluster"
value = "mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "Name"
value = "master-us-test-1c.masters.mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "k8s.io/role/master"
value = "1"
propagate_at_launch = true
}
metrics_granularity = "1Minute"
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
}
resource "aws_autoscaling_group" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
max_size = 2
min_size = 2
mixed_instances_policy = {
launch_template = {
launch_template_specification = {
launch_template_id = "${aws_launch_template.nodes-mixedinstances-example-com.id}"
version = "${aws_launch_template.nodes-mixedinstances-example-com.latest_version}"
}
override = {
instance_type = "m5.large"
}
override = {
instance_type = "m5.xlarge"
}
override = {
instance_type = "t2.medium"
}
}
instances_distribution = {
on_demand_percentage_above_base_capacity = 5
spot_instance_pools = 3
spot_max_price = "0.1"
}
}
vpc_zone_identifier = ["${aws_subnet.us-test-1b-mixedinstances-example-com.id}"]
tag = {
key = "KubernetesCluster"
value = "mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "Name"
value = "nodes.mixedinstances.example.com"
propagate_at_launch = true
}
tag = {
key = "k8s.io/role/node"
value = "1"
propagate_at_launch = true
}
metrics_granularity = "1Minute"
enabled_metrics = ["GroupDesiredCapacity", "GroupInServiceInstances", "GroupMaxSize", "GroupMinSize", "GroupPendingInstances", "GroupStandbyInstances", "GroupTerminatingInstances", "GroupTotalInstances"]
}
resource "aws_ebs_volume" "us-test-1a-etcd-events-mixedinstances-example-com" {
availability_zone = "us-test-1a"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1a.etcd-events.mixedinstances.example.com"
"k8s.io/etcd/events" = "us-test-1a/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1a-etcd-main-mixedinstances-example-com" {
availability_zone = "us-test-1a"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1a.etcd-main.mixedinstances.example.com"
"k8s.io/etcd/main" = "us-test-1a/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1b-etcd-events-mixedinstances-example-com" {
availability_zone = "us-test-1b"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1b.etcd-events.mixedinstances.example.com"
"k8s.io/etcd/events" = "us-test-1b/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1b-etcd-main-mixedinstances-example-com" {
availability_zone = "us-test-1b"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1b.etcd-main.mixedinstances.example.com"
"k8s.io/etcd/main" = "us-test-1b/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1c-etcd-events-mixedinstances-example-com" {
availability_zone = "us-test-1c"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1c.etcd-events.mixedinstances.example.com"
"k8s.io/etcd/events" = "us-test-1c/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_ebs_volume" "us-test-1c-etcd-main-mixedinstances-example-com" {
availability_zone = "us-test-1c"
size = 20
type = "gp2"
encrypted = false
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1c.etcd-main.mixedinstances.example.com"
"k8s.io/etcd/main" = "us-test-1c/us-test-1a,us-test-1b,us-test-1c"
"k8s.io/role/master" = "1"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_iam_instance_profile" "masters-mixedinstances-example-com" {
name = "masters.mixedinstances.example.com"
role = "${aws_iam_role.masters-mixedinstances-example-com.name}"
}
resource "aws_iam_instance_profile" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
role = "${aws_iam_role.nodes-mixedinstances-example-com.name}"
}
resource "aws_iam_role" "masters-mixedinstances-example-com" {
name = "masters.mixedinstances.example.com"
assume_role_policy = "${file("${path.module}/data/aws_iam_role_masters.mixedinstances.example.com_policy")}"
}
resource "aws_iam_role" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
assume_role_policy = "${file("${path.module}/data/aws_iam_role_nodes.mixedinstances.example.com_policy")}"
}
resource "aws_iam_role_policy" "masters-mixedinstances-example-com" {
name = "masters.mixedinstances.example.com"
role = "${aws_iam_role.masters-mixedinstances-example-com.name}"
policy = "${file("${path.module}/data/aws_iam_role_policy_masters.mixedinstances.example.com_policy")}"
}
resource "aws_iam_role_policy" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
role = "${aws_iam_role.nodes-mixedinstances-example-com.name}"
policy = "${file("${path.module}/data/aws_iam_role_policy_nodes.mixedinstances.example.com_policy")}"
}
resource "aws_internet_gateway" "mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_key_pair" "kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157" {
key_name = "kubernetes.mixedinstances.example.com-c4:a6:ed:9a:a8:89:b9:e2:c3:9c:d6:63:eb:9c:71:57"
public_key = "${file("${path.module}/data/aws_key_pair_kubernetes.mixedinstances.example.com-c4a6ed9aa889b9e2c39cd663eb9c7157_public_key")}"
}
resource "aws_launch_configuration" "master-us-test-1a-masters-mixedinstances-example-com" {
name_prefix = "master-us-test-1a.masters.mixedinstances.example.com-"
image_id = "ami-12345678"
instance_type = "m3.medium"
key_name = "${aws_key_pair.kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
iam_instance_profile = "${aws_iam_instance_profile.masters-mixedinstances-example-com.id}"
security_groups = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
associate_public_ip_address = true
user_data = "${file("${path.module}/data/aws_launch_configuration_master-us-test-1a.masters.mixedinstances.example.com_user_data")}"
root_block_device = {
volume_type = "gp2"
volume_size = 64
delete_on_termination = true
}
ephemeral_block_device = {
device_name = "/dev/sdc"
virtual_name = "ephemeral0"
}
lifecycle = {
create_before_destroy = true
}
enable_monitoring = false
}
resource "aws_launch_configuration" "master-us-test-1b-masters-mixedinstances-example-com" {
name_prefix = "master-us-test-1b.masters.mixedinstances.example.com-"
image_id = "ami-12345678"
instance_type = "m3.medium"
key_name = "${aws_key_pair.kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
iam_instance_profile = "${aws_iam_instance_profile.masters-mixedinstances-example-com.id}"
security_groups = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
associate_public_ip_address = true
user_data = "${file("${path.module}/data/aws_launch_configuration_master-us-test-1b.masters.mixedinstances.example.com_user_data")}"
root_block_device = {
volume_type = "gp2"
volume_size = 64
delete_on_termination = true
}
ephemeral_block_device = {
device_name = "/dev/sdc"
virtual_name = "ephemeral0"
}
lifecycle = {
create_before_destroy = true
}
enable_monitoring = false
}
resource "aws_launch_configuration" "master-us-test-1c-masters-mixedinstances-example-com" {
name_prefix = "master-us-test-1c.masters.mixedinstances.example.com-"
image_id = "ami-12345678"
instance_type = "m3.medium"
key_name = "${aws_key_pair.kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
iam_instance_profile = "${aws_iam_instance_profile.masters-mixedinstances-example-com.id}"
security_groups = ["${aws_security_group.masters-mixedinstances-example-com.id}"]
associate_public_ip_address = true
user_data = "${file("${path.module}/data/aws_launch_configuration_master-us-test-1c.masters.mixedinstances.example.com_user_data")}"
root_block_device = {
volume_type = "gp2"
volume_size = 64
delete_on_termination = true
}
ephemeral_block_device = {
device_name = "/dev/sdc"
virtual_name = "ephemeral0"
}
lifecycle = {
create_before_destroy = true
}
enable_monitoring = false
}
resource "aws_launch_template" "nodes-mixedinstances-example-com" {
name_prefix = "nodes.mixedinstances.example.com-"
lifecycle = {
create_before_destroy = true
}
block_device_mappings = {
device_name = "/dev/xvda"
ebs = {
volume_type = "gp2"
volume_size = 128
delete_on_termination = true
}
}
iam_instance_profile = {
name = "${aws_iam_instance_profile.nodes-mixedinstances-example-com.id}"
}
image_id = "ami-12345678"
instance_type = "t2.medium"
key_name = "${aws_key_pair.kubernetes-mixedinstances-example-com-c4a6ed9aa889b9e2c39cd663eb9c7157.id}"
network_interfaces = {
associate_public_ip_address = true
delete_on_termination = true
security_groups = ["${aws_security_group.nodes-mixedinstances-example-com.id}"]
}
user_data = "${file("${path.module}/data/aws_launch_template_nodes.mixedinstances.example.com_user_data")}"
}
resource "aws_route" "0-0-0-0--0" {
route_table_id = "${aws_route_table.mixedinstances-example-com.id}"
destination_cidr_block = "0.0.0.0/0"
gateway_id = "${aws_internet_gateway.mixedinstances-example-com.id}"
}
resource "aws_route_table" "mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
"kubernetes.io/kops/role" = "public"
}
}
resource "aws_route_table_association" "us-test-1a-mixedinstances-example-com" {
subnet_id = "${aws_subnet.us-test-1a-mixedinstances-example-com.id}"
route_table_id = "${aws_route_table.mixedinstances-example-com.id}"
}
resource "aws_route_table_association" "us-test-1b-mixedinstances-example-com" {
subnet_id = "${aws_subnet.us-test-1b-mixedinstances-example-com.id}"
route_table_id = "${aws_route_table.mixedinstances-example-com.id}"
}
resource "aws_route_table_association" "us-test-1c-mixedinstances-example-com" {
subnet_id = "${aws_subnet.us-test-1c-mixedinstances-example-com.id}"
route_table_id = "${aws_route_table.mixedinstances-example-com.id}"
}
resource "aws_security_group" "masters-mixedinstances-example-com" {
name = "masters.mixedinstances.example.com"
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
description = "Security group for masters"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "masters.mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_security_group" "nodes-mixedinstances-example-com" {
name = "nodes.mixedinstances.example.com"
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
description = "Security group for nodes"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "nodes.mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_security_group_rule" "all-master-to-master" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
}
resource "aws_security_group_rule" "all-master-to-node" {
type = "ingress"
security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
}
resource "aws_security_group_rule" "all-node-to-node" {
type = "ingress"
security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
}
resource "aws_security_group_rule" "https-external-to-master-0-0-0-0--0" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 443
to_port = 443
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "master-egress" {
type = "egress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "node-egress" {
type = "egress"
security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 0
to_port = 0
protocol = "-1"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "node-to-master-tcp-1-2379" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 1
to_port = 2379
protocol = "tcp"
}
resource "aws_security_group_rule" "node-to-master-tcp-2382-4000" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 2382
to_port = 4000
protocol = "tcp"
}
resource "aws_security_group_rule" "node-to-master-tcp-4003-65535" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 4003
to_port = 65535
protocol = "tcp"
}
resource "aws_security_group_rule" "node-to-master-udp-1-65535" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
source_security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 1
to_port = 65535
protocol = "udp"
}
resource "aws_security_group_rule" "ssh-external-to-master-0-0-0-0--0" {
type = "ingress"
security_group_id = "${aws_security_group.masters-mixedinstances-example-com.id}"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_security_group_rule" "ssh-external-to-node-0-0-0-0--0" {
type = "ingress"
security_group_id = "${aws_security_group.nodes-mixedinstances-example-com.id}"
from_port = 22
to_port = 22
protocol = "tcp"
cidr_blocks = ["0.0.0.0/0"]
}
resource "aws_subnet" "us-test-1a-mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
cidr_block = "10.0.1.0/24"
availability_zone = "us-test-1a"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1a.mixedinstances.example.com"
SubnetType = "Public"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
"kubernetes.io/role/elb" = "1"
}
}
resource "aws_subnet" "us-test-1b-mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
cidr_block = "10.0.2.0/24"
availability_zone = "us-test-1b"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1b.mixedinstances.example.com"
SubnetType = "Public"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
"kubernetes.io/role/elb" = "1"
}
}
resource "aws_subnet" "us-test-1c-mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
cidr_block = "10.0.3.0/24"
availability_zone = "us-test-1c"
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "us-test-1c.mixedinstances.example.com"
SubnetType = "Public"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
"kubernetes.io/role/elb" = "1"
}
}
resource "aws_vpc" "mixedinstances-example-com" {
cidr_block = "10.0.0.0/16"
enable_dns_hostnames = true
enable_dns_support = true
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_vpc_dhcp_options" "mixedinstances-example-com" {
domain_name = "us-test-1.compute.internal"
domain_name_servers = ["AmazonProvidedDNS"]
tags = {
KubernetesCluster = "mixedinstances.example.com"
Name = "mixedinstances.example.com"
"kubernetes.io/cluster/mixedinstances.example.com" = "owned"
}
}
resource "aws_vpc_dhcp_options_association" "mixedinstances-example-com" {
vpc_id = "${aws_vpc.mixedinstances-example-com.id}"
dhcp_options_id = "${aws_vpc_dhcp_options.mixedinstances-example-com.id}"
}
terraform = {
required_version = ">= 0.9.3"
}

View File

@ -72,6 +72,8 @@ type AutoscalingGroup struct {
// MixedSpotInstancePools is the number of Spot pools to use to allocate your Spot capacity (defaults to 2)
// pools are determined from the different instance types in the Overrides array of LaunchTemplate
MixedSpotInstancePools *int64
// MixedSpotMaxPrice is the maximum price per unit hour you are willing to pay for a Spot Instance
MixedSpotMaxPrice *string
// Subnets is a collection of subnets to attach the nodes to
Subnets []*Subnet
// SuspendProcesses
@ -141,6 +143,7 @@ func (e *AutoscalingGroup) Find(c *fi.Context) (*AutoscalingGroup, error) {
actual.MixedOnDemandBase = mpd.OnDemandBaseCapacity
actual.MixedSpotAllocationStrategy = mpd.SpotAllocationStrategy
actual.MixedSpotInstancePools = mpd.SpotInstancePools
actual.MixedSpotMaxPrice = mpd.SpotMaxPrice
}
if g.MixedInstancesPolicy.LaunchTemplate != nil {
@ -272,6 +275,7 @@ func (v *AutoscalingGroup) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Autos
OnDemandBaseCapacity: e.MixedOnDemandBase,
SpotAllocationStrategy: e.MixedSpotAllocationStrategy,
SpotInstancePools: e.MixedSpotInstancePools,
SpotMaxPrice: e.MixedSpotMaxPrice,
},
LaunchTemplate: &autoscaling.LaunchTemplate{
LaunchTemplateSpecification: &autoscaling.LaunchTemplateSpecification{LaunchTemplateName: e.LaunchTemplate.ID},
@ -358,6 +362,10 @@ func (v *AutoscalingGroup) RenderAWS(t *awsup.AWSAPITarget, a, e, changes *Autos
setup(request).InstancesDistribution.SpotInstancePools = e.MixedSpotInstancePools
changes.MixedSpotInstancePools = nil
}
if changes.MixedSpotMaxPrice != nil {
setup(request).InstancesDistribution.SpotMaxPrice = e.MixedSpotMaxPrice
changes.MixedSpotMaxPrice = nil
}
if changes.MixedInstanceOverrides != nil {
if setup(request).LaunchTemplate == nil {
setup(request).LaunchTemplate = &autoscaling.LaunchTemplate{
@ -490,6 +498,9 @@ func (e *AutoscalingGroup) UseMixedInstancesPolicy() bool {
if len(e.MixedInstanceOverrides) > 0 {
return true
}
if e.MixedSpotMaxPrice != nil {
return true
}
return false
}
@ -596,7 +607,7 @@ type terraformAutoscalingInstanceDistribution struct {
// SpotInstancePool is the number of pools
SpotInstancePool *int64 `json:"spot_instance_pools,omitempty"`
// SpotMaxPrice is the max bid on spot instance, defaults to demand value
SpotMaxPrice *float64 `json:"spot_max_price,omitempty"`
SpotMaxPrice *string `json:"spot_max_price,omitempty"`
}
type terraformMixedInstancesPolicy struct {
@ -662,6 +673,7 @@ func (_ *AutoscalingGroup) RenderTerraform(t *terraform.TerraformTarget, a, e, c
OnDemandPercentageAboveBaseCapacity: e.MixedOnDemandAboveBase,
SpotAllocationStrategy: e.MixedSpotAllocationStrategy,
SpotInstancePool: e.MixedSpotInstancePools,
SpotMaxPrice: e.MixedSpotMaxPrice,
},
},
},
@ -672,39 +684,44 @@ func (_ *AutoscalingGroup) RenderTerraform(t *terraform.TerraformTarget, a, e, c
}
}
role := ""
for k := range e.Tags {
if strings.HasPrefix(k, CloudTagInstanceGroupRolePrefix) {
suffix := strings.TrimPrefix(k, CloudTagInstanceGroupRolePrefix)
if role != "" && role != suffix {
return fmt.Errorf("Found multiple role tags: %q vs %q", role, suffix)
}
role = suffix
}
}
if e.LaunchConfiguration != nil {
tf.LaunchConfigurationName = e.LaunchConfiguration.TerraformLink()
// Create TF output variable with security group ids
// This is in the launch configuration, but the ASG has the information about the instance group type
role := ""
for k := range e.Tags {
if strings.HasPrefix(k, CloudTagInstanceGroupRolePrefix) {
suffix := strings.TrimPrefix(k, CloudTagInstanceGroupRolePrefix)
if role != "" && role != suffix {
return fmt.Errorf("Found multiple role tags: %q vs %q", role, suffix)
}
role = suffix
}
}
if role != "" {
for _, sg := range e.LaunchConfiguration.SecurityGroups {
if err := t.AddOutputVariableArray(role+"_security_group_ids", sg.TerraformLink()); err != nil {
return err
}
}
if err := t.AddOutputVariableArray(role+"_autoscaling_group_ids", e.TerraformLink()); err != nil {
}
} else if e.LaunchTemplate != nil && role != "" {
for _, sg := range e.LaunchTemplate.SecurityGroups {
if err := t.AddOutputVariableArray(role+"_security_group_ids", sg.TerraformLink()); err != nil {
return err
}
}
if role == "node" {
for _, s := range e.Subnets {
if err := t.AddOutputVariableArray(role+"_subnet_ids", s.TerraformLink()); err != nil {
return err
}
}
if role != "" {
if err := t.AddOutputVariableArray(role+"_autoscaling_group_ids", e.TerraformLink()); err != nil {
return err
}
}
if role == "node" {
for _, s := range e.Subnets {
if err := t.AddOutputVariableArray(role+"_subnet_ids", s.TerraformLink()); err != nil {
return err
}
}
}
@ -765,7 +782,7 @@ type cloudformationAutoscalingInstanceDistribution struct {
// SpotInstancePool is the number of pools
SpotInstancePool *int64 `json:"SpotInstancePool,omitempty"`
// SpotMaxPrice is the max bid on spot instance, defaults to demand value
SpotMaxPrice *float64 `json:"SpotMaxPrice,omitempty"`
SpotMaxPrice *string `json:"SpotMaxPrice,omitempty"`
}
type cloudformationMixedInstancesPolicy struct {
@ -815,6 +832,7 @@ func (_ *AutoscalingGroup) RenderCloudformation(t *cloudformation.Cloudformation
OnDemandPercentageAboveBaseCapacity: e.MixedOnDemandAboveBase,
SpotAllocationStrategy: e.MixedSpotAllocationStrategy,
SpotInstancePool: e.MixedSpotInstancePools,
SpotMaxPrice: e.MixedSpotMaxPrice,
},
}