Commit 787132e5 authored by Bryant Biggs's avatar Bryant Biggs Committed by GitHub

feat: Add support for creating IAM role/instance profile with policies (#302)

parent 668ac71d
repos: repos:
- repo: https://github.com/antonbabenko/pre-commit-terraform - repo: https://github.com/antonbabenko/pre-commit-terraform
rev: v1.74.1 rev: v1.76.0
hooks: hooks:
- id: terraform_fmt - id: terraform_fmt
- id: terraform_wrapper_module_for_each - id: terraform_wrapper_module_for_each
......
...@@ -184,14 +184,21 @@ No modules. ...@@ -184,14 +184,21 @@ No modules.
| Name | Type | | Name | Type |
|------|------| |------|------|
| [aws_iam_instance_profile.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_instance_profile) | resource |
| [aws_iam_role.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
| [aws_iam_role_policy_attachment.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
| [aws_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource | | [aws_instance.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/instance) | resource |
| [aws_spot_instance_request.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/spot_instance_request) | resource | | [aws_spot_instance_request.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/spot_instance_request) | resource |
| [aws_iam_policy_document.assume_role_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
| [aws_partition.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/partition) | data source |
| [aws_ssm_parameter.this](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/ssm_parameter) | data source |
## Inputs ## Inputs
| Name | Description | Type | Default | Required | | Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:| |------|-------------|------|---------|:--------:|
| <a name="input_ami"></a> [ami](#input\_ami) | ID of AMI to use for the instance | `string` | `""` | no | | <a name="input_ami"></a> [ami](#input\_ami) | ID of AMI to use for the instance | `string` | `null` | no |
| <a name="input_ami_ssm_parameter"></a> [ami\_ssm\_parameter](#input\_ami\_ssm\_parameter) | SSM parameter name for the AMI ID. For Amazon Linux AMI SSM parameters see [reference](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-public-parameters-ami.html) | `string` | `"/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"` | no |
| <a name="input_associate_public_ip_address"></a> [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Whether to associate a public IP address with an instance in a VPC | `bool` | `null` | no | | <a name="input_associate_public_ip_address"></a> [associate\_public\_ip\_address](#input\_associate\_public\_ip\_address) | Whether to associate a public IP address with an instance in a VPC | `bool` | `null` | no |
| <a name="input_availability_zone"></a> [availability\_zone](#input\_availability\_zone) | AZ to start the instance in | `string` | `null` | no | | <a name="input_availability_zone"></a> [availability\_zone](#input\_availability\_zone) | AZ to start the instance in | `string` | `null` | no |
| <a name="input_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#input\_capacity\_reservation\_specification) | Describes an instance's Capacity Reservation targeting option | `any` | `{}` | no | | <a name="input_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#input\_capacity\_reservation\_specification) | Describes an instance's Capacity Reservation targeting option | `any` | `{}` | no |
...@@ -199,6 +206,7 @@ No modules. ...@@ -199,6 +206,7 @@ No modules.
| <a name="input_cpu_credits"></a> [cpu\_credits](#input\_cpu\_credits) | The credit option for CPU usage (unlimited or standard) | `string` | `null` | no | | <a name="input_cpu_credits"></a> [cpu\_credits](#input\_cpu\_credits) | The credit option for CPU usage (unlimited or standard) | `string` | `null` | no |
| <a name="input_cpu_threads_per_core"></a> [cpu\_threads\_per\_core](#input\_cpu\_threads\_per\_core) | Sets the number of CPU threads per core for an instance (has no effect unless cpu\_core\_count is also set). | `number` | `null` | no | | <a name="input_cpu_threads_per_core"></a> [cpu\_threads\_per\_core](#input\_cpu\_threads\_per\_core) | Sets the number of CPU threads per core for an instance (has no effect unless cpu\_core\_count is also set). | `number` | `null` | no |
| <a name="input_create"></a> [create](#input\_create) | Whether to create an instance | `bool` | `true` | no | | <a name="input_create"></a> [create](#input\_create) | Whether to create an instance | `bool` | `true` | no |
| <a name="input_create_iam_instance_profile"></a> [create\_iam\_instance\_profile](#input\_create\_iam\_instance\_profile) | Determines whether an IAM instance profile is created or to use an existing IAM instance profile | `bool` | `false` | no |
| <a name="input_create_spot_instance"></a> [create\_spot\_instance](#input\_create\_spot\_instance) | Depicts if the instance is a spot instance | `bool` | `false` | no | | <a name="input_create_spot_instance"></a> [create\_spot\_instance](#input\_create\_spot\_instance) | Depicts if the instance is a spot instance | `bool` | `false` | no |
| <a name="input_disable_api_stop"></a> [disable\_api\_stop](#input\_disable\_api\_stop) | If true, enables EC2 Instance Stop Protection. | `bool` | `null` | no | | <a name="input_disable_api_stop"></a> [disable\_api\_stop](#input\_disable\_api\_stop) | If true, enables EC2 Instance Stop Protection. | `bool` | `null` | no |
| <a name="input_disable_api_termination"></a> [disable\_api\_termination](#input\_disable\_api\_termination) | If true, enables EC2 Instance Termination Protection | `bool` | `null` | no | | <a name="input_disable_api_termination"></a> [disable\_api\_termination](#input\_disable\_api\_termination) | If true, enables EC2 Instance Termination Protection | `bool` | `null` | no |
...@@ -211,6 +219,13 @@ No modules. ...@@ -211,6 +219,13 @@ No modules.
| <a name="input_hibernation"></a> [hibernation](#input\_hibernation) | If true, the launched EC2 instance will support hibernation | `bool` | `null` | no | | <a name="input_hibernation"></a> [hibernation](#input\_hibernation) | If true, the launched EC2 instance will support hibernation | `bool` | `null` | no |
| <a name="input_host_id"></a> [host\_id](#input\_host\_id) | ID of a dedicated host that the instance will be assigned to. Use when an instance is to be launched on a specific dedicated host | `string` | `null` | no | | <a name="input_host_id"></a> [host\_id](#input\_host\_id) | ID of a dedicated host that the instance will be assigned to. Use when an instance is to be launched on a specific dedicated host | `string` | `null` | no |
| <a name="input_iam_instance_profile"></a> [iam\_instance\_profile](#input\_iam\_instance\_profile) | IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile | `string` | `null` | no | | <a name="input_iam_instance_profile"></a> [iam\_instance\_profile](#input\_iam\_instance\_profile) | IAM Instance Profile to launch the instance with. Specified as the name of the Instance Profile | `string` | `null` | no |
| <a name="input_iam_role_description"></a> [iam\_role\_description](#input\_iam\_role\_description) | Description of the role | `string` | `null` | no |
| <a name="input_iam_role_name"></a> [iam\_role\_name](#input\_iam\_role\_name) | Name to use on IAM role created | `string` | `null` | no |
| <a name="input_iam_role_path"></a> [iam\_role\_path](#input\_iam\_role\_path) | IAM role path | `string` | `null` | no |
| <a name="input_iam_role_permissions_boundary"></a> [iam\_role\_permissions\_boundary](#input\_iam\_role\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the IAM role | `string` | `null` | no |
| <a name="input_iam_role_policies"></a> [iam\_role\_policies](#input\_iam\_role\_policies) | Policies attached to the IAM role | `map(string)` | `{}` | no |
| <a name="input_iam_role_tags"></a> [iam\_role\_tags](#input\_iam\_role\_tags) | A map of additional tags to add to the IAM role/profile created | `map(string)` | `{}` | no |
| <a name="input_iam_role_use_name_prefix"></a> [iam\_role\_use\_name\_prefix](#input\_iam\_role\_use\_name\_prefix) | Determines whether the IAM role name (`iam_role_name` or `name`) is used as a prefix | `bool` | `true` | no |
| <a name="input_instance_initiated_shutdown_behavior"></a> [instance\_initiated\_shutdown\_behavior](#input\_instance\_initiated\_shutdown\_behavior) | Shutdown behavior for the instance. Amazon defaults this to stop for EBS-backed instances and terminate for instance-store instances. Cannot be set on instance-store instance | `string` | `null` | no | | <a name="input_instance_initiated_shutdown_behavior"></a> [instance\_initiated\_shutdown\_behavior](#input\_instance\_initiated\_shutdown\_behavior) | Shutdown behavior for the instance. Amazon defaults this to stop for EBS-backed instances and terminate for instance-store instances. Cannot be set on instance-store instance | `string` | `null` | no |
| <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | The type of instance to start | `string` | `"t3.micro"` | no | | <a name="input_instance_type"></a> [instance\_type](#input\_instance\_type) | The type of instance to start | `string` | `"t3.micro"` | no |
| <a name="input_ipv6_address_count"></a> [ipv6\_address\_count](#input\_ipv6\_address\_count) | A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet | `number` | `null` | no | | <a name="input_ipv6_address_count"></a> [ipv6\_address\_count](#input\_ipv6\_address\_count) | A number of IPv6 addresses to associate with the primary network interface. Amazon EC2 chooses the IPv6 addresses from the range of your subnet | `number` | `null` | no |
...@@ -251,6 +266,12 @@ No modules. ...@@ -251,6 +266,12 @@ No modules.
|------|-------------| |------|-------------|
| <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the instance | | <a name="output_arn"></a> [arn](#output\_arn) | The ARN of the instance |
| <a name="output_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#output\_capacity\_reservation\_specification) | Capacity reservation specification of the instance | | <a name="output_capacity_reservation_specification"></a> [capacity\_reservation\_specification](#output\_capacity\_reservation\_specification) | Capacity reservation specification of the instance |
| <a name="output_iam_instance_profile_arn"></a> [iam\_instance\_profile\_arn](#output\_iam\_instance\_profile\_arn) | ARN assigned by AWS to the instance profile |
| <a name="output_iam_instance_profile_id"></a> [iam\_instance\_profile\_id](#output\_iam\_instance\_profile\_id) | Instance profile's ID |
| <a name="output_iam_instance_profile_unique"></a> [iam\_instance\_profile\_unique](#output\_iam\_instance\_profile\_unique) | Stable and unique string identifying the IAM instance profile |
| <a name="output_iam_role_arn"></a> [iam\_role\_arn](#output\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role |
| <a name="output_iam_role_name"></a> [iam\_role\_name](#output\_iam\_role\_name) | The name of the IAM role |
| <a name="output_iam_role_unique_id"></a> [iam\_role\_unique\_id](#output\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role |
| <a name="output_id"></a> [id](#output\_id) | The ID of the instance | | <a name="output_id"></a> [id](#output\_id) | The ID of the instance |
| <a name="output_instance_state"></a> [instance\_state](#output\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` | | <a name="output_instance_state"></a> [instance\_state](#output\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` |
| <a name="output_ipv6_addresses"></a> [ipv6\_addresses](#output\_ipv6\_addresses) | The IPv6 address assigned to the instance, if applicable. | | <a name="output_ipv6_addresses"></a> [ipv6\_addresses](#output\_ipv6\_addresses) | The IPv6 address assigned to the instance, if applicable. |
......
...@@ -66,6 +66,12 @@ No inputs. ...@@ -66,6 +66,12 @@ No inputs.
|------|-------------| |------|-------------|
| <a name="output_ec2_complete_arn"></a> [ec2\_complete\_arn](#output\_ec2\_complete\_arn) | The ARN of the instance | | <a name="output_ec2_complete_arn"></a> [ec2\_complete\_arn](#output\_ec2\_complete\_arn) | The ARN of the instance |
| <a name="output_ec2_complete_capacity_reservation_specification"></a> [ec2\_complete\_capacity\_reservation\_specification](#output\_ec2\_complete\_capacity\_reservation\_specification) | Capacity reservation specification of the instance | | <a name="output_ec2_complete_capacity_reservation_specification"></a> [ec2\_complete\_capacity\_reservation\_specification](#output\_ec2\_complete\_capacity\_reservation\_specification) | Capacity reservation specification of the instance |
| <a name="output_ec2_complete_iam_instance_profile_arn"></a> [ec2\_complete\_iam\_instance\_profile\_arn](#output\_ec2\_complete\_iam\_instance\_profile\_arn) | ARN assigned by AWS to the instance profile |
| <a name="output_ec2_complete_iam_instance_profile_id"></a> [ec2\_complete\_iam\_instance\_profile\_id](#output\_ec2\_complete\_iam\_instance\_profile\_id) | Instance profile's ID |
| <a name="output_ec2_complete_iam_instance_profile_unique"></a> [ec2\_complete\_iam\_instance\_profile\_unique](#output\_ec2\_complete\_iam\_instance\_profile\_unique) | Stable and unique string identifying the IAM instance profile |
| <a name="output_ec2_complete_iam_role_arn"></a> [ec2\_complete\_iam\_role\_arn](#output\_ec2\_complete\_iam\_role\_arn) | The Amazon Resource Name (ARN) specifying the IAM role |
| <a name="output_ec2_complete_iam_role_name"></a> [ec2\_complete\_iam\_role\_name](#output\_ec2\_complete\_iam\_role\_name) | The name of the IAM role |
| <a name="output_ec2_complete_iam_role_unique_id"></a> [ec2\_complete\_iam\_role\_unique\_id](#output\_ec2\_complete\_iam\_role\_unique\_id) | Stable and unique string identifying the IAM role |
| <a name="output_ec2_complete_id"></a> [ec2\_complete\_id](#output\_ec2\_complete\_id) | The ID of the instance | | <a name="output_ec2_complete_id"></a> [ec2\_complete\_id](#output\_ec2\_complete\_id) | The ID of the instance |
| <a name="output_ec2_complete_instance_state"></a> [ec2\_complete\_instance\_state](#output\_ec2\_complete\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` | | <a name="output_ec2_complete_instance_state"></a> [ec2\_complete\_instance\_state](#output\_ec2\_complete\_instance\_state) | The state of the instance. One of: `pending`, `running`, `shutting-down`, `terminated`, `stopping`, `stopped` |
| <a name="output_ec2_complete_primary_network_interface_id"></a> [ec2\_complete\_primary\_network\_interface\_id](#output\_ec2\_complete\_primary\_network\_interface\_id) | The ID of the instance's primary network interface | | <a name="output_ec2_complete_primary_network_interface_id"></a> [ec2\_complete\_primary\_network\_interface\_id](#output\_ec2\_complete\_primary\_network\_interface\_id) | The ID of the instance's primary network interface |
......
...@@ -33,7 +33,7 @@ module "ec2_complete" { ...@@ -33,7 +33,7 @@ module "ec2_complete" {
name = local.name name = local.name
ami = data.aws_ami.amazon_linux.id ami = data.aws_ami.amazon_linux.id
instance_type = "c5.4xlarge" instance_type = "c5.xlarge" # used to set core count below
availability_zone = element(module.vpc.azs, 0) availability_zone = element(module.vpc.azs, 0)
subnet_id = element(module.vpc.private_subnets, 0) subnet_id = element(module.vpc.private_subnets, 0)
vpc_security_group_ids = [module.security_group.security_group_id] vpc_security_group_ids = [module.security_group.security_group_id]
...@@ -41,6 +41,12 @@ module "ec2_complete" { ...@@ -41,6 +41,12 @@ module "ec2_complete" {
associate_public_ip_address = true associate_public_ip_address = true
disable_api_stop = false disable_api_stop = false
create_iam_instance_profile = true
iam_role_description = "IAM role for EC2 instance"
iam_role_policies = {
AdministratorAccess = "arn:aws:iam::aws:policy/AdministratorAccess"
}
# only one of these can be enabled at a time # only one of these can be enabled at a time
hibernation = true hibernation = true
# enclave_options_enabled = true # enclave_options_enabled = true
...@@ -83,9 +89,6 @@ module "ec2_network_interface" { ...@@ -83,9 +89,6 @@ module "ec2_network_interface" {
name = "${local.name}-network-interface" name = "${local.name}-network-interface"
ami = data.aws_ami.amazon_linux.id
instance_type = "c5.large"
network_interface = [ network_interface = [
{ {
device_index = 0 device_index = 0
...@@ -102,8 +105,6 @@ module "ec2_metadata_options" { ...@@ -102,8 +105,6 @@ module "ec2_metadata_options" {
name = "${local.name}-metadata-options" name = "${local.name}-metadata-options"
ami = data.aws_ami.amazon_linux.id
instance_type = "c5.4xlarge"
subnet_id = element(module.vpc.private_subnets, 0) subnet_id = element(module.vpc.private_subnets, 0)
vpc_security_group_ids = [module.security_group.security_group_id] vpc_security_group_ids = [module.security_group.security_group_id]
...@@ -122,7 +123,6 @@ module "ec2_t2_unlimited" { ...@@ -122,7 +123,6 @@ module "ec2_t2_unlimited" {
name = "${local.name}-t2-unlimited" name = "${local.name}-t2-unlimited"
ami = data.aws_ami.amazon_linux.id
instance_type = "t2.micro" instance_type = "t2.micro"
cpu_credits = "unlimited" cpu_credits = "unlimited"
subnet_id = element(module.vpc.private_subnets, 0) subnet_id = element(module.vpc.private_subnets, 0)
...@@ -137,7 +137,6 @@ module "ec2_t3_unlimited" { ...@@ -137,7 +137,6 @@ module "ec2_t3_unlimited" {
name = "${local.name}-t3-unlimited" name = "${local.name}-t3-unlimited"
ami = data.aws_ami.amazon_linux.id
instance_type = "t3.micro" instance_type = "t3.micro"
cpu_credits = "unlimited" cpu_credits = "unlimited"
subnet_id = element(module.vpc.private_subnets, 0) subnet_id = element(module.vpc.private_subnets, 0)
...@@ -196,7 +195,6 @@ module "ec2_multiple" { ...@@ -196,7 +195,6 @@ module "ec2_multiple" {
name = "${local.name}-multi-${each.key}" name = "${local.name}-multi-${each.key}"
ami = data.aws_ami.amazon_linux.id
instance_type = each.value.instance_type instance_type = each.value.instance_type
availability_zone = each.value.availability_zone availability_zone = each.value.availability_zone
subnet_id = each.value.subnet_id subnet_id = each.value.subnet_id
...@@ -218,7 +216,6 @@ module "ec2_spot_instance" { ...@@ -218,7 +216,6 @@ module "ec2_spot_instance" {
name = "${local.name}-spot-instance" name = "${local.name}-spot-instance"
create_spot_instance = true create_spot_instance = true
ami = data.aws_ami.amazon_linux.id
availability_zone = element(module.vpc.azs, 0) availability_zone = element(module.vpc.azs, 0)
subnet_id = element(module.vpc.private_subnets, 0) subnet_id = element(module.vpc.private_subnets, 0)
vpc_security_group_ids = [module.security_group.security_group_id] vpc_security_group_ids = [module.security_group.security_group_id]
...@@ -308,6 +305,22 @@ module "ec2_targeted_capacity_reservation" { ...@@ -308,6 +305,22 @@ module "ec2_targeted_capacity_reservation" {
tags = local.tags tags = local.tags
} }
resource "aws_ec2_capacity_reservation" "open" {
instance_type = "t3.micro"
instance_platform = "Linux/UNIX"
availability_zone = "${local.region}a"
instance_count = 1
instance_match_criteria = "open"
}
resource "aws_ec2_capacity_reservation" "targeted" {
instance_type = "t3.micro"
instance_platform = "Linux/UNIX"
availability_zone = "${local.region}a"
instance_count = 1
instance_match_criteria = "targeted"
}
################################################################################ ################################################################################
# Supporting Resources # Supporting Resources
################################################################################ ################################################################################
...@@ -363,19 +376,3 @@ resource "aws_kms_key" "this" { ...@@ -363,19 +376,3 @@ resource "aws_kms_key" "this" {
resource "aws_network_interface" "this" { resource "aws_network_interface" "this" {
subnet_id = element(module.vpc.private_subnets, 0) subnet_id = element(module.vpc.private_subnets, 0)
} }
resource "aws_ec2_capacity_reservation" "open" {
instance_type = "t3.micro"
instance_platform = "Linux/UNIX"
availability_zone = "${local.region}a"
instance_count = 1
instance_match_criteria = "open"
}
resource "aws_ec2_capacity_reservation" "targeted" {
instance_type = "t3.micro"
instance_platform = "Linux/UNIX"
availability_zone = "${local.region}a"
instance_count = 1
instance_match_criteria = "targeted"
}
...@@ -44,6 +44,36 @@ output "ec2_complete_tags_all" { ...@@ -44,6 +44,36 @@ output "ec2_complete_tags_all" {
value = module.ec2_complete.tags_all value = module.ec2_complete.tags_all
} }
output "ec2_complete_iam_role_name" {
description = "The name of the IAM role"
value = module.ec2_complete.iam_role_name
}
output "ec2_complete_iam_role_arn" {
description = "The Amazon Resource Name (ARN) specifying the IAM role"
value = module.ec2_complete.iam_role_arn
}
output "ec2_complete_iam_role_unique_id" {
description = "Stable and unique string identifying the IAM role"
value = module.ec2_complete.iam_role_unique_id
}
output "ec2_complete_iam_instance_profile_arn" {
description = "ARN assigned by AWS to the instance profile"
value = module.ec2_complete.iam_instance_profile_arn
}
output "ec2_complete_iam_instance_profile_id" {
description = "Instance profile's ID"
value = module.ec2_complete.iam_instance_profile_id
}
output "ec2_complete_iam_instance_profile_unique" {
description = "Stable and unique string identifying the IAM instance profile"
value = module.ec2_complete.iam_instance_profile_unique
}
# EC2 T2 Unlimited # EC2 T2 Unlimited
output "ec2_t2_unlimited_id" { output "ec2_t2_unlimited_id" {
description = "The ID of the instance" description = "The ID of the instance"
......
data "aws_partition" "current" {}
locals { locals {
create = var.create && var.putin_khuylo create = var.create && var.putin_khuylo
is_t_instance_type = replace(var.instance_type, "/^t(2|3|3a){1}\\..*$/", "1") == "1" ? true : false is_t_instance_type = replace(var.instance_type, "/^t(2|3|3a){1}\\..*$/", "1") == "1" ? true : false
} }
data "aws_ssm_parameter" "this" {
count = local.create ? 1 : 0
name = var.ami_ssm_parameter
}
################################################################################
# Instance
################################################################################
resource "aws_instance" "this" { resource "aws_instance" "this" {
count = local.create && !var.create_spot_instance ? 1 : 0 count = local.create && !var.create_spot_instance ? 1 : 0
ami = var.ami ami = try(coalesce(var.ami, data.aws_ssm_parameter.this[0].value), null)
instance_type = var.instance_type instance_type = var.instance_type
cpu_core_count = var.cpu_core_count cpu_core_count = var.cpu_core_count
cpu_threads_per_core = var.cpu_threads_per_core cpu_threads_per_core = var.cpu_threads_per_core
...@@ -24,7 +36,7 @@ resource "aws_instance" "this" { ...@@ -24,7 +36,7 @@ resource "aws_instance" "this" {
key_name = var.key_name key_name = var.key_name
monitoring = var.monitoring monitoring = var.monitoring
get_password_data = var.get_password_data get_password_data = var.get_password_data
iam_instance_profile = var.iam_instance_profile iam_instance_profile = var.create_iam_instance_profile ? aws_iam_instance_profile.this[0].name : var.iam_instance_profile
associate_public_ip_address = var.associate_public_ip_address associate_public_ip_address = var.associate_public_ip_address
private_ip = var.private_ip private_ip = var.private_ip
...@@ -141,10 +153,14 @@ resource "aws_instance" "this" { ...@@ -141,10 +153,14 @@ resource "aws_instance" "this" {
volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null
} }
################################################################################
# Spot Instance
################################################################################
resource "aws_spot_instance_request" "this" { resource "aws_spot_instance_request" "this" {
count = local.create && var.create_spot_instance ? 1 : 0 count = local.create && var.create_spot_instance ? 1 : 0
ami = var.ami ami = try(coalesce(var.ami, data.aws_ssm_parameter.this[0].value), null)
instance_type = var.instance_type instance_type = var.instance_type
cpu_core_count = var.cpu_core_count cpu_core_count = var.cpu_core_count
cpu_threads_per_core = var.cpu_threads_per_core cpu_threads_per_core = var.cpu_threads_per_core
...@@ -161,7 +177,7 @@ resource "aws_spot_instance_request" "this" { ...@@ -161,7 +177,7 @@ resource "aws_spot_instance_request" "this" {
key_name = var.key_name key_name = var.key_name
monitoring = var.monitoring monitoring = var.monitoring
get_password_data = var.get_password_data get_password_data = var.get_password_data
iam_instance_profile = var.iam_instance_profile iam_instance_profile = var.create_iam_instance_profile ? aws_iam_instance_profile.this[0].name : var.iam_instance_profile
associate_public_ip_address = var.associate_public_ip_address associate_public_ip_address = var.associate_public_ip_address
private_ip = var.private_ip private_ip = var.private_ip
...@@ -285,3 +301,63 @@ resource "aws_spot_instance_request" "this" { ...@@ -285,3 +301,63 @@ resource "aws_spot_instance_request" "this" {
tags = merge({ "Name" = var.name }, var.tags) tags = merge({ "Name" = var.name }, var.tags)
volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null volume_tags = var.enable_volume_tags ? merge({ "Name" = var.name }, var.volume_tags) : null
} }
################################################################################
# IAM Role / Instance Profile
################################################################################
locals {
iam_role_name = try(coalesce(var.iam_role_name, var.name), "")
}
data "aws_iam_policy_document" "assume_role_policy" {
count = var.create && var.create_iam_instance_profile ? 1 : 0
statement {
sid = "EC2AssumeRole"
actions = ["sts:AssumeRole"]
principals {
type = "Service"
identifiers = ["ec2.${data.aws_partition.current.dns_suffix}"]
}
}
}
resource "aws_iam_role" "this" {
count = var.create && var.create_iam_instance_profile ? 1 : 0
name = var.iam_role_use_name_prefix ? null : local.iam_role_name
name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null
path = var.iam_role_path
description = var.iam_role_description
assume_role_policy = data.aws_iam_policy_document.assume_role_policy[0].json
permissions_boundary = var.iam_role_permissions_boundary
force_detach_policies = true
tags = merge(var.tags, var.iam_role_tags)
}
resource "aws_iam_role_policy_attachment" "this" {
for_each = { for k, v in var.iam_role_policies : k => v if var.create && var.create_iam_instance_profile }
policy_arn = each.value
role = aws_iam_role.this[0].name
}
resource "aws_iam_instance_profile" "this" {
count = var.create && var.create_iam_instance_profile ? 1 : 0
role = aws_iam_role.this[0].name
name = var.iam_role_use_name_prefix ? null : local.iam_role_name
name_prefix = var.iam_role_use_name_prefix ? "${local.iam_role_name}-" : null
path = var.iam_role_path
tags = merge(var.tags, var.iam_role_tags)
lifecycle {
create_before_destroy = true
}
}
...@@ -77,3 +77,37 @@ output "spot_instance_id" { ...@@ -77,3 +77,37 @@ output "spot_instance_id" {
description = "The Instance ID (if any) that is currently fulfilling the Spot Instance request" description = "The Instance ID (if any) that is currently fulfilling the Spot Instance request"
value = try(aws_spot_instance_request.this[0].spot_instance_id, "") value = try(aws_spot_instance_request.this[0].spot_instance_id, "")
} }
################################################################################
# IAM Role / Instance Profile
################################################################################
output "iam_role_name" {
description = "The name of the IAM role"
value = try(aws_iam_role.this[0].name, null)
}
output "iam_role_arn" {
description = "The Amazon Resource Name (ARN) specifying the IAM role"
value = try(aws_iam_role.this[0].arn, null)
}
output "iam_role_unique_id" {
description = "Stable and unique string identifying the IAM role"
value = try(aws_iam_role.this[0].unique_id, null)
}
output "iam_instance_profile_arn" {
description = "ARN assigned by AWS to the instance profile"
value = try(aws_iam_instance_profile.this[0].arn, null)
}
output "iam_instance_profile_id" {
description = "Instance profile's ID"
value = try(aws_iam_instance_profile.this[0].id, null)
}
output "iam_instance_profile_unique" {
description = "Stable and unique string identifying the IAM instance profile"
value = try(aws_iam_instance_profile.this[0].unique_id, null)
}
...@@ -10,10 +10,16 @@ variable "name" { ...@@ -10,10 +10,16 @@ variable "name" {
default = "" default = ""
} }
variable "ami_ssm_parameter" {
description = "SSM parameter name for the AMI ID. For Amazon Linux AMI SSM parameters see [reference](https://docs.aws.amazon.com/systems-manager/latest/userguide/parameter-store-public-parameters-ami.html)"
type = string
default = "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2"
}
variable "ami" { variable "ami" {
description = "ID of AMI to use for the instance" description = "ID of AMI to use for the instance"
type = string type = string
default = "" default = null
} }
variable "associate_public_ip_address" { variable "associate_public_ip_address" {
...@@ -316,3 +322,55 @@ variable "putin_khuylo" { ...@@ -316,3 +322,55 @@ variable "putin_khuylo" {
type = bool type = bool
default = true default = true
} }
################################################################################
# IAM Role / Instance Profile
################################################################################
variable "create_iam_instance_profile" {
description = "Determines whether an IAM instance profile is created or to use an existing IAM instance profile"
type = bool
default = false
}
variable "iam_role_name" {
description = "Name to use on IAM role created"
type = string
default = null
}
variable "iam_role_use_name_prefix" {
description = "Determines whether the IAM role name (`iam_role_name` or `name`) is used as a prefix"
type = bool
default = true
}
variable "iam_role_path" {
description = "IAM role path"
type = string
default = null
}
variable "iam_role_description" {
description = "Description of the role"
type = string
default = null
}
variable "iam_role_permissions_boundary" {
description = "ARN of the policy that is used to set the permissions boundary for the IAM role"
type = string
default = null
}
variable "iam_role_policies" {
description = "Policies attached to the IAM role"
type = map(string)
default = {}
}
variable "iam_role_tags" {
description = "A map of additional tags to add to the IAM role/profile created"
type = map(string)
default = {}
}
...@@ -14,7 +14,7 @@ This wrapper does not implement any extra functionality. ...@@ -14,7 +14,7 @@ This wrapper does not implement any extra functionality.
terraform { terraform {
source = "tfr:///terraform-aws-modules/ec2-instance/aws//wrappers" source = "tfr:///terraform-aws-modules/ec2-instance/aws//wrappers"
# Alternative source: # Alternative source:
# source = "git::git@github.com:terraform-aws-modules/terraform-aws-ec2-instance.git?ref=master//wrappers" # source = "git::git@github.com:terraform-aws-modules/terraform-aws-ec2-instance.git//wrappers?ref=master"
} }
inputs = { inputs = {
...@@ -72,7 +72,7 @@ module "wrapper" { ...@@ -72,7 +72,7 @@ module "wrapper" {
terraform { terraform {
source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers" source = "tfr:///terraform-aws-modules/s3-bucket/aws//wrappers"
# Alternative source: # Alternative source:
# source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git?ref=master//wrappers" # source = "git::git@github.com:terraform-aws-modules/terraform-aws-s3-bucket.git//wrappers?ref=master"
} }
inputs = { inputs = {
......
...@@ -5,7 +5,8 @@ module "wrapper" { ...@@ -5,7 +5,8 @@ module "wrapper" {
create = try(each.value.create, var.defaults.create, true) create = try(each.value.create, var.defaults.create, true)
name = try(each.value.name, var.defaults.name, "") name = try(each.value.name, var.defaults.name, "")
ami = try(each.value.ami, var.defaults.ami, "") ami_ssm_parameter = try(each.value.ami_ssm_parameter, var.defaults.ami_ssm_parameter, "/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2")
ami = try(each.value.ami, var.defaults.ami, null)
associate_public_ip_address = try(each.value.associate_public_ip_address, var.defaults.associate_public_ip_address, null) associate_public_ip_address = try(each.value.associate_public_ip_address, var.defaults.associate_public_ip_address, null)
availability_zone = try(each.value.availability_zone, var.defaults.availability_zone, null) availability_zone = try(each.value.availability_zone, var.defaults.availability_zone, null)
capacity_reservation_specification = try(each.value.capacity_reservation_specification, var.defaults.capacity_reservation_specification, {}) capacity_reservation_specification = try(each.value.capacity_reservation_specification, var.defaults.capacity_reservation_specification, {})
...@@ -56,4 +57,12 @@ module "wrapper" { ...@@ -56,4 +57,12 @@ module "wrapper" {
spot_valid_from = try(each.value.spot_valid_from, var.defaults.spot_valid_from, null) spot_valid_from = try(each.value.spot_valid_from, var.defaults.spot_valid_from, null)
disable_api_stop = try(each.value.disable_api_stop, var.defaults.disable_api_stop, null) disable_api_stop = try(each.value.disable_api_stop, var.defaults.disable_api_stop, null)
putin_khuylo = try(each.value.putin_khuylo, var.defaults.putin_khuylo, true) putin_khuylo = try(each.value.putin_khuylo, var.defaults.putin_khuylo, true)
create_iam_instance_profile = try(each.value.create_iam_instance_profile, var.defaults.create_iam_instance_profile, false)
iam_role_name = try(each.value.iam_role_name, var.defaults.iam_role_name, null)
iam_role_use_name_prefix = try(each.value.iam_role_use_name_prefix, var.defaults.iam_role_use_name_prefix, true)
iam_role_path = try(each.value.iam_role_path, var.defaults.iam_role_path, null)
iam_role_description = try(each.value.iam_role_description, var.defaults.iam_role_description, null)
iam_role_permissions_boundary = try(each.value.iam_role_permissions_boundary, var.defaults.iam_role_permissions_boundary, null)
iam_role_policies = try(each.value.iam_role_policies, var.defaults.iam_role_policies, {})
iam_role_tags = try(each.value.iam_role_tags, var.defaults.iam_role_tags, {})
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment