Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions data/data/aws/bootstrap/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,12 @@ resource "aws_s3_bucket_object" "ignition" {
resource "aws_iam_instance_profile" "bootstrap" {
name = "${var.cluster_id}-bootstrap-profile"

role = aws_iam_role.bootstrap.name
role = var.iam_role_name != "" ? var.iam_role_name : aws_iam_role.bootstrap[0].name
}

resource "aws_iam_role" "bootstrap" {
count = var.iam_role_name == "" ? 1 : 0

name = "${var.cluster_id}-bootstrap-role"
path = "/"

Expand Down Expand Up @@ -78,8 +80,9 @@ EOF
}

resource "aws_iam_role_policy" "bootstrap" {
count = var.iam_role_name == "" ? 1 : 0
name = "${var.cluster_id}-bootstrap-policy"
role = aws_iam_role.bootstrap.id
role = aws_iam_role.bootstrap[0].id

policy = <<EOF
{
Expand All @@ -103,7 +106,6 @@ resource "aws_iam_role_policy" "bootstrap" {
]
}
EOF

}

resource "aws_instance" "bootstrap" {
Expand Down
5 changes: 5 additions & 0 deletions data/data/aws/bootstrap/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,8 @@ variable "publish_strategy" {
type = string
description = "The publishing strategy for endpoints like load balancers"
}

variable "iam_role_name" {
type = string
description = "The name of the existing role to use for the instance profile"
}
10 changes: 6 additions & 4 deletions data/data/aws/iam/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,13 @@ data "aws_partition" "current" {}
resource "aws_iam_instance_profile" "worker" {
name = "${var.cluster_id}-worker-profile"

role = aws_iam_role.worker_role.name
role = var.worker_iam_role_name != "" ? var.worker_iam_role_name : aws_iam_role.worker_role[0].name
}

resource "aws_iam_role" "worker_role" {
name = "${var.cluster_id}-worker-role"
path = "/"
count = var.worker_iam_role_name == "" ? 1 : 0
name = "${var.cluster_id}-worker-role"
path = "/"

assume_role_policy = <<EOF
{
Expand Down Expand Up @@ -46,8 +47,9 @@ resource "aws_iam_role_policy" "worker_policy" {
// clusters.
// Please see: docs/dev/aws/iam_permissions.md

Comment thread
smrowley marked this conversation as resolved.
Outdated
count = var.worker_iam_role_name == "" ? 1 : 0
name = "${var.cluster_id}-worker-policy"
role = aws_iam_role.worker_role.id
role = aws_iam_role.worker_role[0].id

policy = <<EOF
{
Expand Down
4 changes: 4 additions & 0 deletions data/data/aws/iam/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,7 @@ variable "tags" {
description = "AWS tags to be applied to created resources."
}

variable "worker_iam_role_name" {
type = string
description = "The name of the existing role to use for the instance profile for workers"
}
5 changes: 4 additions & 1 deletion data/data/aws/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ module "bootstrap" {
vpc_security_group_ids = [module.vpc.master_sg_id]
volume_kms_key_id = var.aws_master_root_volume_kms_key_id
publish_strategy = var.aws_publish_strategy
iam_role_name = var.aws_master_iam_role_name

tags = local.tags
}
Expand All @@ -66,12 +67,14 @@ module "masters" {
ec2_ami = var.aws_region == var.aws_ami_region ? var.aws_ami : aws_ami_copy.imported[0].id
user_data_ign = var.ignition_master
publish_strategy = var.aws_publish_strategy
iam_role_name = var.aws_master_iam_role_name
}

module "iam" {
source = "./iam"

cluster_id = var.cluster_id
cluster_id = var.cluster_id
worker_iam_role_name = var.aws_worker_iam_role_name

tags = local.tags
}
Expand Down
6 changes: 4 additions & 2 deletions data/data/aws/master/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ data "aws_ebs_default_kms_key" "current" {}
resource "aws_iam_instance_profile" "master" {
name = "${var.cluster_id}-master-profile"

role = aws_iam_role.master_role.name
role = var.iam_role_name != "" ? var.iam_role_name : aws_iam_role.master_role[0].name
}

resource "aws_iam_role" "master_role" {
count = var.iam_role_name == "" ? 1 : 0
name = "${var.cluster_id}-master-role"
path = "/"
description = local.description
Expand Down Expand Up @@ -52,8 +53,9 @@ resource "aws_iam_role_policy" "master_policy" {
// clusters.
// Please see: docs/dev/aws/iam_permissions.md

Comment thread
smrowley marked this conversation as resolved.
Outdated
count = var.iam_role_name == "" ? 1 : 0
name = "${var.cluster_id}-master-policy"
role = aws_iam_role.master_role.id
role = aws_iam_role.master_role[0].id

policy = <<EOF
{
Expand Down
5 changes: 5 additions & 0 deletions data/data/aws/master/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,8 @@ and therefore are force to implicitly assume that the list is of aws_lb_target_g
helps to decide if the target_group_arns is of length (target_group_arns_length) or (target_group_arns_length - 1)
EOF
}

variable "iam_role_name" {
type = string
description = "The name of the existing role to use for the instance profile"
}
12 changes: 12 additions & 0 deletions data/data/aws/variables-aws.tf
Original file line number Diff line number Diff line change
Expand Up @@ -148,3 +148,15 @@ The stub Ignition config that should be used to boot the bootstrap instance. Thi
specified in aws_ignition_bucket.
EOF
}

variable "aws_master_iam_role_name" {
type = string
description = "The name of the IAM role that will be attached to master instances."
default = ""
}

variable "aws_worker_iam_role_name" {
type = string
description = "The name of the IAM role that will be attached to worker instances."
default = ""
}
15 changes: 15 additions & 0 deletions data/data/install.openshift.io_installconfigs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,11 @@ spec:
the ec2 instance. If set, the AMI should belong to the
same region as the cluster.
type: string
iamRole:
description: IAMRole is the name of the IAM Role to use
for the instance profile of the machine. Leave unset to
have the installer create the IAM Role on your behalf.
type: string
rootVolume:
description: EC2RootVolume defines the root volume for EC2
instances in the machine pool.
Expand Down Expand Up @@ -439,6 +444,11 @@ spec:
the ec2 instance. If set, the AMI should belong to the same
region as the cluster.
type: string
iamRole:
description: IAMRole is the name of the IAM Role to use for
the instance profile of the machine. Leave unset to have
the installer create the IAM Role on your behalf.
type: string
rootVolume:
description: EC2RootVolume defines the root volume for EC2
instances in the machine pool.
Expand Down Expand Up @@ -921,6 +931,11 @@ spec:
the ec2 instance. If set, the AMI should belong to the same
region as the cluster.
type: string
iamRole:
description: IAMRole is the name of the IAM Role to use for
the instance profile of the machine. Leave unset to have
the installer create the IAM Role on your behalf.
type: string
rootVolume:
description: EC2RootVolume defines the root volume for EC2
instances in the machine pool.
Expand Down
71 changes: 61 additions & 10 deletions pkg/asset/cluster/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import (

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/ec2"
"github.com/aws/aws-sdk-go/service/iam"
"github.com/pkg/errors"

"github.com/openshift/installer/pkg/asset/installconfig"
"github.com/openshift/installer/pkg/types"
Expand All @@ -29,6 +31,19 @@ func Metadata(clusterID, infraID string, config *types.InstallConfig) *awstypes.
// PreTerraform performs any infrastructure initialization which must
// happen before Terraform creates the remaining infrastructure.
func PreTerraform(ctx context.Context, clusterID string, installConfig *installconfig.InstallConfig) error {

if err := tagSubnetEC2Instances(ctx, clusterID, installConfig); err != nil {
return err
}

if err := tagIamRoles(ctx, clusterID, installConfig); err != nil {
return err
}

return nil
}

func tagSubnetEC2Instances(ctx context.Context, clusterID string, installConfig *installconfig.InstallConfig) error {
if len(installConfig.Config.Platform.AWS.Subnets) == 0 {
return nil
}
Expand Down Expand Up @@ -56,21 +71,57 @@ func PreTerraform(ctx context.Context, clusterID string, installConfig *installc
if err != nil {
return err
}
key, value := sharedTag(clusterID)
ec2Tags := []*ec2.Tag{{Key: &key, Value: &value}}
ec2Client := ec2.New(session, aws.NewConfig().WithRegion(installConfig.Config.Platform.AWS.Region))

tags := []*ec2.Tag{
{
Key: aws.String(fmt.Sprintf("kubernetes.io/cluster/%s", clusterID)),
Value: aws.String("shared"),
},
}
client := ec2.New(session, aws.NewConfig().WithRegion(installConfig.Config.Platform.AWS.Region))

if _, err = client.CreateTagsWithContext(ctx, &ec2.CreateTagsInput{
if _, err = ec2Client.CreateTagsWithContext(ctx, &ec2.CreateTagsInput{
Resources: ids,
Tags: tags,
Tags: ec2Tags,
}); err != nil {
return err
}

return nil
}

func tagIamRoles(ctx context.Context, clusterID string, installConfig *installconfig.InstallConfig) error {
workerMachinePool := installConfig.Config.WorkerMachinePool()

var iamRoleNames []*string

if installConfig.Config.ControlPlane.Platform.AWS.IAMRole != "" {
iamRoleNames = append(iamRoleNames, &installConfig.Config.ControlPlane.Platform.AWS.IAMRole)
}

if workerMachinePool.Platform.AWS.IAMRole != "" {
iamRoleNames = append(iamRoleNames, &workerMachinePool.Platform.AWS.IAMRole)
}

if len(iamRoleNames) == 0 {
return nil
}

session, err := installConfig.AWS.Session(ctx)
if err != nil {
return err
}
key, value := sharedTag(clusterID)
iamTags := []*iam.Tag{{Key: &key, Value: &value}}
iamClient := iam.New(session, aws.NewConfig().WithRegion(installConfig.Config.Platform.AWS.Region))

for _, iamRoleName := range iamRoleNames {
if _, err := iamClient.TagRoleWithContext(ctx, &iam.TagRoleInput{
RoleName: iamRoleName,
Tags: iamTags,
}); err != nil {
return errors.Wrapf(err, "could not tag %s role", *iamRoleName)
}
}

return nil
}

func sharedTag(clusterID string) (string, string) {
return fmt.Sprintf("kubernetes.io/cluster/%s", clusterID), "shared"
}
14 changes: 14 additions & 0 deletions pkg/asset/cluster/tfvars.go
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,18 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
if len(osImage) == 2 {
osImageRegion = osImage[1]
}

workerMachinePool := installConfig.Config.WorkerMachinePool()
workerIAMRoleName := ""
if workerMachinePool.Platform.AWS != nil {
workerIAMRoleName = workerMachinePool.Platform.AWS.IAMRole
}

masterIAMRoleName := ""
if installConfig.Config.ControlPlane.Platform.AWS != nil {
masterIAMRoleName = installConfig.Config.ControlPlane.Platform.AWS.IAMRole
}

data, err := awstfvars.TFVars(awstfvars.TFVarsSources{
VPC: vpc,
PrivateSubnets: privateSubnets,
Expand All @@ -247,6 +259,8 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error {
IgnitionBucket: bucket,
IgnitionPresignedURL: url,
AdditionalTrustBundle: installConfig.Config.AdditionalTrustBundle,
MasterIAMRoleName: masterIAMRoleName,
WorkerIAMRoleName: workerIAMRoleName,
})
if err != nil {
return errors.Wrapf(err, "failed to get %s Terraform variables", platform)
Expand Down
Loading