Skip to content

Commit

Permalink
LZA-163: S3 and CUR modules (#26)
Browse files Browse the repository at this point in the history
* LZA-163: S3 and CUR modules

* LZA-163: Move cur infra into one module and create IAM roe

* LZA-163: Update S3 settings, create inline policy and S3 lifecycle rule

* LZA-163: Create S3 Replication Rule

* LZA-163: Create bucket policy

* LZA-163: Terraform fmt and update aws region condition validation

* LZA-163: add aws_s3_bucket_public_access_block

* LZA-163: add aws_s3_bucket_public_access_block

* LZA-163: Change bucket name references to use tf resource value

* LZA-163: Change bucket name references to use tf resource value and add arn for iam role in replication rule

* Configure .trivyignore for CUDOS setup (#28)

* Create .trivyignore file and add s3 kms

* Change to use trivyignores instead of ignorefile

* Change to use avd references

* move .trivyignore file to module root

* append avd to ignore checks

* Capitalise misconf value

* LZA-163: Updates from testing

* Delete main.tf

* Update .trivyignore

* Update README.md

* LZA-163: Updates from testing

* LZA-163: Updates from testing

* LZA-163: Updates from testing

* LZA-163: Updates from testing

---------

Co-authored-by: Liam MacPherson <[email protected]>
  • Loading branch information
danielpalmeribm and LiamMacP authored Mar 21, 2024
1 parent ede9173 commit 350fba3
Show file tree
Hide file tree
Showing 7 changed files with 469 additions and 0 deletions.
1 change: 1 addition & 0 deletions .github/workflows/pull-request-sast.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,5 @@ jobs:
uses: aquasecurity/[email protected]
with:
scan-type: 'config'
trivyignores: ".trivyignore"
exit-code: '1'
5 changes: 5 additions & 0 deletions .trivyignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#Ignore requirement for S3 logging bucket as per CUDOS setup instructions
AVD-AWS-0089

#Ignore requirement for customer managed key for S3 encryption as per CUDOS setup instructions
AVD-AWS-0132
2 changes: 2 additions & 0 deletions modules/aws/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ The following modules are available:
- [Group Account Assignments](./group_account_assignments/README.md)
- [Group User Memberships](./group_user_memberships/README.md)
- [Groups](./groups/README.md)
- [Permission Sets](./permission_sets/README.md)
- [Identity Center Instance](./ssoadmin_instance/README.md)
- [Permission Sets](./permission_sets/README.md)
- [Users](./users/README.md)
- [Cost and Usage Reports](./cost_usage_reports/README.md)
25 changes: 25 additions & 0 deletions modules/aws/cost_usage_reports/.terraform.lock.hcl

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

55 changes: 55 additions & 0 deletions modules/aws/cost_usage_reports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Core Cloud AWS Cost & Usage Report Module

This module is responsible for creating and managing Cost and Usage Reports and their related infrastructure in AWS.

## Usage

```hcl
module "cost_usage_reports" {
source = "git::ssh://[email protected]/UKHomeOffice/core-cloud-terraform-modules.git//modules/aws/cost_usage_reports"
report_name = <VALUE>
time_unit = <VALUE>
format = <VALUE>
compression = <VALUE>
additional_schema_elements = <VALUE>
bucket_name = <VALUE>
bucket_region = <VALUE>
additional_artifacts = <VALUE>
s3_prefix = <VALUE>
refresh_closed_reports = <VALUE>
report_versioning = <VALUE>
iam_role = <VALUE>
lifecycle_rule = <VALUE>
noncurrent_version_expiration_days = <VALUE>
expiration_days = <VALUE>
inline_policy_name = <VALUE>
billing_account = <VALUE>
replication_rule = <VALUE>
destination_bucket = <VALUE>
}
```

## Validation

This module expects the variables to conform to the following:
- `report_name` - Must be a string between 1 and 256 characters.
- `time_unit` - Valid values for time_unit are DAILY, HOURLY or MONTHLY.
- `format` - Valid values for format are textORcsv or Parquet.
- `compression` - Valid values for time_unit are GZIP, ZIP or Parquet.
- `additional_schema_elements` - Valid values for additional_schema_elements are RESOURCES or SPLIT_COST_ALLOCATION_DATA.
- `bucket_name` - Must be a string between 1 and 64 characters.
- `bucket_region` - - Must be an AWS region.
- `additional_artifacts` - Valid values for time_unit are REDSHIFT, QUICKSHIFT or ATHENA.
- `s3_prefix` - Must be a string between 1 and 256 characters.
- `refresh_closed_reports` - Boolean value.
- `report_versioning` - Valid values for report_versioning are CREATE_NEW_REPORT or OVERWRITE_REPORT.
- `iam_role` - Friendly name of the role. If omitted, Terraform will assign a random, unique name.
- `lifecycle_rule` - Must be a string between 1 and 256 characters.
- `noncurrent_version_expiration_days` - Must be a positive integer.
- `expiration_days` - Must be a positive integer.
- `inline_policy_name` - Must be a string between 1 and 256 characters.
- `billing_account` - Must be a 12 character string.
- `replication_rule` - Must be a string between 1 and 256 characters.
- `destination_bucket` - The destination_bucket ARN must be less than 256 characters.
217 changes: 217 additions & 0 deletions modules/aws/cost_usage_reports/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,217 @@
terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "> 5.0.0, < 6.0.0"
}
}
}

provider "aws" {
region = "eu-west-2"
}

provider "aws" {
region = "us-east-1"
alias = "us-east-1"
}

#COST AND USAGE REPORT
resource "aws_cur_report_definition" "cur_report_definitions" {
depends_on = [aws_iam_role.cur_role, aws_s3_bucket_policy.cur_S3_bucket_policy]
provider = aws.us-east-1
report_name = var.report_name
time_unit = var.time_unit
format = var.format
compression = var.compression
additional_schema_elements = var.additional_schema_elements
s3_bucket = aws_s3_bucket.s3_buckets.id
s3_region = var.bucket_region
additional_artifacts = var.additional_artifacts
s3_prefix = "cur/${var.billing_account}"
refresh_closed_reports = var.refresh_closed_reports
report_versioning = var.report_versioning
}

#S3 BUCKET
resource "aws_s3_bucket" "s3_buckets" {
bucket = var.bucket_name
}

#S3 SETTINGS
resource "aws_s3_bucket_ownership_controls" "bucket_ownership_controls" {
bucket = aws_s3_bucket.s3_buckets.id
rule {
object_ownership = "BucketOwnerEnforced"
}
}

resource "aws_s3_bucket_versioning" "versioning_rules" {
bucket = aws_s3_bucket.s3_buckets.id
versioning_configuration {
status = "Enabled"
}
}

resource "aws_s3_bucket_server_side_encryption_configuration" "encryption_rules" {
bucket = aws_s3_bucket.s3_buckets.id

rule {
apply_server_side_encryption_by_default {
sse_algorithm = "AES256"
}
}
}

resource "aws_s3_bucket_public_access_block" "cur_public_access_block" {
bucket = aws_s3_bucket.s3_buckets.id

block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}

#IAM ROLE
resource "aws_iam_role" "cur_role" {
name = var.iam_role
assume_role_policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Action" : "sts:AssumeRole",
"Principal" : {
"Service" : "s3.amazonaws.com"
},
"Effect" : "Allow",
"Sid" : ""
}
]
})

inline_policy {
name = var.inline_policy_name

policy = jsonencode({
"Version" : "2012-10-17",
"Statement" : [
{
"Action" : [
"s3:GetReplicationConfiguration",
"s3:ListBucket"
],
"Resource" : "arn:aws:s3:::cid-${var.billing_account}-central-finops-local",
"Effect" : "Allow"
},
{
"Action" : [
"s3:GetObjectVersionForReplication",
"s3:GetObjectVersionAcl"
],
"Resource" : "arn:aws:s3:::cid-${var.billing_account}-central-finops-local/*",
"Effect" : "Allow"
},
{
"Action" : [
"s3:ReplicateObject",
"s3:ReplicateDelete",
"s3:ReplicateTags",
"s3:GetObjectVersionTagging"
],
"Resource" : "arn:aws:s3:::cid-873134405383-shared/cur/${var.billing_account}/*",
"Effect" : "Allow"
}
]
})
}
}

#S3 BUCKET POLICY
resource "aws_s3_bucket_policy" "cur_S3_bucket_policy" {
bucket = aws_s3_bucket.s3_buckets.id
policy = jsonencode({
"Version" : "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Service": "billingreports.amazonaws.com"
},
"Action": [
"s3:GetBucketAcl",
"s3:GetBucketPolicy"
],
"Resource": aws_s3_bucket.s3_buckets.arn,
"Condition": {
"StringEquals": {
"aws:SourceAccount": var.billing_account,
"aws:SourceArn": "arn:aws:cur:us-east-1:${var.billing_account}:definition/*"
}
}
},
{
"Effect": "Allow",
"Principal": {
"Service": "billingreports.amazonaws.com"
},
"Action": "s3:PutObject",
"Resource": "${aws_s3_bucket.s3_buckets.arn}/*",
"Condition": {
"StringEquals": {
"aws:SourceAccount": var.billing_account,
"aws:SourceArn": "arn:aws:cur:us-east-1:${var.billing_account}:definition/*"
}
}
}
]
})
}


#S3 LIFECYCLE RULE
resource "aws_s3_bucket_lifecycle_configuration" "cur_bucket_lifecycle_rule" {
depends_on = [aws_s3_bucket_versioning.versioning_rules]
bucket = aws_s3_bucket.s3_buckets.id
rule {
id = var.lifecycle_rule

filter {}

noncurrent_version_expiration {
noncurrent_days = var.noncurrent_version_expiration_days
}

expiration {
days = var.expiration_days
}
status = "Enabled"
}
}

/* # REPLICATION RULE
resource "aws_s3_bucket_replication_configuration" "cur_bucket_replication_rule" {
depends_on = [aws_s3_bucket_versioning.versioning_rules]
bucket = aws_s3_bucket.s3_buckets.id
role = aws_iam_role.cur_role.arn
rule {
id = var.replication_rule
filter {}
destination {
bucket = var.destination_bucket
storage_class = "STANDARD"
}
delete_marker_replication {
status = "Enabled"
}
source_selection_criteria {
sse_kms_encrypted_objects {
status = "Disabled"
}
}
status = "Enabled"
}
} */
Loading

0 comments on commit 350fba3

Please sign in to comment.