diff --git a/README.md b/README.md index 98ba146..414cc77 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ # Terraform AWS Session Manager -A Terraform module to setup [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html). +A Terraform module to setup [AWS Systems Manager Session Manager](https://docs.aws.amazon.com/systems-manager/latest/userguide/session-manager.html). -This module creates the a SSM document to support encrypted session manager communication and logs. It also creates a KMS key, S3 bucket, and CloudWatch Log group to store logs. In addition, for EC2 instances without a public IP address it can create VPC endpoints to enable private session manager communication. However, the VPC endpoint creation can also be facilitated by other modules such as [this](https://github.com/terraform-aws-modules/terraform-aws-vpc). Be aware of the [AWS PrivateLink pricing](https://aws.amazon.com/privatelink/pricing/) before deployment. +This module creates the a SSM document to support encrypted session manager communication and logs. It also creates a KMS key, S3 bucket, and CloudWatch Log group to store logs. In addition, for EC2 instances without a public IP address it can create VPC endpoints to enable private session manager communication. However, the VPC endpoint creation can also be facilitated by other modules such as [this](https://github.com/terraform-aws-modules/terraform-aws-vpc). Be aware of the [AWS PrivateLink pricing](https://aws.amazon.com/privatelink/pricing/) before deployment. ## Usage @@ -29,62 +29,90 @@ module "ssm" { version = "0.2.0" bucket_name = "my-session-logs" access_log_bucket_name = "my-session-access-logs" - vpc_id = "vpc-0dc9ef19c0c23aeaa" - tags = { - Function = "ssm" - } enable_log_to_s3 = true enable_log_to_cloudwatch = true vpc_endpoints_enabled = true + vpc_id = "vpc-0dc9ef19c0c23aeaa" + tags = { + Function = "ssm" + } } ``` -This module does not create any IAM policies for access to session manager. To do that, look at example policies in the [AWS Documentation](https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-restrict-access-quickstart.html) +This module does not create any IAM policies for access to session manager. To do that, look at example policies in the [AWS Documentation](https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-restrict-access-quickstart.html) + +## Notes + +In case `Session Manager` has already been accessed using AWS console, `SSM-SessionManagerRunShell` document - which is otherwise managed by this module - may need to be deleted prior to running this module. The following error may occur if the document has not been deleted upfront: + +`Error: Error creating SSM document: DocumentAlreadyExists: Document with same name SSM-SessionManagerRunShell already exists` +To delete the document, issue: +`aws ssm delete-document --name SSM-SessionManagerRunShell` + +## Requirements + +| Name | Version | +|------|---------| +| terraform | >= 0.12 | +| aws | >= 1.36 | + +## Providers + +| Name | Version | +|------|---------| +| aws | >= 1.36 | ## Inputs + Below is a list of this modules input values: + | Name | Description | Type | Default | Required | |------|-------------|------|---------|:-----:| -| bucket\_name | Name of S3 bucket to store session logs | `string` | | yes | +| bucket\_name | Name of S3 bucket to store session logs | `string` | `ssm-session-logs--` | no | +| bucket\_key\_prefix | Name of S3 sub-folder (prefix) | `string` | | no | | log\_archive\_days | Number of days to wait before archiving to Glacier | `number` | `30` | no | | log\_expire\_days | Number of days to wait before deleting session logs | `number` | `365` | no | -| access\_log\_bucket\_name | Name of the S3 bucket to store bucket access logs | `string` | | yes | +| access\_log\_bucket\_name | Name of the S3 bucket to store bucket access logs | `string` | `ssm-session-access-logs--` | no | | access\_log\_expire\_days | Number of days to wait before deleting access logs | `number` | `30` | no | -| kms\_key\_deletion\_window | Waiting period for scheduled KMS Key deletion. Can be 7-30 days | `number` | `7` | no | -| kms\_key\_alias | Alias of the KMS key. Must start with alias/ followed by a name | `string` | `alias/ssm-key` | no | +| kms\_key\_deletion\_window | Number of days to wait for scheduled KMS Key deletion [7-30] | `number` | `7` | no | +| kms\_key\_alias | Alias of the KMS key. Must start with alias/ followed by a name | `string` | `alias/ssm-key` | no | | cloudwatch\_logs\_retention | Number of days to retain Session Logs in CloudWatch | `number` | `30` | no | | cloudwatch\_log\_group\_name | Name of the CloudWatch Log Group for storing SSM Session Logs | `string` | `/ssm/session-logs` | no | -| tags | A map of tags to add to all resources | `map(string)` | `{}` | no | -| vpc\_id | VPC ID to deploy endpoints to | `string` | `null` | no | +| idle\_session\_timeout| Number of minutes a user can be inactive before a session ends [1-60] | `number` | `20` | no | +| run\_as\_default\_user | OS default user name, if IAM user/role 'SSMSessionRunAs' tag is undefined | `string` | `ssm-user` | no | +| shell\_profile\_windows | Environment variables, shell preferences, or commands to run when session starts | `string` | | no | +| shell\_profile\_linux | Environment variables, shell preferences, or commands to run when session starts | `string` | | no | | enable\_log\_to\_s3 | Enable Session Manager to Log to S3 | `bool` | `true` | no | | enable\_log\_to\_cloudwatch | Enable Session Manager to Log to CloudWatch Logs | `bool` | `true` | no | +| enable\_run\_as\_user | Enable Run As support for Linux instances | `bool` | `false` | no | | vpc\_endpoints\_enabled | Create VPC Endpoints | `bool` | `false` | no | - - +| vpc\_id | VPC ID to deploy endpoints to | `string` | `null` | no | +| tags | A map of tags to add to all resources | `map(string)` | `{}` | no | ## Outputs -| Name | Example Value | Description | -|------|----------------|-------------| -| session_logs_bucket_name | my-session-logs | S3 bucket for session logs | -| access_log_bucket_name | my-session-access-logs | S3 bucket for S3 access logs | -| cloudwatch_log_group_arn | arn:aws:logs:us-west-2:123456789012:log-group:/ssm/session-logs:* | CloudWatch Log group for session logs | -| kms_key_arn | arn:aws:kms:us-west-2:123456789012:key/2320fbba-d4e5-420d-82d3-1a4d6b8605e8 | KMS Key Arn for Encrypting logs and session | -| iam_role_arn | arn:aws:iam::123456789012:role/ssm_role | IAM Role for EC2 instances | -| iam_profile_name | ssm_profile | EC2 instance profile for SSM | -| ssm_security_group | ["sg-05e4f4cf12db5a191"] | Security Group used to access VPC Endpoints | -| vpc_endpoint_ssm | ["vpce-0cefc23e81d365733"] | VPC Endpoint for SSM | -| vpc_endpoint_ec2messages | ["vpce-0f507468fb9b06b8b"] | VPC Endpoint for EC2 Messages | -| vpc_endpoint_ssmmessages | ["vpce-0fe2cb670d40ec053"] | VPC Endpoint for SSM Messages | -| vpc_endpoint_s3 | ["vpce-0a8ebde94fa301a4a"] | VPC Endpoint for S3 | -| vpc_endpoint_logs | ["vpce-08c90d8df9ef37f90"] | VPC Endpoint for CloudWatch Logs | -| vpc_endpoint_kms | ["vpce-07ddc11beac1d4a3f"] | VPC Endpoint for KMS | +| Name | Example Value | Description | +|------|----------------|-------------| +| session\_logs\_bucket\_name | my-session-logs | S3 bucket for session logs | +| access\_log\_bucket\_name | my-session-access-logs | S3 bucket for S3 access logs | +| cloudwatch\_log\_group\_arn | arn:aws:logs:us-west-2:123456789012:log-group:/ssm/session-logs:\* | CloudWatch Log group for session logs | +| kms\_key\_arn | arn:aws:kms:us-west-2:123456789012:key/2320fbba-d4e5-420d-82d3-1a4d6b8605e8 | KMS Key Arn for Encrypting logs and session | +| iam\_policy\_arn | arn:aws:iam::123456789012:policy/ssm\_s3\_cwl\_kms\_access\_us-east-1 | IAM Policy for EC2 instances | +| iam\_role\_arn | arn:aws:iam::123456789012:role/ssm\_role\_us-east-1 | IAM Role for EC2 instances | +| iam\_profile\_name | ssm\_profile\_us-east-1 | EC2 instance profile for SSM | +| ssm\_security\_group | ["sg-05e4f4cf12db5a191"] | Security Group used to access VPC Endpoints | +| vpc\_endpoint\_ssm | ["vpce-0cefc23e81d365733"] | VPC Endpoint for SSM | +| vpc\_endpoint\_ec2messages | ["vpce-0f507468fb9b06b8b"] | VPC Endpoint for EC2 Messages | +| vpc\_endpoint\_ssmmessages | ["vpce-0fe2cb670d40ec053"] | VPC Endpoint for SSM Messages | +| vpc\_endpoint\_s3 | ["vpce-0a8ebde94fa301a4a"] | VPC Endpoint for S3 | +| vpc\_endpoint\_logs | ["vpce-08c90d8df9ef37f90"] | VPC Endpoint for CloudWatch Logs | +| vpc\_endpoint\_kms | ["vpce-07ddc11beac1d4a3f"] | VPC Endpoint for KMS | ## SSM Usage Example -* Launch an instance using the ssm_profile created by Terraform +* Launch an instance using the ssm\_profile created by Terraform * Install the session-manager-plugin and start a session ```bash diff --git a/main.tf b/main.tf index b628e28..92a4841 100644 --- a/main.tf +++ b/main.tf @@ -3,7 +3,8 @@ data "aws_caller_identity" "current" {} data "aws_region" "current" {} resource "aws_s3_bucket" "session_logs_bucket" { - bucket = var.bucket_name + count = var.enable_log_to_s3 ? 1 : 0 + bucket = var.bucket_name == "" ? "ssm-session-logs-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}" : var.bucket_name acl = "private" force_destroy = true tags = var.tags @@ -36,14 +37,15 @@ resource "aws_s3_bucket" "session_logs_bucket" { } logging { - target_bucket = aws_s3_bucket.access_log_bucket.id + target_bucket = aws_s3_bucket.access_log_bucket[0].id target_prefix = "log/" } } resource "aws_s3_bucket_public_access_block" "session_logs_bucket" { - bucket = aws_s3_bucket.session_logs_bucket.id + count = var.enable_log_to_s3 ? 1 : 0 + bucket = aws_s3_bucket.session_logs_bucket[0].id block_public_acls = true block_public_policy = true ignore_public_acls = true @@ -52,11 +54,11 @@ resource "aws_s3_bucket_public_access_block" "session_logs_bucket" { resource "aws_s3_bucket" "access_log_bucket" { - bucket = var.access_log_bucket_name + count = var.enable_log_to_s3 ? 1 : 0 + bucket = var.access_log_bucket_name == "" ? "ssm-session-access-logs-${data.aws_caller_identity.current.account_id}-${data.aws_region.current.name}" : var.access_log_bucket_name acl = "log-delivery-write" force_destroy = true - - tags = var.tags + tags = var.tags versioning { enabled = true @@ -82,14 +84,15 @@ resource "aws_s3_bucket" "access_log_bucket" { } resource "aws_s3_bucket_public_access_block" "access_log_bucket" { - bucket = aws_s3_bucket.access_log_bucket.id + count = var.enable_log_to_s3 ? 1 : 0 + bucket = aws_s3_bucket.access_log_bucket[0].id block_public_acls = true block_public_policy = true ignore_public_acls = true restrict_public_buckets = true } -data "aws_iam_policy_document" "kms_access" { +data "aws_iam_policy_document" "kms_key_default" { statement { sid = "KMS Key Default" principals { @@ -123,12 +126,11 @@ data "aws_iam_policy_document" "kms_access" { } - resource "aws_kms_key" "ssmkey" { - description = "SSM Key" + description = "SSM key" deletion_window_in_days = var.kms_key_deletion_window enable_key_rotation = true - policy = data.aws_iam_policy_document.kms_access.json + policy = data.aws_iam_policy_document.kms_key_default.json tags = var.tags } @@ -138,11 +140,11 @@ resource "aws_kms_alias" "ssmkey" { } resource "aws_cloudwatch_log_group" "session_manager_log_group" { + count = var.enable_log_to_cloudwatch ? 1 : 0 name = var.cloudwatch_log_group_name retention_in_days = var.cloudwatch_logs_retention kms_key_id = aws_kms_key.ssmkey.arn - - tags = var.tags + tags = var.tags } resource "aws_ssm_document" "session_manager_prefs" { @@ -151,30 +153,38 @@ resource "aws_ssm_document" "session_manager_prefs" { document_format = "JSON" tags = var.tags + # https://docs.aws.amazon.com/systems-manager/latest/userguide/getting-started-configure-preferences-cli.html content = <