Skip to content

Commit

Permalink
data/aws: Encrypt the AMI used by the bootstrap and master machines
Browse files Browse the repository at this point in the history
This is a quick hack to get encrypted masters.  Ideally we'd want to
deregister these on bootstrap-teardown, but handling that nicely will
be easier after some cleanups from [1].  As it stands, we'll
deregister this as part of the general cluster teardown.

Because we don't set kms_key_id [2] we get "the default AWS KMS Key"
(according to [2]).  AWS docs are not particularly clear about whether
users can configure the default key for their account/region to
override that default, although it is clear that it defaults to an
AWS-managed CMK [3] and that the alias for AMI encryption is
alias/aws/ebs [4].  If there is no way to override alias/aws/ebs,
we'll probably eventially need to expose kms_key_id to users.

[1]: openshift#1148
[2]: https://www.terraform.io/docs/providers/aws/r/ami_copy.html#kms_key_id
[3]: https://docs.aws.amazon.com/kms/latest/developerguide/concepts.html#aws-managed-cmk
[4]: https://aws.amazon.com/blogs/security/how-to-create-a-custom-ami-with-encrypted-amazon-ebs-snapshots-and-share-it-with-other-accounts-and-regions/
  • Loading branch information
wking committed Feb 26, 2019
1 parent 76b167d commit 4fcef5e
Show file tree
Hide file tree
Showing 5 changed files with 42 additions and 7 deletions.
17 changes: 15 additions & 2 deletions data/data/aws/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ provider "aws" {
module "bootstrap" {
source = "./bootstrap"

ami = "${var.aws_ec2_ami_override}"
ami = "${aws_ami_copy.main.id}"
instance_type = "${var.aws_bootstrap_instance_type}"
cluster_id = "${var.cluster_id}"
ignition = "${var.ignition_bootstrap}"
Expand Down Expand Up @@ -40,7 +40,7 @@ module "masters" {
subnet_ids = "${module.vpc.private_subnet_ids}"
target_group_arns = "${module.vpc.aws_lb_target_group_arns}"
target_group_arns_length = "${module.vpc.aws_lb_target_group_arns_length}"
ec2_ami = "${var.aws_ec2_ami_override}"
ec2_ami = "${aws_ami_copy.main.id}"
user_data_ign = "${var.ignition_master}"
}

Expand Down Expand Up @@ -77,3 +77,16 @@ module "vpc" {

tags = "${local.tags}"
}

resource "aws_ami_copy" "main" {
name = "${var.cluster_id}-master"
source_ami_id = "${var.aws_ami}"
source_ami_region = "${var.aws_region}"
encrypted = true

tags = "${merge(map(
"Name", "${var.cluster_id}-master",
"sourceAMI": "${var.aws_ami}",
"sourceRegion": "${var.aws_region}",
), local.tags)}"
}
5 changes: 2 additions & 3 deletions data/data/aws/variables-aws.tf
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ variable "aws_master_instance_type" {
description = "Instance type for the master node(s). Example: `m4.large`."
}

variable "aws_ec2_ami_override" {
variable "aws_ami" {
type = "string"
description = "(optional) AMI override for all nodes. Example: `ami-foobar123`."
default = ""
description = "AMI for all nodes. An encrypted copy of this AMI will be used. Example: `ami-foobar123`."
}

variable "aws_extra_tags" {
Expand Down
6 changes: 6 additions & 0 deletions docs/user/aws/install.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ INFO Access the OpenShift web-console here: https://console-openshift-console.ap
INFO Login to the console with user: kubeadmin, password: XXXX
```

This creates an encrypted AMI for the bootstrap and control-plane machines.
The encrypted AMI is [copied][encrypted-copy] from the AMI configured in the control-plane machine-API provider spec, which is RHCOS by default.
The encryption uses the default EBS key for your target account and region (`aws kms describe-key --key-id alias/aws/ebs`).
The encrypted AMI is deregistered by `destroy cluster`.

### Running Cluster

In Route53, there will be a new, private hosted zone (for internal lookups):
Expand All @@ -56,3 +61,4 @@ The OpenShift console is available via the kubeadmin login provided by the insta
![OpenShift web console](images/install_console.png)

[cloud-install]: https://cloud.openshift.com/clusters/install
[encrypted-copy]: https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIEncryption.html#create-ami-encrypted-root-snapshot
17 changes: 17 additions & 0 deletions pkg/destroy/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,8 @@ func deleteEC2(session *session.Session, arn arn.ARN, logger logrus.FieldLogger)
return deleteEC2DHCPOptions(client, id, logger)
case "elastic-ip":
return deleteEC2ElasticIP(client, id, logger)
case "image":
return deleteEC2Image(client, id, logger)
case "instance":
return deleteEC2Instance(client, iam.New(session), id, logger)
case "internet-gateway":
Expand Down Expand Up @@ -491,6 +493,21 @@ func deleteEC2DHCPOptions(client *ec2.EC2, id string, logger logrus.FieldLogger)
return nil
}

func deleteEC2Image(client *ec2.EC2, id string, logger logrus.FieldLogger) error {
_, err := client.DeregisterImage(&ec2.DeregisterImageInput{
ImageId: &id,
})
if err != nil {
if err.(awserr.Error).Code() == "InvalidAMIID.NotFound" {
return nil
}
return err
}

logger.Info("Deleted")
return nil
}

func deleteEC2ElasticIP(client *ec2.EC2, id string, logger logrus.FieldLogger) error {
_, err := client.ReleaseAddress(&ec2.ReleaseAddressInput{
AllocationId: aws.String(id),
Expand Down
4 changes: 2 additions & 2 deletions pkg/tfvars/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import (
)

type config struct {
EC2AMIOverride string `json:"aws_ec2_ami_override,omitempty"`
AMI string `json:"aws_ami"`
ExtraTags map[string]string `json:"aws_extra_tags,omitempty"`
BootstrapInstanceType string `json:"aws_bootstrap_instance_type,omitempty"`
MasterInstanceType string `json:"aws_master_instance_type,omitempty"`
Expand Down Expand Up @@ -54,7 +54,7 @@ func TFVars(masterConfig *v1beta1.AWSMachineProviderConfig) ([]byte, error) {
cfg := &config{
Region: masterConfig.Placement.Region,
ExtraTags: tags,
EC2AMIOverride: *masterConfig.AMI.ID,
AMI: *masterConfig.AMI.ID,
BootstrapInstanceType: fmt.Sprintf("%s.large", instanceClass),
MasterInstanceType: masterConfig.InstanceType,
Size: *rootVolume.EBS.VolumeSize,
Expand Down

0 comments on commit 4fcef5e

Please sign in to comment.