Skip to content

Commit

Permalink
[breaking] [feature] aws-iam-instance-profile reuse existing role and…
Browse files Browse the repository at this point in the history
… remove SSM support (#183)

* Allows passing an existing role to aws-iam-instance-profile, and the module will attach whatever permissions are needed. This allows using roles that are created and managed by other modules (e.g. EKS worker role), but provides ability to attach a standard set of permissions to that role. It will still always create the instance profile, even if the profile will be unused.
* Removes unused permissions from the aws-iam-instance-profile module for using SSM.
  • Loading branch information
mbarrien authored Mar 24, 2020
1 parent 8d7f1ff commit b31cd72
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 130 deletions.
3 changes: 2 additions & 1 deletion aws-iam-instance-profile/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ resource "aws_instance" "instance" {

| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:-----:|
| enable\_ssm | Attach the appropriate policies to allow the instance to integrate with AWS Systems Manager. | `string` | `"true"` | no |
| create\_role | Creates a role for use with the instance profile. | `bool` | `true` | no |
| existing\_role\_name | Use existing role with the given name instead of creating a new role. Attaches all standard policies to given role. Only used if create\_role is false. | `string` | n/a | yes |
| iam\_path | The IAM path to the role. | `string` | `"/"` | no |
| name\_prefix | Creates a unique name for both the role and instance profile beginning with the specified prefix. Max 32 characters long. | `string` | n/a | yes |
| role\_description | The description of the IAM role. | `string` | `""` | no |
Expand Down
112 changes: 7 additions & 105 deletions aws-iam-instance-profile/main.tf
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
locals {
role_name = coalescelist(aws_iam_role.role[*].name, [var.existing_role_name])[0]
}

data "aws_iam_policy_document" "assume-role" {
statement {
sid = "AssumeRole"
Expand All @@ -11,6 +15,7 @@ data "aws_iam_policy_document" "assume-role" {
}

resource "aws_iam_role" "role" {
count = var.create_role ? 1 : 0
name_prefix = var.name_prefix
description = var.role_description
path = var.iam_path
Expand All @@ -21,120 +26,17 @@ resource "aws_iam_role" "role" {
}
}

resource "aws_iam_role_policy" "ssm" {
count = var.enable_ssm ? 1 : 0
role = aws_iam_role.role.name
policy = data.aws_iam_policy_document.ssm_policy.json
}

resource "aws_iam_role_policy_attachment" "cloudwatch-agent" {
role = aws_iam_role.role.name
role = local.role_name
policy_arn = "arn:aws:iam::aws:policy/CloudWatchAgentServerPolicy"
}

resource "aws_iam_instance_profile" "profile" {
name_prefix = var.name_prefix
path = var.iam_path
role = aws_iam_role.role.name
role = local.role_name

lifecycle {
ignore_changes = [name, name_prefix, path]
}
}

data "aws_iam_policy_document" "ssm_policy" {
statement {
actions = [
"ssm:DescribeAssociation",
"ssm:GetDeployablePatchSnapshotForInstance",
"ssm:GetDocument",
"ssm:DescribeDocument",
"ssm:GetManifest",
"ssm:GetParameters",
"ssm:ListAssociations",
"ssm:ListInstanceAssociations",
"ssm:PutInventory",
"ssm:PutComplianceItems",
"ssm:PutConfigurePackageResult",
"ssm:UpdateAssociationStatus",
"ssm:UpdateInstanceAssociationStatus",
"ssm:UpdateInstanceInformation",
]

resources = ["*"]
}

statement {
actions = [
"ssmmessages:CreateControlChannel",
"ssmmessages:CreateDataChannel",
"ssmmessages:OpenControlChannel",
"ssmmessages:OpenDataChannel",
]

resources = ["*"]
}

statement {
actions = [
"ec2messages:AcknowledgeMessage",
"ec2messages:DeleteMessage",
"ec2messages:FailMessage",
"ec2messages:GetEndpoint",
"ec2messages:GetMessages",
"ec2messages:SendReply",
]

resources = ["*"]
}

statement {
actions = ["cloudwatch:PutMetricData"]

resources = ["*"]
}

statement {
actions = ["ec2:DescribeInstanceStatus"]

resources = ["*"]
}

statement {
actions = [
"ds:CreateComputer",
"ds:DescribeDirectories",
]

resources = ["*"]
}

statement {
actions = [
"logs:CreateLogGroup",
"logs:CreateLogStream",
"logs:DescribeLogGroups",
"logs:DescribeLogStreams",
"logs:PutLogEvents",
]

resources = ["*"]
}

statement {
actions = [
"s3:GetObject",
"s3:ListBucket",
]

//https://docs.aws.amazon.com/systems-manager/latest/userguide/ssm-agent-minimum-s3-permissions.html
resources = [
"arn:aws:s3:::aws-ssm-*/*",
"arn:aws:s3:::aws-windows-downloads-*/*",
"arn:aws:s3:::amazon-ssm-*/*",
"arn:aws:s3:::amazon-ssm-packages-*/*",
"arn:aws:s3:::*-birdwatcher-prod/*",
"arn:aws:s3:::patch-baseline-snapshot-*/*",
]
}
}
16 changes: 0 additions & 16 deletions aws-iam-instance-profile/module_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,3 @@ func TestAWSIAMInstanceProfile(t *testing.T) {

testutil.Run(t, terraformOptions)
}

func TestAWSIAMInstanceProfileDisableSSM(t *testing.T) {
terraformOptions := testutil.Options(
testutil.IAMRegion,
map[string]interface{}{
"name_prefix": random.UniqueId(),
"iam_path": "/foo/",
"role_description": random.UniqueId(),
"enable_ssm": "false",
},
)

defer terraform.Destroy(t, terraformOptions)

testutil.Run(t, terraformOptions)
}
4 changes: 2 additions & 2 deletions aws-iam-instance-profile/outputs.tf
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
output "role_arn" {
value = aws_iam_role.role.arn
value = coalescelist(aws_iam_role.role[*].arn, [""])[0]
description = "The Amazon Resource Name (ARN) specifying the role."
}

output "role_name" {
value = aws_iam_role.role.name
value = local.role_name
description = "The name of the role."
}

Expand Down
18 changes: 12 additions & 6 deletions aws-iam-instance-profile/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,18 @@ variable "name_prefix" {
description = "Creates a unique name for both the role and instance profile beginning with the specified prefix. Max 32 characters long."
}

variable "existing_role_name" {
type = string
description = "Use existing role with the given name instead of creating a new role. Attaches all standard policies to given role. Only used if create_role is false."
default = null
}

variable "create_role" {
type = bool
description = "Creates a role for use with the instance profile."
default = true
}

variable "iam_path" {
type = string
default = "/"
Expand All @@ -14,9 +26,3 @@ variable "role_description" {
description = "The description of the IAM role."
default = ""
}

variable "enable_ssm" {
type = string
description = "Attach the appropriate policies to allow the instance to integrate with AWS Systems Manager."
default = "true"
}

0 comments on commit b31cd72

Please sign in to comment.