Terraform
Getting started with Terraform
You can use this Terraform file to set up the IAM role, IAM policies,and S3 bucket to integrate with Scanner. You provide the value for s3_bucket_to_index
, and Scanner provides the values for scanner_aws_account_id
and scanner_external_id
.
It will also update your S3 bucket to send s3:ObjectCreated
notifications to the SQS queue in your Scanner instance.
variable "scanner_external_id" {
description = "Scanner provides an External ID to use here."
type = string
}
variable "scanner_aws_account_id" {
description = "Scanner provides its AWS Account ID to use here."
type = string
}
variable "s3_bucket_to_index" {
description = "Enter the name of the S3 bucket that you would like Scanner to index."
type = string
}
resource "aws_iam_role" "scanner_role" {
name = "ScannerRole"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
AWS = var.scanner_aws_account_id
}
Action = "sts:AssumeRole"
Condition = {
StringEquals = {
"sts:ExternalId" = var.scanner_external_id
}
}
}
]
})
}
resource "aws_sns_topic" "logs_bucket_event_notification_topic" {
name = "scnr-LogsBucketEventNotificationTopic"
}
resource "aws_sns_topic_policy" "logs_bucket_event_notification_topic_policy" {
arn = aws_sns_topic.logs_bucket_event_notification_topic.arn
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = ["SNS:Publish"]
Effect = "Allow"
Principal = {
Service = "s3.amazonaws.com"
}
Resource = aws_sns_topic.logs_bucket_event_notification_topic.arn
}
]
})
}
resource "aws_s3_bucket_notification" "s3_bucket_to_index_notification" {
bucket = var.s3_bucket_to_index
topic {
topic_arn = aws_sns_topic.logs_bucket_event_notification_topic.arn
events = ["s3:ObjectCreated:*"]
}
}
resource "aws_sns_topic_subscription" "logs_bucket_event_notification_topic_subscription" {
topic_arn = aws_sns_topic.logs_bucket_event_notification_topic.arn
protocol = "sqs"
endpoint = "arn:aws:sqs:${data.aws_region.current.name}:${var.scanner_aws_account_id}:scnr-S3ObjectCreatedNotificationsQueue"
}
resource "aws_s3_bucket" "scanner_index_files_bucket" {
bucket = "scanner-index-files-${var.scanner_external_id}"
// NOTE: With this flag, Terraform will disallow the deletion of the entire
// stack. Unfortunately Terraform does not yet provide a way to protect only
// some resources while deleting the rest.
lifecycle {
prevent_destroy = true
}
}
resource "aws_s3_bucket_public_access_block" "scanner_index_files_bucket_public_access_block" {
bucket = aws_s3_bucket.scanner_index_files_bucket.id
block_public_acls = true
block_public_policy = true
ignore_public_acls = true
restrict_public_buckets = true
}
resource "aws_s3_bucket_server_side_encryption_configuration" "scanner_index_files_bucket_encryption_config" {
bucket = aws_s3_bucket.scanner_index_files_bucket.id
rule {
bucket_key_enabled = true
apply_server_side_encryption_by_default {
sse_algorithm = "aws:kms"
}
}
}
resource "aws_s3_bucket_lifecycle_configuration" "scanner_index_files_bucket_lifecycle_configuration" {
bucket = aws_s3_bucket.scanner_index_files_bucket.id
rule {
id = "ExpireTagging"
status = "Enabled"
filter {
tag {
key = "Scnr-Lifecycle"
value = "expire"
}
}
expiration {
days = 1
}
}
rule {
id = "AbortIncompleteMultiPartUploads"
status = "Enabled"
abort_incomplete_multipart_upload {
days_after_initiation = 1
}
}
}
resource "aws_iam_policy" "scanner_policy" {
name = "ScannerPolicy"
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Action = [
"s3:ListAllMyBuckets",
"s3:GetBucketLocation",
"s3:GetBucketTagging"
]
Resource = "*"
},
{
Effect = "Allow"
Action = "s3:ListBucket"
Resource = "arn:aws:s3:::${var.s3_bucket_to_index}"
},
{
Effect = "Allow"
Action = "s3:GetObject"
Resource = "arn:aws:s3:::${var.s3_bucket_to_index}/*"
},
{
Effect = "Allow"
Action = [
"s3:GetObjectTagging",
"s3:PutObjectTagging",
"s3:ListBucket",
"s3:CreateBucket",
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
Resource = [
"arn:aws:s3:::scanner-index-files-${var.scanner_external_id}",
"arn:aws:s3:::scanner-index-files-${var.scanner_external_id}/*"
]
}
]
})
}
resource "aws_iam_policy_attachment" "scanner_policy_attachment" {
name = "ScannerPolicyAttachment"
roles = [aws_iam_role.scanner_role.name]
policy_arn = aws_iam_policy.scanner_policy.arn
}
output "scanner_role_arn" {
description = "The ARN of the new Scanner IAM Role"
value = aws_iam_role.scanner_role.arn
}
data "aws_caller_identity" "current" {}
data "aws_region" "current" {}
Last updated