Skip to content

Commit e847cac

Browse files
feat: migrate aws billing lambdas to use external packaging (#158)
* feat: migrate lambda cur_per_resource_process to use external packaging * feat: migrate lambda cur_per_resource to use external packaging * feat: migrate lambda cur_per_service to use external packaging
1 parent baf41ec commit e847cac

File tree

6 files changed

+184
-110
lines changed

6 files changed

+184
-110
lines changed

modules/integrations/splunk_aws_billing/README.md

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,14 @@
1515
| Name | Version |
1616
|------|---------|
1717
| <a name="provider_aws"></a> [aws](#provider\_aws) | 6.16.0 |
18-
| <a name="provider_null"></a> [null](#provider\_null) | 3.2.4 |
1918

2019
## Modules
2120

22-
No modules.
21+
| Name | Source | Version |
22+
|------|--------|---------|
23+
| <a name="module_cur_per_resource"></a> [cur\_per\_resource](#module\_cur\_per\_resource) | terraform-aws-modules/lambda/aws | 8.1.0 |
24+
| <a name="module_cur_per_resource_process"></a> [cur\_per\_resource\_process](#module\_cur\_per\_resource\_process) | terraform-aws-modules/lambda/aws | 8.1.0 |
25+
| <a name="module_cur_per_service"></a> [cur\_per\_service](#module\_cur\_per\_service) | terraform-aws-modules/lambda/aws | 8.1.0 |
2326

2427
## Resources
2528

@@ -33,9 +36,6 @@ No modules.
3336
| [aws_iam_policy.lambda_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy) | resource |
3437
| [aws_iam_role.lambda_exec_role](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role) | resource |
3538
| [aws_iam_role_policy_attachment.attach_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role_policy_attachment) | resource |
36-
| [aws_lambda_function.cur_per_resource](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |
37-
| [aws_lambda_function.cur_per_resource_process](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |
38-
| [aws_lambda_function.cur_per_service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_function) | resource |
3939
| [aws_lambda_permission.cur_per_resource](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
4040
| [aws_lambda_permission.cur_per_resource_process](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
4141
| [aws_lambda_permission.cur_per_service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission) | resource |
@@ -47,14 +47,11 @@ No modules.
4747
| [aws_s3_bucket_public_access_block.aws_billing_report](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_public_access_block) | resource |
4848
| [aws_s3_bucket_server_side_encryption_configuration.aws_billing_report_settings](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_server_side_encryption_configuration) | resource |
4949
| [aws_s3_bucket_versioning.aws_billing_report](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_bucket_versioning) | resource |
50-
| [aws_s3_object.cur_per_resource](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource |
51-
| [aws_s3_object.cur_per_resource_process](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource |
52-
| [aws_s3_object.cur_per_service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/s3_object) | resource |
53-
| [null_resource.install_dependencies_per_resource](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
54-
| [null_resource.install_dependencies_per_resource_process](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
55-
| [null_resource.install_dependencies_per_service](https://registry.terraform.io/providers/hashicorp/null/latest/docs/resources/resource) | resource |
5650
| [aws_caller_identity.current](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/caller_identity) | data source |
5751
| [aws_iam_policy_document.cur_bucket_policy](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
52+
| [aws_iam_policy_document.cur_per_resource](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
53+
| [aws_iam_policy_document.cur_per_resource_process](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
54+
| [aws_iam_policy_document.cur_per_service](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
5855
| [aws_iam_policy_document.lambda_policy_document](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/iam_policy_document) | data source |
5956
| [aws_secretsmanager_secret.secrets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/secretsmanager_secret) | data source |
6057
| [aws_secretsmanager_secret_version.secrets](https://registry.terraform.io/providers/hashicorp/aws/latest/docs/data-sources/secretsmanager_secret_version) | data source |

modules/integrations/splunk_aws_billing/billing_per_resource.tf

Lines changed: 59 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,84 @@
1-
resource "null_resource" "install_dependencies_per_resource" {
2-
provisioner "local-exec" {
3-
command = "bash ${path.module}/scripts/requirements.sh /tmp/aws_billing/per_resource/${var.aws_profile} handler_per_resource"
4-
}
5-
6-
triggers = {
7-
lambda_source_hash = filesha256("${path.module}/lambda/handler_per_resource.py")
8-
common_source_hash = filesha256("${path.module}/lambda/common.py")
9-
requirements_hash = filesha256("${path.module}/lambda/requirements.txt")
10-
requirements_handler_hash = filesha256("${path.module}/scripts/requirements.sh")
11-
}
1+
locals {
2+
cur_per_resource_lambda_name = "forge-aws-billing-per-resource"
123
}
134

14-
resource "aws_s3_object" "cur_per_resource" {
15-
bucket = aws_s3_bucket.aws_billing_report.id
16-
key = "lambda/aws_billing_lambda_function_per_resource-${null_resource.install_dependencies_per_resource.id}.zip"
17-
source = "/tmp/aws_billing/per_resource/${var.aws_profile}/lambda_package/lambda.zip"
5+
module "cur_per_resource" {
6+
source = "terraform-aws-modules/lambda/aws"
7+
version = "8.1.0"
188

19-
depends_on = [null_resource.install_dependencies_per_resource]
20-
}
9+
function_name = local.cur_per_resource_lambda_name
10+
description = "Processes AWS Billing CUR reports per resource and sends data to Splunk"
2111

22-
resource "aws_lambda_function" "cur_per_resource" {
23-
function_name = "forge-aws-billing-per-resource"
24-
s3_bucket = aws_s3_object.cur_per_resource.bucket
25-
s3_key = aws_s3_object.cur_per_resource.key
2612
handler = "handler_per_resource.lambda_handler"
27-
architectures = ["x86_64"]
2813
runtime = "python3.12"
29-
role = aws_iam_role.lambda_exec_role.arn
30-
timeout = 900
14+
architectures = ["x86_64"]
3115
memory_size = 10240
16+
timeout = 900
17+
publish = true
18+
19+
source_path = [{
20+
path = "${path.module}/lambda"
21+
pip_requirements = "${path.module}/lambda/requirements.txt"
22+
}]
23+
24+
logging_log_group = aws_cloudwatch_log_group.cur_per_resource.name
25+
use_existing_cloudwatch_log_group = true
26+
27+
trigger_on_package_timestamp = false
28+
29+
environment_variables = {
30+
SPLUNK_HEC_URL = var.splunk_aws_billing_config.splunk_hec_url
31+
SPLUNK_HEC_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_cloud_hec_token_aws_billing"].secret_string
32+
SPLUNK_INDEX = var.splunk_aws_billing_config.splunk_index
33+
SPLUNK_METRICS_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_o11y_ingest_token_aws_billing"].secret_string
34+
SPLUNK_METRICS_URL = var.splunk_aws_billing_config.splunk_metrics_url
35+
}
36+
37+
attach_policy_jsons = true
38+
policy_jsons = [
39+
data.aws_iam_policy_document.cur_per_resource.json,
40+
data.aws_iam_policy_document.lambda_policy_document.json,
41+
]
42+
number_of_policy_jsons = 2
43+
44+
tags = local.all_security_tags
45+
46+
store_on_s3 = true
47+
s3_object_tags_only = true
48+
s3_object_tags = var.default_tags
49+
s3_bucket = aws_s3_bucket.aws_billing_report.id
50+
s3_prefix = "lambda/aws_billing_lambda_function_per_resource_process"
3251
}
3352

3453
resource "aws_lambda_permission" "cur_per_resource" {
3554
statement_id = "AllowS3Invoke"
3655
action = "lambda:InvokeFunction"
37-
function_name = aws_lambda_function.cur_per_resource.function_name
56+
function_name = local.cur_per_resource_lambda_name
3857
principal = "s3.amazonaws.com"
3958
source_arn = "arn:aws:s3:::${aws_s3_bucket.aws_billing_report.id}"
4059
}
4160

4261
resource "aws_cloudwatch_log_group" "cur_per_resource" {
43-
name = "/aws/lambda/${aws_lambda_function.cur_per_resource.function_name}"
62+
name = "/aws/lambda/${local.cur_per_resource_lambda_name}"
4463
retention_in_days = 3
4564
tags = local.all_security_tags
4665
tags_all = local.all_security_tags
4766
}
4867

68+
data "aws_iam_policy_document" "cur_per_resource" {
69+
statement {
70+
actions = [
71+
"logs:CreateLogStream",
72+
"logs:PutLogEvents"
73+
]
74+
effect = "Allow"
75+
76+
resources = [
77+
"arn:aws:logs:*:${data.aws_caller_identity.current.account_id}:log-group:${aws_cloudwatch_log_group.cur_per_resource.name}*:*"
78+
]
79+
}
80+
}
81+
4982
resource "aws_bcmdataexports_export" "cur_per_resource" {
5083
export {
5184
name = "aws-billing-report-per-resource"
Lines changed: 57 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,80 @@
1-
resource "null_resource" "install_dependencies_per_resource_process" {
2-
provisioner "local-exec" {
3-
command = "bash ${path.module}/scripts/requirements.sh /tmp/aws_billing/per_resource_process/${var.aws_profile} handler_per_resource_process"
4-
}
5-
6-
triggers = {
7-
lambda_source_hash = filesha256("${path.module}/lambda/handler_per_resource_process.py")
8-
common_source_hash = filesha256("${path.module}/lambda/common.py")
9-
requirements_hash = filesha256("${path.module}/lambda/requirements.txt")
10-
requirements_handler_hash = filesha256("${path.module}/scripts/requirements.sh")
11-
}
1+
locals {
2+
cur_per_resource_process_lambda_name = "forge-aws-billing-per-resource-process"
123
}
134

14-
resource "aws_s3_object" "cur_per_resource_process" {
15-
bucket = aws_s3_bucket.aws_billing_report.id
16-
key = "lambda/aws_billing_lambda_function_per_resource_process-${null_resource.install_dependencies_per_resource_process.id}.zip"
17-
source = "/tmp/aws_billing/per_resource_process/${var.aws_profile}/lambda_package/lambda.zip"
5+
module "cur_per_resource_process" {
6+
source = "terraform-aws-modules/lambda/aws"
7+
version = "8.1.0"
188

19-
depends_on = [null_resource.install_dependencies_per_resource_process]
20-
}
9+
function_name = local.cur_per_resource_process_lambda_name
10+
description = "Processes AWS billing data and sends to Splunk"
2111

22-
resource "aws_lambda_function" "cur_per_resource_process" {
23-
function_name = "forge-aws-billing-per-resource-process"
24-
s3_bucket = aws_s3_object.cur_per_resource_process.bucket
25-
s3_key = aws_s3_object.cur_per_resource_process.key
2612
handler = "handler_per_resource_process.lambda_handler"
27-
architectures = ["x86_64"]
2813
runtime = "python3.12"
29-
role = aws_iam_role.lambda_exec_role.arn
30-
timeout = 900
14+
architectures = ["x86_64"]
3115
memory_size = 10240
16+
timeout = 900
17+
publish = true
18+
19+
source_path = [{
20+
path = "${path.module}/lambda"
21+
pip_requirements = "${path.module}/lambda/requirements.txt"
22+
}]
3223

33-
environment {
34-
variables = {
35-
SPLUNK_HEC_URL = var.splunk_aws_billing_config.splunk_hec_url
36-
SPLUNK_HEC_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_cloud_hec_token_aws_billing"].secret_string
37-
SPLUNK_INDEX = var.splunk_aws_billing_config.splunk_index
38-
SPLUNK_METRICS_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_o11y_ingest_token_aws_billing"].secret_string
39-
SPLUNK_METRICS_URL = var.splunk_aws_billing_config.splunk_metrics_url
40-
}
24+
logging_log_group = aws_cloudwatch_log_group.cur_per_resource_process.name
25+
use_existing_cloudwatch_log_group = true
26+
27+
trigger_on_package_timestamp = false
28+
29+
environment_variables = {
30+
SPLUNK_HEC_URL = var.splunk_aws_billing_config.splunk_hec_url
31+
SPLUNK_HEC_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_cloud_hec_token_aws_billing"].secret_string
32+
SPLUNK_INDEX = var.splunk_aws_billing_config.splunk_index
33+
SPLUNK_METRICS_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_o11y_ingest_token_aws_billing"].secret_string
34+
SPLUNK_METRICS_URL = var.splunk_aws_billing_config.splunk_metrics_url
4135
}
36+
37+
attach_policy_jsons = true
38+
policy_jsons = [
39+
data.aws_iam_policy_document.cur_per_resource_process.json,
40+
data.aws_iam_policy_document.lambda_policy_document.json,
41+
]
42+
number_of_policy_jsons = 2
43+
44+
tags = local.all_security_tags
45+
46+
store_on_s3 = true
47+
s3_object_tags_only = true
48+
s3_object_tags = var.default_tags
49+
s3_bucket = aws_s3_bucket.aws_billing_report.id
50+
s3_prefix = "lambda/aws_billing_lambda_function_per_resource_process"
4251
}
4352

4453
resource "aws_lambda_permission" "cur_per_resource_process" {
4554
statement_id = "AllowS3Invoke"
4655
action = "lambda:InvokeFunction"
47-
function_name = aws_lambda_function.cur_per_resource_process.function_name
56+
function_name = local.cur_per_resource_process_lambda_name
4857
principal = "s3.amazonaws.com"
4958
source_arn = "arn:aws:s3:::${aws_s3_bucket.aws_billing_report.id}"
5059
}
5160

5261
resource "aws_cloudwatch_log_group" "cur_per_resource_process" {
53-
name = "/aws/lambda/${aws_lambda_function.cur_per_resource_process.function_name}"
62+
name = "/aws/lambda/${local.cur_per_resource_process_lambda_name}"
5463
retention_in_days = 3
5564
tags = local.all_security_tags
5665
tags_all = local.all_security_tags
5766
}
67+
68+
data "aws_iam_policy_document" "cur_per_resource_process" {
69+
statement {
70+
actions = [
71+
"logs:CreateLogStream",
72+
"logs:PutLogEvents"
73+
]
74+
effect = "Allow"
75+
76+
resources = [
77+
"arn:aws:logs:*:${data.aws_caller_identity.current.account_id}:log-group:${aws_cloudwatch_log_group.cur_per_resource_process.name}*:*"
78+
]
79+
}
80+
}

modules/integrations/splunk_aws_billing/billing_per_service.tf

Lines changed: 57 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,62 +1,84 @@
1-
resource "null_resource" "install_dependencies_per_service" {
2-
3-
provisioner "local-exec" {
4-
command = "bash ${path.module}/scripts/requirements.sh /tmp/aws_billing/per_service/${var.aws_profile} handler_per_service"
5-
}
6-
7-
triggers = {
8-
lambda_source_hash = filesha256("${path.module}/lambda/handler_per_service.py")
9-
common_source_hash = filesha256("${path.module}/lambda/common.py")
10-
requirements_hash = filesha256("${path.module}/lambda/requirements.txt")
11-
requirements_handler_hash = filesha256("${path.module}/scripts/requirements.sh")
12-
}
1+
locals {
2+
cur_per_service_lambda_name = "forge-aws-billing-per-service"
133
}
144

15-
resource "aws_s3_object" "cur_per_service" {
16-
bucket = aws_s3_bucket.aws_billing_report.id
17-
key = "lambda/aws_billing_lambda_function_per_service-${null_resource.install_dependencies_per_service.id}.zip"
18-
source = "/tmp/aws_billing/per_service/${var.aws_profile}/lambda_package/lambda.zip"
5+
module "cur_per_service" {
6+
source = "terraform-aws-modules/lambda/aws"
7+
version = "8.1.0"
198

20-
depends_on = [null_resource.install_dependencies_per_service]
21-
}
9+
function_name = local.cur_per_service_lambda_name
10+
description = "Processes AWS Billing CUR reports per service and sends data to Splunk"
2211

23-
resource "aws_lambda_function" "cur_per_service" {
24-
function_name = "forge-aws-billing-per-service"
25-
s3_bucket = aws_s3_object.cur_per_service.bucket
26-
s3_key = aws_s3_object.cur_per_service.key
2712
handler = "handler_per_service.lambda_handler"
28-
architectures = ["x86_64"]
2913
runtime = "python3.12"
30-
role = aws_iam_role.lambda_exec_role.arn
31-
timeout = 900
14+
architectures = ["x86_64"]
3215
memory_size = 10240
16+
timeout = 900
17+
publish = true
3318

34-
environment {
35-
variables = {
36-
SPLUNK_HEC_URL = var.splunk_aws_billing_config.splunk_hec_url
37-
SPLUNK_HEC_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_cloud_hec_token_aws_billing"].secret_string
38-
SPLUNK_INDEX = var.splunk_aws_billing_config.splunk_index
39-
SPLUNK_METRICS_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_o11y_ingest_token_aws_billing"].secret_string
40-
SPLUNK_METRICS_URL = var.splunk_aws_billing_config.splunk_metrics_url
41-
}
19+
source_path = [{
20+
path = "${path.module}/lambda"
21+
pip_requirements = "${path.module}/lambda/requirements.txt"
22+
}]
23+
24+
logging_log_group = aws_cloudwatch_log_group.cur_per_service.name
25+
use_existing_cloudwatch_log_group = true
26+
27+
trigger_on_package_timestamp = false
28+
29+
environment_variables = {
30+
SPLUNK_HEC_URL = var.splunk_aws_billing_config.splunk_hec_url
31+
SPLUNK_HEC_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_cloud_hec_token_aws_billing"].secret_string
32+
SPLUNK_INDEX = var.splunk_aws_billing_config.splunk_index
33+
SPLUNK_METRICS_TOKEN = data.aws_secretsmanager_secret_version.secrets["splunk_o11y_ingest_token_aws_billing"].secret_string
34+
SPLUNK_METRICS_URL = var.splunk_aws_billing_config.splunk_metrics_url
4235
}
36+
37+
attach_policy_jsons = true
38+
policy_jsons = [
39+
data.aws_iam_policy_document.cur_per_service.json,
40+
data.aws_iam_policy_document.lambda_policy_document.json,
41+
]
42+
number_of_policy_jsons = 2
43+
44+
tags = local.all_security_tags
45+
46+
store_on_s3 = true
47+
s3_object_tags_only = true
48+
s3_object_tags = var.default_tags
49+
s3_bucket = aws_s3_bucket.aws_billing_report.id
50+
s3_prefix = "lambda/aws_billing_lambda_function_per_resource_process"
4351
}
4452

4553
resource "aws_lambda_permission" "cur_per_service" {
4654
statement_id = "AllowS3Invoke"
4755
action = "lambda:InvokeFunction"
48-
function_name = aws_lambda_function.cur_per_service.function_name
56+
function_name = local.cur_per_service_lambda_name
4957
principal = "s3.amazonaws.com"
5058
source_arn = "arn:aws:s3:::${aws_s3_bucket.aws_billing_report.id}"
5159
}
5260

5361
resource "aws_cloudwatch_log_group" "cur_per_service" {
54-
name = "/aws/lambda/${aws_lambda_function.cur_per_service.function_name}"
62+
name = "/aws/lambda/${local.cur_per_service_lambda_name}"
5563
retention_in_days = 3
5664
tags = local.all_security_tags
5765
tags_all = local.all_security_tags
5866
}
5967

68+
data "aws_iam_policy_document" "cur_per_service" {
69+
statement {
70+
actions = [
71+
"logs:CreateLogStream",
72+
"logs:PutLogEvents"
73+
]
74+
effect = "Allow"
75+
76+
resources = [
77+
"arn:aws:logs:*:${data.aws_caller_identity.current.account_id}:log-group:${aws_cloudwatch_log_group.cur_per_service.name}*:*"
78+
]
79+
}
80+
}
81+
6082
resource "aws_bcmdataexports_export" "cur_per_service" {
6183
export {
6284
name = "aws-billing-report-per-service"
Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,2 @@
1-
boto3
21
pandas[pyarrow]
32
requests

0 commit comments

Comments
 (0)