Skip to content

eboboshka/terraform-aws-s3-anti-virus

 
 

Repository files navigation

terraform-aws-s3-anti-virus

Creates an AWS Lambda function to do anti-virus scanning of objects in AWS S3 using bucket-antivirus-function

While waiting for updates on that repo you will need to use a special repository:

git clone git@github.com:upsidetravel/bucket-antivirus-function.git
cd bucket-antivirus-function

With that repo checked out you must run the make all command and then copy the resulting zip file to AWS S3 with:

aws s3 cp bucket-antivirus-function/build/lambda.zip "s3://your-s3-bucket-for-lambda-dependencies/lambda.zip"

or use the s3_bucket_object resource in your Terraform code

...

resource "aws_s3_bucket_object" "function_zip" {
  ## https://github.com/upsidetravel/bucket-antivirus-function
  bucket = module.s3_bucket_dependencies.bucket_id
  key    = "lambda.zip"
  source = "./bucket-antivirus-function/build/lambda.zip"
  etag   = filemd5("./bucket-antivirus-function/build/lambda.zip")
  ...
}

...

Creates the following resources for anti-virus updates:

  • IAM role for Lambda function to update Anti-Virus databases in S3
  • CloudWatch Event to trigger function on a schedule.
  • AWS Lambda function to download Anti-Virus databases files to S3

Creates the following resources for anti-virus scanning:

  • IAM role for Lambda function to scan files in S3
  • S3 Event to trigger function on object creation
  • AWS Lambda function to scan S3 object and send alert to slack if any objects are infected and quarantined.

Terraform Versions

Terraform 0.13 and newer. Pin module version to ~> 3.X. Submit pull-requests to main branch.

Terraform 0.12. Pin module version to ~> 2.X. Submit pull-requests to terraform012 branch.

Usage

module "s3_anti_virus" {
  source = "trussworks/s3-anti-virus/aws"
  version = "2.1.2"

  name_scan   = "s3-anti-virus-scan"
  name_update = "s3-anti-virus-updates"

  lambda_s3_bucket            = "lambda-builds-us-west-2"
  lambda_s3_object_key        = "lambda.zip"

  av_update_minutes = "180"
  av_scan_buckets   = ["bucket-name"]

  av_definition_s3_bucket   = "av-update-bucket-name"
  av_definition_s3_prefix   = "anti-virus"

  tags = {
    "Environment" = "my-environment"
    "Purpose"     = "s3-anti-virus"
    "Terraform"   = "true"
  }
}

Example

...

locals {
  dir_source_code_function = "temp/bucket-antivirus-function"
  dir_build                = "temp/build"
  s3_object_clamav_func    = "Lambda_Function/lambda.zip"
}

resource "null_resource" "build_function" {
  triggers = {
    md5file = try(filemd5("./${local.dir_build}/lambda.zip"), timestamp())
  }

  ## Docker is required on your local machine!
  ## https://www.docker.com/get-started
  ##
  provisioner "local-exec" {
    interpreter = ["docker"]
    command     = "-v"
  }

  provisioner "local-exec" {
    command = <<-EOT
      mkdir -p ./${local.dir_source_code_function} ./${local.dir_build} &&
      git clone git@github.com:upsidetravel/bucket-antivirus-function.git ./${local.dir_source_code_function} &&
      docker build -t bucket-antivirus-function:latest $(pwd)/${local.dir_source_code_function} &&
      docker run -v $(pwd)/${local.dir_build}:/opt/mount --rm --entrypoint cp bucket-antivirus-function:latest /opt/app/build/lambda.zip /opt/mount/lambda.zip &&
      rm -rf ./${local.dir_source_code_function}
    EOT
  }
}

resource "aws_s3_bucket_object" "function_zip" {
  ## https://github.com/upsidetravel/bucket-antivirus-function
  ## Remote
  bucket = module.s3_bucket_dependencies.bucket_id
  key    = local.s3_object_clamav_func

  ## Local
  source = "./${local.dir_build}/lambda.zip"
  etag   = try(filemd5("./${local.dir_build}/lambda.zip"), null)
  tags   = module.naming.tags

  depends_on = [
    null_resource.build_function
  ]
}

module "s3_anti_virus" {
  ## https://github.com/trussworks/terraform-aws-s3-anti-virus
  ## https://registry.terraform.io/modules/trussworks/s3-anti-virus/aws/latest
  source  = "trussworks/s3-anti-virus/aws"
  version = "~> x.x.x"

  name_scan   = "${module.naming.id}-scan"
  name_update = "${module.naming.id}-updates"

  ## https://github.com/upsidetravel/bucket-antivirus-function
  lambda_s3_bucket     = module.s3_bucket_dependencies.bucket_id
  lambda_s3_object_key = aws_s3_bucket_object.function_zip.key

  av_update_schedule_expression = "rate(6 hours)"
  av_definition_s3_bucket       = module.s3_bucket_dependencies.bucket_id
  av_definition_s3_prefix       = "ClamAV_Virus_Database"

  av_scan_buckets = [
    module.s3_bucket_test_1.bucket_id,
    module.s3_bucket_test_2.bucket_id
  ]

  depends_on = [
    module.s3_bucket_dependencies,
    aws_s3_bucket_object.function_zip
  ]

  tags = module.naming.tags
}
...

TODO

  • Add directory with examples
  • Add lambda function build to the module using local-exec.
  • ^ Don't forget to check the installed docker on the local machine
  • Fix permanent triggers and false positives with source_account (known after apply) # forces replacement

Requirements

Name Version
terraform >= 0.13.0
aws >= 3.0

Providers

Name Version
aws >= 3.0

Modules

No modules.

Resources

Name Type
aws_cloudwatch_event_rule.main_update resource
aws_cloudwatch_event_target.main_update resource
aws_cloudwatch_log_group.main_scan resource
aws_cloudwatch_log_group.main_update resource
aws_iam_role.main_scan resource
aws_iam_role.main_update resource
aws_iam_role_policy.main_scan resource
aws_iam_role_policy.main_update resource
aws_lambda_function.main_scan resource
aws_lambda_function.main_update resource
aws_lambda_permission.main_scan resource
aws_lambda_permission.main_update resource
aws_s3_bucket_notification.main_scan resource
aws_caller_identity.current data source
aws_iam_policy_document.assume_role_scan data source
aws_iam_policy_document.assume_role_update data source
aws_iam_policy_document.main_scan data source
aws_iam_policy_document.main_update data source
aws_partition.current data source
aws_region.current data source
aws_s3_bucket.main_scan data source

Inputs

Name Description Type Default Required
av_definition_path Path containing files at runtime string "/tmp/clamav_defs" no
av_definition_s3_bucket Bucket containing antivirus database files. string n/a yes
av_definition_s3_prefix Prefix for antivirus database files. string "clamav_defs" no
av_delete_infected_files Set it True in order to delete infected values. bool false no
av_process_original_version_only Controls that only original version of an S3 key is processed (if bucket versioning is enabled) bool false no
av_scan_buckets A list of S3 bucket names to scan for viruses. list(string) n/a yes
av_scan_start_metadata The tag/metadata indicating the start of the scan string "av-scan-start" no
av_scan_start_sns_arn SNS topic ARN to publish notification about start of scan (optional). string null no
av_signature_metadata The tag/metadata name representing file's AV type string "av-signature" no
av_status_clean The value assigned to clean items inside of tags/metadata string "CLEAN" no
av_status_infected The value assigned to clean items inside of tags/metadata string "INFECTED" no
av_status_metadata The tag/metadata name representing file's AV status string "av-status" no
av_status_sns_arn SNS topic ARN to publish scan results (optional). string null no
av_status_sns_publish_clean Publish AV_STATUS_CLEAN results to AV_STATUS_SNS_ARN. bool true no
av_status_sns_publish_infected Publish AV_STATUS_INFECTED results to AV_STATUS_SNS_ARN. bool true no
av_timestamp_metadata The tag/metadata name representing file's scan time string "av-timestamp" no
av_update_minutes How often to download updated Anti-Virus databases. number null no
av_update_schedule_expression A new, more flexible option for the scheduler. Not working if av_update_minutes variable is set. The scheduling expression how often to download updated Anti-Virus databases. For example, cron(0 20 * * ? *) or rate(180 minutes) string "rate(180 minutes)" no
clamavlib_path Path to ClamAV library files string "./bin" no
cloudwatch_logs_retention_days Number of days to keep logs in AWS CloudWatch. number 90 no
datadog_api_key API Key for pushing metrics to DataDog (optional) string null no
event_source The source of antivirus scan event "S3" or "SNS" (optional) string "S3" no
lambda_package Deprecated. The name of the lambda package. Used for a directory tree and zip file. string "anti-virus" no
lambda_runtime Identifier of the function's runtime. string "python3.7" no
lambda_s3_bucket The name of the S3 bucket used to store the Lambda builds. string n/a yes
lambda_s3_object_key The object key for the lambda distribution. If given, the value is used as the key in lieu of the value constructed using lambda_package and lambda_version. string null no
lambda_version Deprecated. The version the Lambda function to deploy. string "2.0.0" no
memory_size Lambda memory allocation, in MB number 2048 no
name_scan Name for resources associated with anti-virus scanning string "s3-anti-virus-scan" no
name_update Name for resources associated with anti-virus updating string "s3-anti-virus-updates" no
permissions_boundary ARN of the boundary policy to attach to IAM roles. string null no
s3_endpoint The Endpoint to use when interacting wth S3 string null no
sns_endpoint The Endpoint to use when interacting wth SNS string null no
tags A map of tags to add to all resources. map(string) {} no
timeout_seconds Lambda timeout, in seconds number 300 no

Outputs

Name Description
scan_aws_cloudwatch_log_group_arn ARN for the Anti-Virus Scanning Cloudwatch LogGroup.
scan_aws_cloudwatch_log_group_name The Anti-Virus Scanning Cloudwatch LogGroup name.
scan_lambda_function_arn ARN for the Anti-Virus Scanning lambda function.
scan_lambda_function_iam_role_arn Name of the Anti-Virus Scanning lambda role.
scan_lambda_function_iam_role_name Name of the Anti-Virus Scanning lambda role.
scan_lambda_function_name The Anti-Virus Scanning lambda function name.
scan_lambda_function_version Current version of the Anti-Virus Scanning lambda function.
update_aws_cloudwatch_log_group_arn ARN for the Anti-Virus Definitions Cloudwatch LogGroup.
update_aws_cloudwatch_log_group_name The Anti-Virus Definitions Cloudwatch LogGroup name.
update_lambda_function_arn ARN for the Anti-Virus Definitions lambda function.
update_lambda_function_iam_role_arn ARN of the Anti-Virus Definitions lambda role.
update_lambda_function_iam_role_name Name of the Anti-Virus Definitions lambda role.
update_lambda_function_name The Anti-Virus Definitions lambda function name.
update_lambda_function_version Current version of the Anti-Virus Definitions lambda function.

About

Creates and configures Anti-Virus Scanning of S3 Buckets.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • HCL 100.0%