Skip to content

Commit

Permalink
feat!: Allow IAM role to be passed to the module (#37)
Browse files Browse the repository at this point in the history
  • Loading branch information
phzietsman authored Feb 2, 2023
1 parent a3bba83 commit 216ec0b
Show file tree
Hide file tree
Showing 32 changed files with 98 additions and 827 deletions.
2 changes: 2 additions & 0 deletions .checkov-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ skip-check:
- CKV2_GHA_1
# Ensure AWS Lambda function is configured to validate code-signing
- CKV_AWS_272
# Function URLs are disabled
- CKV_AWS_258
2 changes: 2 additions & 0 deletions .github/workflows/pre-commit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ jobs:
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v2
with:
python-version: '3.8'
- uses: hashicorp/setup-terraform@v2
- uses: aws-actions/configure-aws-credentials@v1
with:
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -52,3 +52,5 @@ test.auto.tfvars*

# Lambda deployment build
.package
.external_modules
builds/
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,17 @@ See `examples` dropdown on Terraform Cloud, or [browse here](/examples/).
|------|-------------|------|---------|:--------:|
| <a name="input_account_name"></a> [account\_name](#input\_account\_name) | Name of your account to Identify your account in the notification message | `string` | n/a | yes |
| <a name="input_amber_threshold"></a> [amber\_threshold](#input\_amber\_threshold) | Percentage exceeded threshold to send an amber alert and notify the slack channel | `string` | `"20"` | no |
| <a name="input_cloudwatch_logs_retention_in_days"></a> [cloudwatch\_logs\_retention\_in\_days](#input\_cloudwatch\_logs\_retention\_in\_days) | Specifies the number of days you want to retain log events in the specified log group. Possible values are: 1, 3, 5, 7, 14, 30, 60, 90, 120, 150, 180, 365, 400, 545, 731, 1827, and 3653. | `number` | `14` | no |
| <a name="input_create_role"></a> [create\_role](#input\_create\_role) | Controls whether IAM role for Lambda Function should be created | `bool` | `true` | no |
| <a name="input_emails_for_notifications"></a> [emails\_for\_notifications](#input\_emails\_for\_notifications) | List of emails to receive cost notifier notifications | `list(string)` | `[]` | no |
| <a name="input_enable_remote_build"></a> [enable\_remote\_build](#input\_enable\_remote\_build) | Whether to enable remote building for the lambda function package ardhive, otherwise a local copy of the archive is used. | `bool` | `false` | no |
| <a name="input_kms_key_arn"></a> [kms\_key\_arn](#input\_kms\_key\_arn) | The alias, alias ARN, key ID, or key ARN of an AWS KMS key used to encrypt all resources. | `string` | `null` | no |
| <a name="input_lambda_description"></a> [lambda\_description](#input\_lambda\_description) | Lambda function description. | `string` | `"This function sends AWS cost notifications. Source: github.com/cloudandthings/terraform-aws-costnotifier"` | no |
| <a name="input_lambda_role"></a> [lambda\_role](#input\_lambda\_role) | IAM role ARN attached to the Lambda Function. This governs both who / what can invoke your Lambda Function, as well as what resources our Lambda Function has access to. See Lambda Permission Model for more details. | `string` | `""` | no |
| <a name="input_naming_prefix"></a> [naming\_prefix](#input\_naming\_prefix) | Naming prefix used to name all resources | `string` | n/a | yes |
| <a name="input_notification_schedule"></a> [notification\_schedule](#input\_notification\_schedule) | CRON expression to schedule notification | `string` | `"cron(0 20 ? * MON-SUN *)"` | no |
| <a name="input_permissions_boundary"></a> [permissions\_boundary](#input\_permissions\_boundary) | ARN of the policy that is used to set the permissions boundary for the role. | `string` | `null` | no |
| <a name="input_red_threshold"></a> [red\_threshold](#input\_red\_threshold) | Percentage exceeded threshold to send a red alert and notify the slack channel | `string` | `"50"` | no |
| <a name="input_runtime"></a> [runtime](#input\_runtime) | The python runtime for the lambda. If running this from Terraform Cloud this must be python3.8. | `string` | `"python3.8"` | no |
| <a name="input_security_group_ids"></a> [security\_group\_ids](#input\_security\_group\_ids) | List of VPC security group IDs associated with the Lambda function. | `list(string)` | `[]` | no |
| <a name="input_subnet_ids"></a> [subnet\_ids](#input\_subnet\_ids) | List of VPC subnet IDs associated with the Lambda function. | `list(string)` | `[]` | no |
| <a name="input_tags"></a> [tags](#input\_tags) | A mapping of tags to assign to the resources. | `map(string)` | `{}` | no |
Expand All @@ -40,7 +43,7 @@ See `examples` dropdown on Terraform Cloud, or [browse here](/examples/).

| Name | Source | Version |
|------|--------|---------|
| <a name="module_billing_notifier_lambda"></a> [billing\_notifier\_lambda](#module\_billing\_notifier\_lambda) | ./modules/external/nozaq/lambda-auto-package | n/a |
| <a name="module_billing_notifier_lambda"></a> [billing\_notifier\_lambda](#module\_billing\_notifier\_lambda) | terraform-aws-modules/lambda/aws | 4.9.0 |

----
### Outputs
Expand Down Expand Up @@ -72,7 +75,6 @@ See `examples` dropdown on Terraform Cloud, or [browse here](/examples/).
|------|------|
| [aws_cloudwatch_event_rule.billing_notifier_lambda_event_rule](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_rule) | resource |
| [aws_cloudwatch_event_target.billing_notifier_lambda_event_target](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/cloudwatch_event_target) | resource |
| [aws_iam_policy.cost_explorer_access_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
| [aws_lambda_permission.billing_notifier_lambda_permission](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
| [aws_sns_topic.cost_notifier](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic) | resource |
| [aws_sns_topic_subscription.cost_notifier](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/sns_topic_subscription) | resource |
Expand Down
4 changes: 2 additions & 2 deletions examples/slack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ module "example" {
naming_prefix = "costnotifier-example-slack"
account_name = "cloudandthings - master"
webhook_urls = ["https://api.slack.com/messaging/webhooks"] # slack webhook
webhook_urls = ["https://hooks.slack.com"] # slack webhook
webhook_type = "slack"
notification_schedule = "cron(0 7 ? * MON-FRI *)"
Expand All @@ -26,7 +26,7 @@ module "example" {
| Name | Description | Type | Default | Required |
|------|-------------|------|---------|:--------:|
| <a name="input_aws_profile"></a> [aws\_profile](#input\_aws\_profile) | AWS profile | `string` | `null` | no |
| <a name="input_aws_region"></a> [aws\_region](#input\_aws\_region) | AWS region | `string` | `null` | no |
| <a name="input_aws_region"></a> [aws\_region](#input\_aws\_region) | AWS region | `string` | `"af-south-1"` | no |

----
### Modules
Expand Down
2 changes: 1 addition & 1 deletion examples/slack/main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ module "example" {
naming_prefix = "costnotifier-example-slack"
account_name = "cloudandthings - master"

webhook_urls = ["https://api.slack.com/messaging/webhooks"] # slack webhook
webhook_urls = ["https://hooks.slack.com"] # slack webhook
webhook_type = "slack"

notification_schedule = "cron(0 7 ? * MON-FRI *)"
Expand Down
2 changes: 1 addition & 1 deletion examples/slack/variables.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@ variable "aws_profile" {
variable "aws_region" {
description = "AWS region"
type = string
default = null
default = "af-south-1"
}
46 changes: 21 additions & 25 deletions iam.tf
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
resource "aws_iam_policy" "cost_explorer_access_policy" {
path = "/"

policy = jsonencode({
Version = "2012-10-17"
Statement = concat([
{
Effect = "Allow"
Action = [
"ce:GetCostAndUsage"
],
Resource = "*"
}],
[for aws_sns_topic in aws_sns_topic.cost_notifier :
{
Effect = "Allow"
Action = [
"sns:Publish"
]
Resource = aws_sns_topic.arn
}]
)
})

tags = var.tags
locals {
policy_statements = merge({
ce_permissions = {
effect = "Allow"
actions = [
"ce:GetCostAndUsage",
"iam:ListAccountAliases"
]
resources = ["*"]
}
},
local.no_of_emails != 0 ? {
sns_permissions = {
effect = "Allow"
actions = [
"sns:Publish"
]
resources = [for aws_sns_topic in aws_sns_topic.cost_notifier : aws_sns_topic.arn]
}
} : {}
)
}
106 changes: 37 additions & 69 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ resource "aws_cloudwatch_event_rule" "billing_notifier_lambda_event_rule" {
resource "aws_cloudwatch_event_target" "billing_notifier_lambda_event_target" {
rule = aws_cloudwatch_event_rule.billing_notifier_lambda_event_rule.name
target_id = "check-non-compliant-report-event-rule"
arn = module.billing_notifier_lambda.lambda_function.arn
arn = module.billing_notifier_lambda.lambda_function_arn
depends_on = [
module.billing_notifier_lambda
]
Expand All @@ -14,7 +14,7 @@ resource "aws_cloudwatch_event_target" "billing_notifier_lambda_event_target" {
data "aws_caller_identity" "current" {}

resource "aws_lambda_permission" "billing_notifier_lambda_permission" {
function_name = module.billing_notifier_lambda.lambda_function.function_name
function_name = module.billing_notifier_lambda.lambda_function_name

statement_id = "AllowExecutionFromCloudWatch"
action = "lambda:InvokeFunction"
Expand All @@ -28,86 +28,54 @@ resource "aws_lambda_permission" "billing_notifier_lambda_permission" {
]
}

locals {
vpc_config = (
length(var.security_group_ids) + length(var.subnet_ids) == 0
? null
: {
security_group_ids = var.security_group_ids
subnet_ids = var.subnet_ids
}
)

}

#tfsec:ignore:aws-lambda-enable-tracing
module "billing_notifier_lambda" {
source = "terraform-aws-modules/lambda/aws"
version = "4.9.0"

# Temporary until this is merged:
# https://github.com/nozaq/terraform-aws-lambda-auto-package/pull/30
source = "./modules/external/nozaq/lambda-auto-package"
# source = "nozaq/lambda-auto-package/aws"
# version = "0.4.0"

####################################
# General
function_name = var.naming_prefix
description = var.lambda_description

handler = "handler.report_cost"
runtime = "python3.7"

runtime = var.runtime
timeout = 300
tags = var.tags

####################################
# Build

output_path = "${path.module}/billing-notifier/package.zip"

source_dir = var.enable_remote_build ? "${path.module}/billing-notifier/" : null

build_command = var.enable_remote_build ? "${path.module}/billing-notifier/pip.sh ${path.module}/billing-notifier" : ""

build_triggers = {
requirements = base64sha256(file("${path.module}/billing-notifier/requirements.txt"))
execute = base64sha256(file("${path.module}/billing-notifier/pip.sh"))
}

####################################
# KMS
source_path = [
{
path = "${path.module}/billing-notifier/",
pip_requirements = "${path.module}/billing-notifier/requirements.txt"
}
]

# The ARN of the KMS Key to use when encrypting log data.
kms_key_id = var.kms_key_arn
# The ARN of the KMS Key to use when encrypting environment variables.
# Ignored unless `environment` is specified.
lambda_kms_key_arn = var.kms_key_arn
cloudwatch_logs_retention_in_days = var.cloudwatch_logs_retention_in_days
cloudwatch_logs_kms_key_id = var.kms_key_arn
kms_key_arn = var.kms_key_arn

####################################
# IAM
iam_role_name_prefix = var.naming_prefix
create_role = var.create_role
attach_policy_statements = var.create_role

lambda_role = var.lambda_role
role_permissions_boundary = var.permissions_boundary
role_name = var.naming_prefix
role_description = "Role used for the AWS Cost Notifier"
policy_statements = local.policy_statements

# Networking
vpc_security_group_ids = var.security_group_ids
vpc_subnet_ids = var.subnet_ids

environment_variables = {
WEBHOOK_URLS = jsonencode(var.webhook_urls)
WEBHOOK_TYPE = lower(var.webhook_type)
AWS_ACCOUNT_NAME = var.account_name
SNS_ARN = local.no_of_emails != 0 ? aws_sns_topic.cost_notifier[0].arn : "DISABLED"
AMBER_THRESHOLD = var.amber_threshold
RED_THRESHOLD = var.red_threshold
}

policy_arns = [
"arn:aws:iam::aws:policy/service-role/AWSCostAndUsageReportAutomationPolicy",
aws_iam_policy.cost_explorer_access_policy.arn
]
tags = var.tags

permissions_boundary = var.permissions_boundary

####################################
# Environment
environment = {
variables = {
WEBHOOK_URLS = jsonencode(var.webhook_urls)
WEBHOOK_TYPE = lower(var.webhook_type)
AWS_ACCOUNT_NAME = var.account_name
SNS_ARN = local.no_of_emails != 0 ? aws_sns_topic.cost_notifier[0].arn : "DISABLED"
AMBER_THRESHOLD = var.amber_threshold
RED_THRESHOLD = var.red_threshold
}
}
create_lambda_function_url = false

####################################
# Network
vpc_config = local.vpc_config
}
33 changes: 0 additions & 33 deletions modules/external/nozaq/lambda-auto-package/CHANGELOG.md

This file was deleted.

21 changes: 0 additions & 21 deletions modules/external/nozaq/lambda-auto-package/LICENSE

This file was deleted.

Loading

0 comments on commit 216ec0b

Please sign in to comment.