Skip to content
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

Sg module integration #7

Merged
merged 26 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
7947934
Added pem files to gitignore
jordan-fry-cf Sep 8, 2023
eb19a8c
Also added lockfile to gitignore
jordan-fry-cf Sep 8, 2023
61e7252
Initial rework
jordan-fry-cf Sep 8, 2023
b527e9c
Fixed sg edge case
jordan-fry-cf Sep 8, 2023
094f51d
Started EBS rework
jordan-fry-cf Sep 8, 2023
bff9a30
terraform-docs: automated action
github-actions[bot] Sep 8, 2023
b0ae109
Added sorted maps
jordan-fry-cf Sep 11, 2023
35086ea
Added flag for optional SSMManagedInstanceCore
jordan-fry-cf Sep 11, 2023
c80053d
Resolved merge conflicts
jordan-fry-cf Sep 11, 2023
7226464
terraform-docs: automated action
github-actions[bot] Sep 11, 2023
86c2105
Added simple deployment example to README with generic variables
jordan-fry-cf Sep 12, 2023
1854914
Merge branch 'sg-module-integration' of github.com:Coalfire-CF/ACE-AW…
jordan-fry-cf Sep 12, 2023
30f7263
Updated README examples and formatting
jordan-fry-cf Sep 12, 2023
5e734bb
Updated AWS provider block
jordan-fry-cf Sep 14, 2023
d35a18e
Set up additional EBS volume attachments
jordan-fry-cf Sep 14, 2023
ee2301c
Merged with sg-module-integration branch
jordan-fry-cf Sep 14, 2023
2e8079e
terraform-docs: automated action
github-actions[bot] Sep 14, 2023
f83c1e0
Merge pull request #8 from Coalfire-CF/ebs_rework
jordan-fry-cf Sep 14, 2023
947a5fa
Omitted examples dir from checkov
jordan-fry-cf Sep 25, 2023
14765fd
Removed prefix system for vpc cidr declarations
jordan-fry-cf Sep 25, 2023
1d8e954
Updated README resource wording for example
jordan-fry-cf Sep 25, 2023
e271054
Changed sg module to point to git repo
jordan-fry-cf Sep 25, 2023
a6f0ade
Removed version from sg source
jordan-fry-cf Sep 25, 2023
3a45c9a
terraform-docs: automated action
github-actions[bot] Sep 25, 2023
3318bc5
Added source clarification to example module
jordan-fry-cf Sep 25, 2023
ec46e29
Merge branch 'sg-module-integration' of github.com:Coalfire-CF/ACE-AW…
jordan-fry-cf Sep 25, 2023
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
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Local .terraform directories
**/.terraform/*
.terraform.lock.hcl

# .tfstate files
*.tfstate
Expand Down Expand Up @@ -34,3 +35,6 @@ override.tf.json
# Ansible
*.pub
*.ppk

# Keys
*.pem
257 changes: 123 additions & 134 deletions README.md

Large diffs are not rendered by default.

33 changes: 12 additions & 21 deletions ec2.tf
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,26 @@ resource "aws_instance" "this" {

### NETWORKING ###
subnet_id = element(var.subnet_ids, count.index)
vpc_security_group_ids = compact(concat(var.additional_security_groups, [local.sg_id]))
private_ip = var.private_ip
associate_public_ip_address = var.associate_public_ip || var.associate_eip
source_dest_check = var.source_dest_check
vpc_security_group_ids = [module.security_group.id]

### STORAGE ###
root_block_device {
volume_type = var.root_volume_type
volume_size = var.root_volume_size
encrypted = true
kms_key_id = var.ebs_kms_key_arn
encrypted = true
kms_key_id = var.ebs_kms_key_arn
}

dynamic "ebs_block_device" {
for_each = var.ebs_block_devices
content {
device_name = ebs_block_device.value["device_name"]
volume_size = ebs_block_device.value["volume_size"]
volume_type = ebs_block_device.value["volume_type"]
encrypted = true
device_name = ebs_block_device.value["device_name"]
volume_size = ebs_block_device.value["volume_size"]
volume_type = ebs_block_device.value["volume_type"]
encrypted = true
delete_on_termination = var.volume_delete_on_termination
kms_key_id = var.ebs_kms_key_arn
}
Expand All @@ -43,30 +43,21 @@ resource "aws_instance" "this" {

### TAGS ###
tags = merge({
Name = var.instance_count == 1 ? var.name : "${var.name}${count.index + 1}",
Name = var.instance_count == 1 ? var.name : "${var.name}${count.index + 1}",
PatchGroup = tostring(count.index % 2 + 1) # Default PatchGroup tag increments in range 1-2
#Name = "${var.name}${count.index + 1}"
},
var.tags,
var.global_tags,
var.regional_tags)
var.tags,
var.global_tags)

volume_tags = merge({
Name = var.instance_count == 1 ? var.name : "${var.name}${count.index + 1}"
#Name = "${var.name}${count.index + 1}"
},
var.tags,
var.global_tags,
var.regional_tags)
var.tags,
var.global_tags)

lifecycle {
ignore_changes = [root_block_device, ebs_block_device, user_data, ami]
}

provisioner "local-exec" {
command = var.local_exec_command
}

depends_on = [var.module_depends_on]

}
8 changes: 4 additions & 4 deletions eip.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
resource "aws_eip" "eip" {
count = var.associate_eip ? 1 * var.instance_count : 0
vpc = true
count = var.associate_eip ? 1 * var.instance_count : 0
domain = "vpc"
}

resource "aws_eip_association" "eip_attach" {
count = var.associate_eip ? 1 * var. instance_count : 0
count = var.associate_eip ? 1 * var.instance_count : 0
instance_id = aws_instance.this[count.index].id
allocation_id = aws_eip.eip[count.index].id
}
}
42 changes: 3 additions & 39 deletions enis.tf
Original file line number Diff line number Diff line change
@@ -1,42 +1,6 @@

//resource "aws_network_interface" "public" {
// count = length(var.additional_enis["public"])
// subnet_id = var.additional_enis["public"][count.index]["subnet_id"][0]
// security_groups = var.additional_enis["public"][count.index]["security_groups"]
// source_dest_check = var.additional_enis["public"][count.index]["source_dest_check"][0]
// tags = {
// Name = var.additional_enis["public"][count.index]["name"][0]
// }
//}

//resource "aws_eip" "eip_multi_eni" {
// count = length(var.additional_enis["public"])
// vpc = true
//}
//
//resource "aws_eip_association" "eip_multi_eni_attach" {
// count = length(var.additional_enis["public"])
// network_interface_id = aws_network_interface.public[count.index].id
// allocation_id = aws_eip.eip_multi_eni[count.index].id
//}

//resource "aws_network_interface" "private" {
// count = length(var.additional_enis["private"])
// subnet_id = var.additional_enis["private"][count.index]["subnet_id"][0]
// security_groups = var.additional_enis["private"][count.index]["security_groups"]
// source_dest_check = var.additional_enis["private"][count.index]["source_dest_check"][0]
// tags = {
// Name = var.additional_enis["private"][count.index]["name"][0]
// }
//}

//locals {
// eni_ids = concat(aws_network_interface.public.*.id, aws_network_interface.private.*.id)
//}

resource "aws_network_interface_attachment" "eni_attachment" {
count = length(var.additional_eni_ids)
device_index = count.index + 1
instance_id = aws_instance.this[0].id
count = length(var.additional_eni_ids)
device_index = count.index + 1
instance_id = aws_instance.this[0].id
network_interface_id = var.additional_eni_ids[count.index]
}
11 changes: 11 additions & 0 deletions examples/simple/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
## EC2 module simple example

This example creates 2 EC2 instances using the EC2 module, along with a VPC, subnet, and the keys required by the module.

# Prerequisites

Generate an EC2 key pair and place the pem key in this directory. Add the pem file to the tfvars file. To match the example tfvars file, run the following command in the terminal while in this directory:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the way this reads, it creates a vpc itself. vpc and networking should only be done in the networking module. this module should only networking info as vars

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so are you opting that we remove VPC completely from the example?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@douglas-f you good to close this out?


`aws ec2 create-key-pair --profile sandbox --region us-east-2 --key-type rsa --key-format pem --query "KeyMaterial" --key-name "ec2-module-test" --output text > ec2-module-test.pem`

Note that `terraform destroy` will NOT remove the key pair from the AWS account as it is not tracked by state.
37 changes: 37 additions & 0 deletions examples/simple/keys.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Requires a .pem file exists in this directory. This should be a generated key-pair (example in README)
data "local_file" "key" {
filename = "${var.key_name}.pem"
}

resource "aws_ssm_parameter" "ec2_module_key_parameter" {
name = "/test/${var.key_name}.pem"
description = "Private key for EC2 module test build"
type = "SecureString"
value = data.local_file.key.content
}

resource "aws_kms_key" "ebs_key" {
description = "ebs key for ec2-module"
policy = data.aws_iam_policy_document.ebs_key.json
enable_key_rotation = true
}

locals {
partition = strcontains(var.aws_region, "gov") ? "aws-gov" : "aws"
}

data "aws_caller_identity" "current" {}

data "aws_iam_policy_document" "ebs_key" {
statement {
effect = "Allow"
actions = ["kms:*"]
resources = ["*"]
principals {
type = "AWS"
identifiers = [
"arn:${local.partition}:iam::${data.aws_caller_identity.current.account_id}:root"
]
}
}
}
62 changes: 62 additions & 0 deletions examples/simple/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
data "aws_ami" "ami" {
most_recent = true

filter {
name = "name"
values = ["amzn-ami-hvm-*"]
}

owners = ["amazon"]
}

resource "aws_vpc" "main" {
cidr_block = "${var.vpc_cidr_prefix}.0.0/24"
}

resource "aws_subnet" "main" {
vpc_id = aws_vpc.main.id
cidr_block = "${var.vpc_cidr_prefix}.0.0/24"
}

module "ec2_test" {
source = "../.."

name = "ec2_module_test_instance"

ami = data.aws_ami.ami.id
ec2_instance_type = "t2.micro"
instance_count = 2

vpc_id = aws_vpc.main.id
subnet_ids = [aws_subnet.main.id]

ec2_key_pair = "ec2-module-test"
ebs_kms_key_arn = aws_kms_key.ebs_key.arn

# Storage
root_volume_size = "20"

# Security Group Rules
ingress_rules = [{
protocol = "tcp"
from_port = "443"
to_port = "443"
cidr_blocks = [aws_vpc.main.cidr_block]
},
{
protocol = "tcp"
from_port = "22"
to_port = "22"
cidr_blocks = [aws_vpc.main.cidr_block]
}]

egress_rules = [{
protocol = "-1"
from_port = "0"
to_port = "0"
cidr_blocks = ["0.0.0.0/0"]
}]

# Tagging
global_tags = {}
}
16 changes: 16 additions & 0 deletions examples/simple/providers.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
terraform {
required_version = ">= 1.5"

required_providers {
aws = {
source = "hashicorp/aws"
version = ">=3.26"
}
}
}

provider "aws" {
region = var.aws_region
profile = var.profile
use_fips_endpoint = true
}
4 changes: 4 additions & 0 deletions examples/simple/tfvars/example.tfvars
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
aws_region = "us-east-2"
profile = "sandbox"
vpc_cidr_prefix = "10.2"
kourosh-forti-hands marked this conversation as resolved.
Show resolved Hide resolved
key_name = "ec2-module-test"
21 changes: 21 additions & 0 deletions examples/simple/variables.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
variable "aws_region" {
description = "The region where things will be deployed by default"
type = string
default = "us-east-1"
}

variable "key_name" {
description = "The name of the EC2 pem key in this directory (without the suffix)"
type = string
}

variable "profile" {
description = "The name of the profile to get AWS credentials from"
type = string
}

variable "vpc_cidr_prefix" {
description = "The cidr block for the vpc created for testing the security group"
type = string
default = "10.0"
}
43 changes: 18 additions & 25 deletions iam.tf
Original file line number Diff line number Diff line change
@@ -1,22 +1,8 @@
resource "aws_iam_role" "this_role" {
count = length(var.iam_policies) > 0 ? 1 : 0
name = "${var.name}_role"
name = "${var.name}_role"

assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Action": "sts:AssumeRole",
"Principal": {
"Service": "ec2.amazonaws.com"
},
"Effect": "Allow",
"Sid": ""
}
]
}
EOF
assume_role_policy = var.assume_role_policy
}

resource "aws_iam_role_policy_attachment" "iam_policy_attach" {
Expand All @@ -25,24 +11,31 @@ resource "aws_iam_role_policy_attachment" "iam_policy_attach" {
role = aws_iam_role.this_role[0].name
}

#resource "aws_iam_role_policy_attachment" "iam_policy_attach_base" {
# policy_arn = var.default_iam_policy
# role = aws_iam_role.this_role[0].name
#}

resource "aws_iam_instance_profile" "this_profile" {
count = length(var.iam_policies) > 0 ? 1 : 0
name = "${var.name}_profile"
role = aws_iam_role.this_role[0].name
name = "${var.name}_profile"
role = aws_iam_role.this_role[0].name
}

# IAM policy to allow SSM
jordan-fry-cf marked this conversation as resolved.
Show resolved Hide resolved
data "aws_iam_policy" "AmazonSSMManagedInstanceCore" {
name = "AmazonSSMManagedInstanceCore"
}

resource "aws_iam_role_policy_attachment" "SSM_role_policy_attach" {
count = length(var.iam_policies)
policy_arn = data.aws_iam_policy.AmazonSSMManagedInstanceCore.arn
role = aws_iam_role.this_role[0].name
}

resource "aws_kms_grant" "kms_key_grant" {
count = length(var.keys_to_grant)
count = length(var.keys_to_grant)
name = "${var.name}-grant-${count.index}"
key_id = var.keys_to_grant[count.index]
grantee_principal = aws_iam_role.this_role[0].arn
operations = [
"Encrypt",
"Decrypt",
"DescribeKey"]
"DescribeKey"
]
}
25 changes: 25 additions & 0 deletions locals.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
locals {
iam_profile = length(aws_iam_instance_profile.this_profile) > 0 ? aws_iam_instance_profile.this_profile[0].name : var.iam_profile
create_sg = length(var.ingress_rules) > 0 || length(var.egress_rules) > 0 ? 1 : 0
}

# Gathers user data from maps listed in module calls
locals {
jordan-fry-cf marked this conversation as resolved.
Show resolved Hide resolved
user_data = var.user_data == null ? null : [
for script in var.user_data : templatefile(
"${script["path"]["module_directory"]}/${script["path"]["folder_name"]}/${script["path"]["file_name"]}",
script["vars"]
)
]
}

# For lb attachment
locals {
full_size = length(aws_instance.this.*.id) * length(var.target_group_arns)
}

# For additional sg attachment
locals {
additional_sg_to_primary_eni = setproduct(var.additional_security_groups, aws_instance.this.*.primary_network_interface_id)
additional_sg_to_additional_eni = setproduct(var.additional_security_groups, var.additional_eni_ids)
}
Loading