Skip to content

Update Ubuntu AMI query #215

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 3, 2025
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
2 changes: 1 addition & 1 deletion cloudwatch-alarm.tf
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ resource "null_resource" "check_alarm_action" {
count = var.disable_alarm_action ? 0 : local.instance_count

triggers = {
action = "arn:${data.aws_partition.default.partition}:swf:${local.region}:${data.aws_caller_identity.default.account_id}:${var.default_alarm_action}"
action = "arn:${try(data.aws_partition.default[0].partition, null)}:swf:${local.region}:${try(data.aws_caller_identity.default[0].account_id, null)}:${var.default_alarm_action}"
}
}

Expand Down
4 changes: 2 additions & 2 deletions examples/complete/fixtures.us-east-2.tfvars
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
enabled = true
# enabled = true

region = "us-east-2"

Expand Down Expand Up @@ -54,6 +54,6 @@ security_group_rules = [
},
]

ssh_public_key_path = "/secrets"
ssh_public_key_path = "/tmp/secrets"

metric_treat_missing_data = "notBreaching"
17 changes: 12 additions & 5 deletions examples/complete/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ module "aws_key_pair" {
attributes = module.this.attributes
ssh_public_key_path = var.ssh_public_key_path
generate_ssh_key = true

context = module.this.context
}

module "vpc" {
Expand All @@ -24,7 +26,7 @@ module "vpc" {

module "subnets" {
source = "cloudposse/dynamic-subnets/aws"
version = "2.3.0"
version = "2.4.2"

availability_zones = var.availability_zones
vpc_id = module.vpc.vpc_id
Expand All @@ -46,6 +48,7 @@ module "instance_profile_label" {
}

data "aws_iam_policy_document" "test" {
count = module.this.enabled ? 1 : 0
statement {
effect = "Allow"

Expand All @@ -61,29 +64,33 @@ data "aws_iam_policy_document" "test" {
}

resource "aws_iam_role" "test" {
count = module.this.enabled ? 1 : 0

name = module.instance_profile_label.id
assume_role_policy = data.aws_iam_policy_document.test.json
assume_role_policy = one(data.aws_iam_policy_document.test[*].json)
tags = module.instance_profile_label.tags
}

# https://github.com/hashicorp/terraform-guides/tree/master/infrastructure-as-code/terraform-0.13-examples/module-depends-on
resource "aws_iam_instance_profile" "test" {
count = module.this.enabled ? 1 : 0

name = module.instance_profile_label.id
role = aws_iam_role.test.name
role = aws_iam_role.test[0].name
}

module "ec2_instance" {
source = "../../"

ssh_key_pair = module.aws_key_pair.key_name
vpc_id = module.vpc.vpc_id
subnet = module.subnets.private_subnet_ids[0]
subnet = module.this.enabled ? module.subnets.private_subnet_ids[0] : null
security_groups = [module.vpc.vpc_default_security_group_id]
assign_eip_address = var.assign_eip_address
associate_public_ip_address = var.associate_public_ip_address
instance_type = var.instance_type
security_group_rules = var.security_group_rules
instance_profile = aws_iam_instance_profile.test.name
instance_profile = module.this.enabled ? aws_iam_instance_profile.test[0].name : null
tenancy = var.tenancy
metric_treat_missing_data = var.metric_treat_missing_data

Expand Down
2 changes: 1 addition & 1 deletion examples/external-eni/fixtures.us-east-2.tfvars
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,4 @@ security_group_rules = [
},
]

ssh_public_key_path = "/secrets"
ssh_public_key_path = "/tmp/secrets"
32 changes: 19 additions & 13 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,41 +3,47 @@ locals {
instance_count = local.enabled ? 1 : 0
volume_count = var.ebs_volume_count > 0 && local.instance_count > 0 ? var.ebs_volume_count : 0
# create an instance profile if the instance is enabled and we aren't given one to use
instance_profile_count = module.this.enabled && var.instance_profile_enabled && var.instance_profile == "" ? 1 : 0
instance_profile_count = local.enabled && var.instance_profile_enabled && var.instance_profile == "" ? 1 : 0
instance_profile = var.instance_profile_enabled && var.instance_profile != "" ? var.instance_profile : (var.instance_profile_enabled ? one(aws_iam_instance_profile.default[*].name) : "")
security_group_enabled = module.this.enabled && var.security_group_enabled
region = var.region != "" ? var.region : data.aws_region.default.name
security_group_enabled = local.enabled && var.security_group_enabled
region = local.enabled ? coalesce(var.region, one(data.aws_region.default[*].name)) : ""
root_iops = contains(["io1", "io2", "gp3"], var.root_volume_type) ? var.root_iops : null
ebs_iops = contains(["io1", "io2", "gp3"], var.ebs_volume_type) ? var.ebs_iops : null
root_throughput = var.root_volume_type == "gp3" ? var.root_throughput : null
ebs_throughput = var.ebs_volume_type == "gp3" ? var.ebs_throughput : null
availability_zone = var.availability_zone != "" ? var.availability_zone : data.aws_subnet.default.availability_zone
availability_zone = var.availability_zone != "" ? var.availability_zone : try(data.aws_subnet.default[0].availability_zone, null)
ami = var.ami != "" ? var.ami : one(data.aws_ami.default[*].image_id)
ami_owner = var.ami != "" ? var.ami_owner : one(data.aws_ami.default[*].owner_id)
root_volume_type = var.root_volume_type != "" ? var.root_volume_type : one(data.aws_ami.info[*].root_device_type)

region_domain = local.region == "us-east-1" ? "compute-1.amazonaws.com" : "${local.region}.compute.amazonaws.com"
eip_public_dns = var.associate_public_ip_address && var.assign_eip_address && module.this.enabled ? "ec2-${replace(one(aws_eip.default[*].public_ip), ".", "-")}.${local.region_domain}" : ""
eip_public_dns = var.associate_public_ip_address && var.assign_eip_address && local.enabled ? "ec2-${replace(one(aws_eip.default[*].public_ip), ".", "-")}.${local.region_domain}" : ""
public_dns = (
var.associate_public_ip_address && var.assign_eip_address && module.this.enabled ?
var.associate_public_ip_address && var.assign_eip_address && local.enabled ?
local.eip_public_dns : one(aws_instance.default[*].public_dns)
)
}

data "aws_caller_identity" "default" {
count = local.enabled ? 1 : 0
}

data "aws_region" "default" {
count = local.enabled ? 1 : 0
}

data "aws_partition" "default" {
count = local.enabled ? 1 : 0
}

data "aws_subnet" "default" {
id = var.subnet
count = local.enabled ? 1 : 0
id = var.subnet
}

data "aws_iam_policy_document" "default" {
count = local.enabled ? 1 : 0

statement {
sid = ""

Expand All @@ -54,12 +60,12 @@ data "aws_iam_policy_document" "default" {
}
}
data "aws_ami" "default" {
count = var.ami == "" ? 1 : 0
count = local.enabled && var.ami == "" ? 1 : 0
most_recent = "true"

filter {
name = "name"
values = ["ubuntu/images/hvm-ssd/ubuntu-bionic-18.04-amd64-server-*"]
values = ["ubuntu/images/hvm-ssd/ubuntu-jammy-22.04-amd64-server-*"]
}

filter {
Expand All @@ -71,7 +77,7 @@ data "aws_ami" "default" {
}

data "aws_ami" "info" {
count = var.root_volume_type != "" ? 0 : 1
count = local.enabled && var.root_volume_type == "" ? 1 : 0

filter {
name = "image-id"
Expand All @@ -95,10 +101,10 @@ resource "aws_iam_instance_profile" "default" {
}

resource "aws_iam_role" "default" {
count = var.instance_profile_enabled ? local.instance_profile_count : 0
count = local.enabled && var.instance_profile_enabled ? local.instance_profile_count : 0
name = module.this.id
path = "/"
assume_role_policy = data.aws_iam_policy_document.default.json
assume_role_policy = one(data.aws_iam_policy_document.default[*].json)
permissions_boundary = var.permissions_boundary_arn
tags = module.this.tags
}
Expand Down Expand Up @@ -175,7 +181,7 @@ resource "aws_instance" "default" {

resource "aws_eip" "default" {
#bridgecrew:skip=BC_AWS_NETWORKING_48: Skiping `Ensure all EIP addresses allocated to a VPC are attached to EC2 instances` because it is incorrectly flagging that this instance does not belong to a VPC even though subnet_id is configured.
count = var.associate_public_ip_address && var.assign_eip_address && module.this.enabled ? 1 : 0
count = var.associate_public_ip_address && var.assign_eip_address && local.enabled ? 1 : 0
instance = one(aws_instance.default[*].id)
tags = module.this.tags
}
Expand Down
7 changes: 4 additions & 3 deletions ssm_patch.tf
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@

locals {
ssm_patch_log_bucket_enabled = local.ssm_enabled && var.ssm_patch_manager_s3_log_bucket != "" && var.ssm_patch_manager_s3_log_bucket != null
ssm_policy_arn = var.ssm_patch_manager_iam_policy_arn == null || var.ssm_patch_manager_iam_policy_arn == "" ? "arn:${data.aws_partition.default.partition}:iam::aws:policy/AmazonSSMManagedInstanceCore" : var.ssm_patch_manager_iam_policy_arn
partition = module.this.enabled ? one(data.aws_partition.default[*].partition) : ""
ssm_policy_arn = var.ssm_patch_manager_iam_policy_arn == null || var.ssm_patch_manager_iam_policy_arn == "" ? "arn:${local.partition}:iam::aws:policy/AmazonSSMManagedInstanceCore" : var.ssm_patch_manager_iam_policy_arn
ssm_enabled = local.enabled && var.ssm_patch_manager_enabled
}

Expand All @@ -25,8 +26,8 @@ data "aws_iam_policy_document" "ssm_patch_s3_log_policy" {
"s3:GetEncryptionConfiguration",
]
resources = [
"arn:${data.aws_partition.default.partition}:s3:::${var.ssm_patch_manager_s3_log_bucket}/*",
"arn:${data.aws_partition.default.partition}:s3:::${var.ssm_patch_manager_s3_log_bucket}",
"arn:${try(data.aws_partition.default[0].partition, null)}:s3:::${var.ssm_patch_manager_s3_log_bucket}/*",
"arn:${try(data.aws_partition.default[0].partition, null)}:s3:::${var.ssm_patch_manager_s3_log_bucket}",
]
}
}
Expand Down
38 changes: 34 additions & 4 deletions test/src/examples_complete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package test
import (
"math/rand"
"strconv"
"strings"
"testing"
"time"

Expand All @@ -12,8 +13,6 @@ import (

// Test the Terraform module in examples/complete using Terratest.
func TestExamplesComplete(t *testing.T) {
t.Parallel()

rand.Seed(time.Now().UnixNano())

randId := strconv.Itoa(rand.Intn(100000))
Expand All @@ -27,6 +26,7 @@ func TestExamplesComplete(t *testing.T) {
VarFiles: []string{"fixtures.us-east-2.tfvars"},
Vars: map[string]interface{}{
"attributes": attributes,
"enabled": "true",
},
}

Expand Down Expand Up @@ -84,8 +84,6 @@ func TestExamplesComplete(t *testing.T) {
}

func TestExternalEniComplete(t *testing.T) {
t.Parallel()

rand.Seed(time.Now().UnixNano())

randId := strconv.Itoa(rand.Intn(100000))
Expand Down Expand Up @@ -149,3 +147,35 @@ func TestExternalEniComplete(t *testing.T) {
// Verify we're getting back the outputs we expect
assert.Contains(t, securityGroupARN, "arn:aws:ec2", "SG ID should contains substring 'arn:aws:ec2'")
}

// Test the Terraform module in examples/complete using Terratest.
func TestDisabled(t *testing.T) {
rand.Seed(time.Now().UnixNano())

randId := strconv.Itoa(rand.Intn(100000))
attributes := []string{randId}

terraformOptions := &terraform.Options{
// The path to where our Terraform code is located
TerraformDir: "../../examples/complete",
Upgrade: true,
// Variables to pass to our Terraform code using -var-file options
VarFiles: []string{"fixtures.us-east-2.tfvars"},
Vars: map[string]interface{}{
"attributes": attributes,
"enabled": "false",
},
}

// At the end of the test, run `terraform destroy` to clean up any resources that were created
defer terraform.Destroy(t, terraformOptions)

terraform.Init(t, terraformOptions)
plan := terraform.Plan(t, terraformOptions)
planContainsNoChanges := strings.Contains(plan, "No changes.") || strings.Contains(plan, "0 to add, 0 to change, 0 to destroy.") || !strings.Contains(plan, "Plan")

assert.True(t, planContainsNoChanges)

planContainsNoAMIsearch := !strings.Contains(plan, "module.ec2_instance.data.aws_ami.default[0]: Reading...") && !strings.Contains(plan, "module.ec2_instance.data.aws_ami.info[0]: Reading...")
assert.True(t, planContainsNoAMIsearch)
}
25 changes: 23 additions & 2 deletions test/src/go.mod
Original file line number Diff line number Diff line change
@@ -1,9 +1,30 @@
module github.com/cloudposse/terraform-aws-ec2-instance

go 1.14
go 1.23

toolchain go1.23.0

require (
github.com/gruntwork-io/gruntwork-cli v0.7.0 // indirect
github.com/gruntwork-io/terratest v0.34.7
github.com/stretchr/testify v1.6.1
)

require (
github.com/agext/levenshtein v1.2.1 // indirect
github.com/apparentlymart/go-textseg v1.0.0 // indirect
github.com/apparentlymart/go-textseg/v12 v12.0.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.1.0 // indirect
github.com/hashicorp/hcl/v2 v2.8.2 // indirect
github.com/hashicorp/terraform-json v0.9.0 // indirect
github.com/jinzhu/copier v0.0.0-20190924061706-b57f9002281a // indirect
github.com/mitchellh/go-wordwrap v0.0.0-20150314170334-ad45545899c7 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/zclconf/go-cty v1.2.1 // indirect
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect
golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f // indirect
golang.org/x/text v0.3.3 // indirect
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c // indirect
)
Loading