Skip to content

Commit 851214c

Browse files
authored
Merge pull request #95 from jeroenhabets/SECURITY_metadata_options
SECURITY: IMDSv2 support via new cluster_instance_metadata_options parameter
2 parents 1bc865a + 6a051b9 commit 851214c

File tree

7 files changed

+96
-19
lines changed

7 files changed

+96
-19
lines changed

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ BACKWARDS INCOMPATIBILITIES / NOTES:
66
module since, in the case of autoscaling or manual scaling, the value may have
77
changed between `apply`s.
88

9+
IMPROVEMENTS:
10+
11+
* A `cluster_instance_metadata_options` variable has been added which mirrors
12+
the [metadata_options](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/launch_template#metadata-options)
13+
exposed on the `aws_launch_template` resource. Among other things, this allows
14+
users of this module to require that IMDSv2 be used by containers in the
15+
cluster. By default, IMDSv2 is not required in this version of the module but
16+
a future major release of the module may enforce IMDSv2 usage.
17+
18+
919
## 6.0.0 (February 22th 2023)
1020

1121
BACKWARDS INCOMPATIBILITIES / NOTES:

README.md

+19-19
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@ The ECS cluster consists of:
1717
instances
1818
* An SSH key to connect to the ECS container instances
1919
* A security group for the container instances optionally allowing:
20-
* Outbound internet access for all containers
21-
* Inbound TCP access on any port from the VPC network
20+
* Outbound internet access for all containers
21+
* Inbound TCP access on any port from the VPC network
2222
* An IAM role and policy for the container instances allowing:
23-
* ECS interactions
24-
* ECR image pulls
25-
* S3 object fetches
26-
* Logging to cloudwatch
23+
* ECS interactions
24+
* ECR image pulls
25+
* S3 object fetches
26+
* Logging to cloudwatch
2727
* An IAM role and policy for ECS services allowing:
28-
* Elastic load balancer registration / deregistration
29-
* EC2 describe actions and security group ingress rule creation
28+
* Elastic load balancer registration / deregistration
29+
* EC2 describe actions and security group ingress rule creation
3030
* A CloudWatch log group
3131

3232
![Diagram of infrastructure managed by this module](https://raw.githubusercontent.com/infrablocks/terraform-aws-ecs-cluster/main/docs/architecture.png)
@@ -39,25 +39,25 @@ configuration:
3939

4040
```hcl-terraform
4141
module "ecs_cluster" {
42-
source = "infrablocks/ecs-cluster/aws"
42+
source = "infrablocks/ecs-cluster/aws"
4343
version = "5.0.0"
4444
45-
region = "eu-west-2"
46-
vpc_id = "vpc-fb7dc365"
45+
region = "eu-west-2"
46+
vpc_id = "vpc-fb7dc365"
4747
subnet_ids = [
48-
"subnet-eb32c271",
49-
"subnet-64872d1f"
48+
"subnet-eb32c271",
49+
"subnet-64872d1f"
5050
]
5151
52-
component = "important-component"
52+
component = "important-component"
5353
deployment_identifier = "production"
5454
55-
cluster_name = "services"
55+
cluster_name = "services"
5656
cluster_instance_ssh_public_key_path = "~/.ssh/id_rsa.pub"
57-
cluster_instance_type = "t3.small"
57+
cluster_instance_type = "t3.small"
5858
59-
cluster_minimum_size = 2
60-
cluster_maximum_size = 10
59+
cluster_minimum_size = 2
60+
cluster_maximum_size = 10
6161
cluster_desired_capacity = 4
6262
}
6363
```
@@ -91,6 +91,7 @@ for more details.
9191
| cluster_instance_root_block_device_type | The type of the root block device on cluster instances ('standard', 'gp2', or 'io1') | standard | yes |
9292
| cluster_instance_user_data_template | The contents of a template for container instance user data | see user-data | no |
9393
| cluster_instance_ami | AMI for the container instances | ECS optimised AMI | yes |
94+
| cluster_instance_metadata_options | A map of metadata options for cluster instances. | - | no |
9495
| cluster_instance_iam_policy_contents | The contents of the cluster instance IAM policy | see policies | no |
9596
| cluster_service_iam_policy_contents | The contents of the cluster service IAM policy | see policies | no |
9697
| cluster_minimum_size | The minimum size of the ECS cluster | 1 | yes |
@@ -202,7 +203,6 @@ Terraform 1.0.
202203
* logs:ListTagsLogGroup
203204
* logs:DeleteLogGroup
204205

205-
206206
Development
207207
-----------
208208

asg.tf

+9
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ locals {
88
cluster_user_data = replace(
99
local.cluster_user_data_template,
1010
"$${cluster_name}", local.cluster_full_name)
11+
cluster_instance_metadata_options = var.cluster_instance_metadata_options == null ? {} : var.cluster_instance_metadata_options
1112
}
1213

1314
data "aws_ami" "amazon_linux_2" {
@@ -30,6 +31,14 @@ resource "aws_launch_template" "cluster" {
3031
name = aws_iam_instance_profile.cluster.name
3132
}
3233

34+
metadata_options {
35+
http_endpoint = lookup(local.cluster_instance_metadata_options, "http_endpoint", null)
36+
http_tokens = lookup(local.cluster_instance_metadata_options, "http_tokens", null)
37+
http_put_response_hop_limit = lookup(local.cluster_instance_metadata_options, "http_put_response_hop_limit", null)
38+
instance_metadata_tags = lookup(local.cluster_instance_metadata_options, "instance_metadata_tags", null)
39+
http_protocol_ipv6 = lookup(local.cluster_instance_metadata_options, "http_protocol_ipv6", null)
40+
}
41+
3342
user_data = base64encode(local.cluster_user_data)
3443

3544
network_interfaces {

spec/unit/infra/root/main.tf

+2
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ module "ecs_cluster" {
2929
cluster_instance_enable_ebs_volume_encryption = var.cluster_instance_enable_ebs_volume_encryption
3030
cluster_instance_ebs_volume_kms_key_id = var.cluster_instance_ebs_volume_kms_key_id
3131

32+
cluster_instance_metadata_options = var.cluster_instance_metadata_options
33+
3234
cluster_minimum_size = var.cluster_minimum_size
3335
cluster_maximum_size = var.cluster_maximum_size
3436
cluster_desired_capacity = var.cluster_desired_capacity

spec/unit/infra/root/variables.tf

+5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,11 @@ variable "cluster_instance_root_block_device_path" {
2828
default = null
2929
}
3030

31+
variable "cluster_instance_metadata_options" {
32+
type = map
33+
default = null
34+
}
35+
3136
variable "cluster_minimum_size" {
3237
default = null
3338
}

spec/unit/launch_template_spec.rb

+45
Original file line numberDiff line numberDiff line change
@@ -236,4 +236,49 @@
236236
))
237237
end
238238
end
239+
240+
describe 'metadata options' do
241+
it 'disables http_protocol_ipv6 and instance_metadata_tags by default' do
242+
expect(@plan)
243+
.to(include_resource_creation(type: 'aws_launch_template')
244+
.with_attribute_value(
245+
:metadata_options,
246+
including(
247+
including({
248+
http_protocol_ipv6: 'disabled',
249+
instance_metadata_tags: 'disabled'
250+
})
251+
)
252+
))
253+
end
254+
255+
context 'when cluster_instance_metadata_options is provided' do
256+
before(:context) do
257+
@plan = plan(role: :root) do |vars|
258+
vars.cluster_instance_metadata_options = {
259+
http_endpoint: 'enabled',
260+
http_tokens: 'required',
261+
http_protocol_ipv6: 'enabled',
262+
instance_metadata_tags: 'enabled',
263+
http_put_response_hop_limit: 15
264+
}
265+
end
266+
end
267+
268+
it 'uses provided metadata options' do
269+
expect(@plan)
270+
.to(include_resource_creation(type: 'aws_launch_template')
271+
.with_attribute_value(
272+
:metadata_options,
273+
including(including({
274+
http_endpoint: 'enabled',
275+
http_tokens: 'required',
276+
http_protocol_ipv6: 'enabled',
277+
instance_metadata_tags: 'enabled',
278+
http_put_response_hop_limit: 15
279+
}))
280+
))
281+
end
282+
end
283+
end
239284
end

variables.tf

+6
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ variable "cluster_instance_iam_policy_contents" {
7676
type = string
7777
default = null
7878
}
79+
80+
variable "cluster_instance_metadata_options" {
81+
description = "The metadata_options for cluster instances."
82+
type = map
83+
default = null
84+
}
7985
variable "cluster_service_iam_policy_contents" {
8086
description = "The contents of the cluster service IAM policy."
8187
type = string

0 commit comments

Comments
 (0)