Permalink
Browse files

Added the ability to specify an IAM role for master and node instance…

…s on AWS.

under the aws_config for kube you can now set the following:

aws_config {
  master_role: role_name
  node_role: role_name
}

Also added the ability to set tags at the kube level that will tag any resources made for that kube.
It doesn't tag the S3 bucket (not sure if that is needed/wanted as it stores a single file)
This can be used with the following:

aws_config {
  tags: {tag_name: tag_value,
         another_tag: another_value}
}

No error checking is done on the tag for validity until it is applied, that is left to the user.
  • Loading branch information...
jordanrinke committed Sep 18, 2017
1 parent 30789b2 commit 014f945cd36095906fe7331805a6afebcb945789
Showing with 74 additions and 48 deletions.
  1. +16 −13 pkg/model/kube.go
  2. +43 −32 pkg/provider/aws/create_kube.go
  3. +9 −2 pkg/provider/aws/create_node.go
  4. +6 −1 pkg/provider/aws/provider.go
View
@@ -91,19 +91,22 @@ type AWSKubeConfig struct {
NodeVolumeSize int `json:"node_volume_size" sg:"default=100"`
MasterVolumeSize int `json:"master_volume_size" sg:"default=100"`
LastSelectedAZ string `json:"last_selected_az" sg:"readonly"` // if using multiAZ this is the last az the node build used.
PrivateKey string `json:"private_key,omitempty" sg:"readonly"`
VPCID string `json:"vpc_id"`
VPCMANAGED bool `json:"vpc_managed"`
InternetGatewayID string `json:"internet_gateway_id"`
RouteTableID string `json:"route_table_id"`
RouteTableSubnetAssociationID []string `json:"route_table_subnet_association_id" sg:"readonly"`
PrivateNetwork bool `json:"private_network"`
ELBSecurityGroupID string `json:"elb_security_group_id" sg:"readonly"`
NodeSecurityGroupID string `json:"node_security_group_id" sg:"readonly"`
ElasticFileSystemID string `json:"elastic_filesystem_id"`
ElasticFileSystemTargets []string `json:"elastic_filesystem_targets" sg:"readonly"`
BuildElasticFileSystem bool `json:"build_elastic_filesystem"`
MasterRoleName string `json:"master_role"`
NodeRoleName string `json:"node_role"`
Tags map[string]string `json:"tags"`
LastSelectedAZ string `json:"last_selected_az" sg:"readonly"` // if using multiAZ this is the last az the node build used.
PrivateKey string `json:"private_key,omitempty" sg:"readonly"`
VPCID string `json:"vpc_id"`
VPCMANAGED bool `json:"vpc_managed"`
InternetGatewayID string `json:"internet_gateway_id"`
RouteTableID string `json:"route_table_id"`
RouteTableSubnetAssociationID []string `json:"route_table_subnet_association_id" sg:"readonly"`
PrivateNetwork bool `json:"private_network"`
ELBSecurityGroupID string `json:"elb_security_group_id" sg:"readonly"`
NodeSecurityGroupID string `json:"node_security_group_id" sg:"readonly"`
ElasticFileSystemID string `json:"elastic_filesystem_id"`
ElasticFileSystemTargets []string `json:"elastic_filesystem_targets" sg:"readonly"`
BuildElasticFileSystem bool `json:"build_elastic_filesystem"`
}
// DOKubeConfig holds do specific information about DO based KUbernetes clusters.
@@ -94,8 +94,9 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
return err
}
procedure.AddStep("preparing IAM Role kubernetes-master", func() error {
policy := `{
if m.AWSConfig.MasterRoleName == "" {
procedure.AddStep("preparing IAM Role kubernetes-master", func() error {
policy := `{
"Version": "2012-10-17",
"Statement": [
{
@@ -105,11 +106,11 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
}
]
}`
return createIAMRole(iamS, "kubernetes-master", policy)
})
return createIAMRole(iamS, "kubernetes-master", policy)
})
procedure.AddStep("preparing IAM Role Policy kubernetes-master", func() error {
policy := `{
procedure.AddStep("preparing IAM Role Policy kubernetes-master", func() error {
policy := `{
"Version": "2012-10-17",
"Statement": [
{
@@ -136,15 +137,17 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
}
]
}`
return createIAMRolePolicy(iamS, "kubernetes-master", policy)
})
return createIAMRolePolicy(iamS, "kubernetes-master", policy)
})
procedure.AddStep("preparing IAM Instance Profile kubernetes-master", func() error {
return createIAMInstanceProfile(iamS, "kubernetes-master")
})
procedure.AddStep("preparing IAM Instance Profile kubernetes-master", func() error {
return createIAMInstanceProfile(iamS, "kubernetes-master")
})
}
procedure.AddStep("preparing IAM Role kubernetes-minion", func() error {
policy := `{
if m.AWSConfig.NodeRoleName == "" {
procedure.AddStep("preparing IAM Role kubernetes-minion", func() error {
policy := `{
"Version": "2012-10-17",
"Statement": [
{
@@ -154,11 +157,11 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
}
]
}`
return createIAMRole(iamS, "kubernetes-minion", policy)
})
return createIAMRole(iamS, "kubernetes-minion", policy)
})
procedure.AddStep("preparing IAM Role Policy kubernetes-minion", func() error {
policy := `{
procedure.AddStep("preparing IAM Role Policy kubernetes-minion", func() error {
policy := `{
"Version": "2012-10-17",
"Statement": [
{
@@ -203,13 +206,13 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
}
]
}`
return createIAMRolePolicy(iamS, "kubernetes-minion", policy)
})
procedure.AddStep("preparing IAM Instance Profile kubernetes-minion", func() error {
return createIAMInstanceProfile(iamS, "kubernetes-minion")
})
return createIAMRolePolicy(iamS, "kubernetes-minion", policy)
})
procedure.AddStep("preparing IAM Instance Profile kubernetes-minion", func() error {
return createIAMInstanceProfile(iamS, "kubernetes-minion")
})
}
if m.AWSConfig.BuildElasticFileSystem {
procedure.AddStep("creating EFS share", func() error {
@@ -320,7 +323,7 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
}
var userdata bytes.Buffer
if err = template.Execute(&userdata, m); err != nil {
if err = template.Execute(&userdata, m.AWSConfig.Tags); err != nil {
return err
}
@@ -367,7 +370,7 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
return tagAWSResource(ec2S, m.AWSConfig.VPCID, map[string]string{
"KubernetesCluster": m.Name,
"Name": m.Name + "-vpc",
})
}, m.AWSConfig.Tags)
})
procedure.AddStep("enabling VPC DNS", func() error {
@@ -403,7 +406,7 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
return tagAWSResource(ec2S, m.AWSConfig.InternetGatewayID, map[string]string{
"KubernetesCluster": m.Name,
"Name": m.Name + "-ig",
})
}, m.AWSConfig.Tags)
})
procedure.AddStep("attaching Internet Gateway to VPC", func() error {
@@ -465,7 +468,7 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
err := tagAWSResource(ec2S, subnet["subnet_id"], map[string]string{
"KubernetesCluster": m.Name,
"Name": m.Name + "-" + subnet["zone"] + "-psub",
})
}, m.AWSConfig.Tags)
if err != nil {
return err
}
@@ -517,7 +520,7 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
return tagAWSResource(ec2S, m.AWSConfig.RouteTableID, map[string]string{
"KubernetesCluster": m.Name,
"Name": m.Name + "-rt",
})
}, m.AWSConfig.Tags)
})
procedure.AddStep("associating Route Table with Subnet", func() error {
@@ -583,7 +586,7 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
procedure.AddStep("tagging ELB Security Group", func() error {
return tagAWSResource(ec2S, m.AWSConfig.ELBSecurityGroupID, map[string]string{
"KubernetesCluster": m.Name,
})
}, m.AWSConfig.Tags)
})
procedure.AddStep("creating ELB Security Group ingress rules", func() error {
@@ -660,7 +663,7 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
procedure.AddStep("tagging Node Security Group", func() error {
return tagAWSResource(ec2S, m.AWSConfig.NodeSecurityGroupID, map[string]string{
"KubernetesCluster": m.Name,
})
}, m.AWSConfig.Tags)
})
procedure.AddStep("creating Node Security Group ingress rules", func() error {
@@ -841,6 +844,14 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
time.Sleep(5 * time.Second)
procedure.Core.Log.Info("Building master #" + strconv.Itoa(i) + ", in subnet " + selectedSubnet + "...")
var masterRole *string
if m.AWSConfig.MasterRoleName != "" {
masterRole = aws.String(m.AWSConfig.MasterRoleName)
} else {
masterRole = aws.String("kubernetes-master")
}
resp, err := ec2S.RunInstances(&ec2.RunInstancesInput{
MinCount: aws.Int64(1),
MaxCount: aws.Int64(1),
@@ -860,7 +871,7 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
},
},
IamInstanceProfile: &ec2.IamInstanceProfileSpecification{
Name: aws.String("kubernetes-master"),
Name: masterRole,
},
BlockDeviceMappings: []*ec2.BlockDeviceMapping{
{
@@ -891,7 +902,7 @@ func (p *Provider) CreateKube(m *model.Kube, action *core.Action) error {
"KubernetesCluster": m.Name,
"Name": m.Name + "-master",
"Role": m.Name + "-master",
})
}, m.AWSConfig.Tags)
if err != nil {
return err
}
@@ -62,6 +62,13 @@ func (p *Provider) CreateNode(m *model.Node, action *core.Action) error {
selectedSubnet = subnets[(len(m.Kube.Nodes)-1)%len(m.Kube.AWSConfig.PublicSubnetIPRange)]
}
var nodeRole *string
if m.Kube.AWSConfig.NodeRoleName != "" {
nodeRole = aws.String(m.Kube.AWSConfig.NodeRoleName)
} else {
nodeRole = aws.String("kubernetes-minion")
}
resp, err := ec2S.RunInstances(&ec2.RunInstancesInput{
MinCount: aws.Int64(1),
MaxCount: aws.Int64(1),
@@ -73,7 +80,7 @@ func (p *Provider) CreateNode(m *model.Node, action *core.Action) error {
aws.String(m.Kube.AWSConfig.NodeSecurityGroupID),
},
IamInstanceProfile: &ec2.IamInstanceProfileSpecification{
Name: aws.String("kubernetes-minion"),
Name: nodeRole,
},
BlockDeviceMappings: []*ec2.BlockDeviceMapping{
&ec2.BlockDeviceMapping{
@@ -98,7 +105,7 @@ func (p *Provider) CreateNode(m *model.Node, action *core.Action) error {
"KubernetesCluster": m.Kube.Name,
"Name": m.Name,
"Role": m.Kube.Name + "-minion",
})
}, m.Kube.AWSConfig.Tags)
if err != nil {
// TODO
p.Core.Log.Error("Failed to tag EC2 Instance " + *server.InstanceId)
@@ -218,8 +218,13 @@ func createIAMInstanceProfile(iamS iamiface.IAMAPI, name string) error {
return nil
}
func tagAWSResource(ec2S ec2iface.EC2API, idstr string, tags map[string]string) error {
func tagAWSResource(ec2S ec2iface.EC2API, idstr string, tags map[string]string, confTags map[string]string) error {
var ec2Tags []*ec2.Tag
if len(confTags) != 0 {
for key, val := range confTags {
tags[key] = val
}
}
for key, val := range tags {
ec2Tags = append(ec2Tags, &ec2.Tag{
Key: aws.String(key),

0 comments on commit 014f945

Please sign in to comment.