diff --git a/.github/workflows/checkov.yml b/.github/workflows/checkov.yml index 67515dc..abe9981 100644 --- a/.github/workflows/checkov.yml +++ b/.github/workflows/checkov.yml @@ -8,10 +8,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.9 - name: Scan with Checkov id: checkov uses: bridgecrewio/checkov-action@master diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6f75891..4b9b2fe 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,10 +20,10 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - - name: Set up Python 3.8 + - name: Set up Python 3.9 uses: actions/setup-python@v1 with: - python-version: 3.8 + python-version: 3.9 - name: Scan with Checkov id: checkov uses: bridgecrewio/checkov-action@master diff --git a/README.md b/README.md index 76d3723..76994c9 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,7 @@ This tool generates a new IAM access key pair every X number of days and informs ### Setup: - Use the [terraform module](terraform) included in this repo to create all the AWS resources required to automate IAM key rotation -- Add following tags to the IAM user whose access keys needs to be automated. All the tags mentioned are case-insensitive: +- Add the following tags to the IAM user whose access key pair generation needs to be automated. All the tags mentioned are **case-insensitive**: - Required: - `IKR:EMAIL`: Email address of IAM user where alerts related to access keys will be sent - Optional: diff --git a/terraform/README.md b/terraform/README.md index 8d4a95d..4c1865d 100644 --- a/terraform/README.md +++ b/terraform/README.md @@ -15,7 +15,7 @@ This terraform module will deploy the following services: | Name | Version | |------|---------| -| aws | >= 3.42.0 | +| aws | >= 4.0.0 | ## Inputs @@ -27,15 +27,15 @@ This terraform module will deploy the following services: | secret_key | AWS secret key to use as authentication method | `string` | `null` | no | | session_token | AWS session token to use as authentication method | `string` | `null` | no | | table_name | Name of dynamodb table to store access keys to be deleted | `string` | `"iam-key-rotator"` | no | -| enable_sse | Whether to enable server-side encryption | `bool` | `true` | no | -| kms_key_arn | ARN of customer owned CMK to use instead of AWS owned key | `string` | `null` | no | +| enable_sse | Whether to enable server-side encryption for dynamodb table | `bool` | `true` | no | +| kms_key_arn | ARN of customer owned CMK to use instead of AWS owned key for dynamodb table | `string` | `null` | no | | enable_pitr | Enable point-in time recovery for dynamodb table | `bool` | `false` | no | | key_creator_role_name | Name for IAM role to assocaite with key creator lambda function | `string` | `"iam-key-creator"` | no | | key_creator_function_name | Name for lambda function responsible for creating new access key pair | `string` | `"iam-key-creator"` | no | | key_destructor_role_name | Name for IAM role to assocaite with key destructor lambda function | `string` | `"iam-key-destructor"` | no | | key_destructor_function_name | Name for lambda function responsible for deleting existing access key pair | `string` | `"iam-key-destructor"` | no | | cron_expression | [CRON expression](https://docs.aws.amazon.com/eventbridge/latest/userguide/eb-schedule-expressions.html) to determine how frequently `key creator` function will be invoked to check if new key pair needs to be generated for an IAM user | `string` | `"0 12 * * ? *"` | no | -| lambda_runtime | Lambda runtime to use for code execution for both creator and destructor function | `string` | `"python3.8"` | no | +| lambda_runtime | Lambda runtime to use for code execution for both creator and destructor function | `string` | `"python3.9"` | no | | function_memory_size | Amount of memory to allocate to both creator and destructor function | `number` | `128` | no | | function_timeout | Timeout to set for both creator and destructor function | `number` | `10` | no | | reserved_concurrent_executions | Amount of reserved concurrent executions for this lambda function. A value of `0` disables lambda from being triggered and `-1` removes any concurrency limitations | `number` | `-1` | no | @@ -52,6 +52,8 @@ This terraform module will deploy the following services: | smtp_password | Password to use with `mail_from` address for SMTP authentication. **Note:** Required if mail client is set to smtp | `string` | `null` | no | | mailgun_api_url | Mailgun API url for sending email. **Note:** Required if mail client is set to mailgun | `string` | `null` | no | | mailgun_api_key | API key for authenticating requests to Mailgun API. **Note:** Required if mail client is set to mailgun | `string` | `null` | no | +| cw_log_group_retention | Number of days to store the logs in a log group. Valid values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653, and 0. To never expire the logs provide 0 | `number` | `90` | no | +| cw_logs_kms_key_arn | ARN of KMS key to use for encrypting CloudWatch logs at rest | `string` | `null` | no | ## Outputs diff --git a/terraform/main.tf b/terraform/main.tf index 77b3194..69d888d 100644 --- a/terraform/main.tf +++ b/terraform/main.tf @@ -64,7 +64,7 @@ resource "aws_lambda_layer_version" "pytz" { description = "https://pypi.org/project/pytz/" layer_name = "pytz" - compatible_runtimes = ["python3.6", "python3.7", "python3.8"] + compatible_runtimes = ["python3.6", "python3.7", "python3.8", "python3.9"] } resource "aws_lambda_layer_version" "requests" { @@ -73,7 +73,7 @@ resource "aws_lambda_layer_version" "requests" { description = "https://pypi.org/project/requests/" layer_name = "requests" - compatible_runtimes = ["python3.6", "python3.7", "python3.8"] + compatible_runtimes = ["python3.6", "python3.7", "python3.8", "python3.9"] } # ====== iam-key-creator ====== @@ -171,6 +171,13 @@ resource "aws_ssm_parameter" "smtp_password" { tags = var.tags } +resource "aws_cloudwatch_log_group" "iam_key_creator" { + name = "/aws/lambda/${var.key_creator_function_name}" + retention_in_days = var.cw_log_group_retention + kms_key_id = var.cw_logs_kms_key_arn + tags = var.tags +} + resource "aws_lambda_function" "iam_key_creator" { # checkov:skip=CKV_AWS_50: Enabling X-Ray tracing depends on user # checkov:skip=CKV_AWS_115: Setting reserved concurrent execution depends on user @@ -290,6 +297,13 @@ resource "aws_lambda_event_source_mapping" "iam_key_destructor" { starting_position = "LATEST" } +resource "aws_cloudwatch_log_group" "iam_key_destructor" { + name = "/aws/lambda/${var.key_destructor_function_name}" + retention_in_days = var.cw_log_group_retention + kms_key_id = var.cw_logs_kms_key_arn + tags = var.tags +} + resource "aws_lambda_function" "iam_key_destructor" { # checkov:skip=CKV_AWS_50: Enabling X-Ray tracing depends on user # checkov:skip=CKV_AWS_115: Setting reserved concurrent execution depends on user diff --git a/terraform/output.tf b/terraform/output.tf index 42549c3..e349f4a 100644 --- a/terraform/output.tf +++ b/terraform/output.tf @@ -19,11 +19,11 @@ output "cron_expression" { } output "mailgun_ssm_parameter_arn" { - value = var.mail_client == "mailgun" ? join(",", aws_ssm_parameter.mailgun.arn) : null + value = var.mail_client == "mailgun" ? join(",", aws_ssm_parameter.mailgun.*.arn) : null description = "ARN of SSM parameter that stores mailgun API key. Available only if mail client is set to Mailgun" } output "smtp_ssm_parameter_arn" { - value = var.mail_client == "smtp" ? join(",", aws_ssm_parameter.smtp_password.arn) : null + value = var.mail_client == "smtp" ? join(",", aws_ssm_parameter.smtp_password.*.arn) : null description = "ARN of SSM parameter that stores SMTP password. Available only if mail client is set to SMTP" } diff --git a/terraform/provider.tf b/terraform/provider.tf index 9e7509b..89aec3a 100644 --- a/terraform/provider.tf +++ b/terraform/provider.tf @@ -2,7 +2,7 @@ terraform { required_providers { aws = { source = "hashicorp/aws" - version = ">= 3.42.0" + version = ">= 4.0.0" } } } diff --git a/terraform/vars.tf b/terraform/vars.tf index 41083ed..327490d 100644 --- a/terraform/vars.tf +++ b/terraform/vars.tf @@ -37,13 +37,13 @@ variable "table_name" { variable "enable_sse" { type = bool default = true - description = "Whether to enable server-side encryption" + description = "Whether to enable server-side encryption for dynamodb table" } variable "kms_key_arn" { type = string default = null - description = "ARN of customer owned CMK to use instead of AWS owned key" + description = "ARN of customer owned CMK to use instead of AWS owned key for dynamodb table" } variable "enable_pitr" { @@ -84,7 +84,7 @@ variable "cron_expression" { variable "lambda_runtime" { type = string - default = "python3.8" + default = "python3.9" description = "Lambda runtime to use for code execution for both creator and destructor function" } @@ -182,3 +182,15 @@ variable "mailgun_api_key" { default = null description = "API key for authenticating requests to Mailgun API. **Note:** Required if mail client is set to mailgun" } + +variable "cw_log_group_retention" { + type = number + default = 90 + description = "Number of days to store the logs in a log group. Valid values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, 3653, and 0. To never expire the logs provide 0" +} + +variable "cw_logs_kms_key_arn" { + type = string + default = null + description = "ARN of KMS key to use for encrypting CloudWatch logs at rest" +}