Skip to content

Commit

Permalink
Merge pull request #1 from mitre/v0.2
Browse files Browse the repository at this point in the history
V0.2.0
  • Loading branch information
jkufro authored Sep 27, 2021
2 parents 918ed22 + a1434f1 commit 2bf8a16
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 66 deletions.
135 changes: 73 additions & 62 deletions main.tf
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,28 @@ resource "aws_ecr_repository" "mitre_heimdall_pusher" {
resource "aws_kms_key" "HeimdallPassKmsKey" {
description = "The KMS key used to encrypt/decrypt HeimdallPusher's Heimdall account password "
deletion_window_in_days = 10
enable_key_rotation = true

tags = {
Name = "HeimdallPusherPassKmsKey"
}
}

##
# KMS key for encrypting lambda log data
#
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/kms_key
#
resource "aws_kms_key" "ServerlessHeimdallPusherLogsKmsKey" {
description = "The KMS key used to encrypt ConfigToHdf's logs"
deletion_window_in_days = 10
enable_key_rotation = true

tags = {
Name = "ServerlessHeimdallPusherLogsKmsKey"
}
}

##
# SSM SecureString parameter for the Heimdall password
#
Expand All @@ -58,7 +74,51 @@ resource "aws_ssm_parameter" "heimdall_pass_ssm_param" {
}

##
# HeimdallPusher Role to Invoke HeimdallPusher Lambda function
# HeimdallPusher IAM Policy to Invoke HeimdallPusher Lambda function
#
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_policy
#
resource "aws_iam_policy" "serverless_heimdall_pusher_lambda_policy" {
name = "ServerlessHeimdallPusherLambdaPolicy"
path = "/"
description = "Policy that provides proper lambda permissions for the serverless_heimdall_pusher_lambda_role"

# Permissions
# - ssm:GetParameter => allows decryption of Heimdall Password
# - kms:Decrypt => allows decryption of Heimdall Password
# - s3:GetObject,PutObject,DeleteObject => Allow interaction with results S3 bucket
policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ssm:GetParameter"
]
Effect = "Allow"
Resource = aws_ssm_parameter.heimdall_pass_ssm_param.arn
},
{
Action = [
"kms:Decrypt"
]
Effect = "Allow"
Resource = aws_kms_key.HeimdallPassKmsKey.arn
},
{
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
Effect = "Allow"
Resource = "${data.aws_s3_bucket.results_bucket.arn}/*"
}
]
})
}

##
# HeimdallPusher Role to Invoke HeimdallPusher Lambda function
#
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/iam_role
#
Expand All @@ -68,7 +128,8 @@ resource "aws_iam_role" "serverless_heimdall_pusher_lambda_role" {
# Allow execution of the lambda function
managed_policy_arns = [
"arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole",
"arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole"
"arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole",
aws_iam_policy.serverless_heimdall_pusher_lambda_policy.arn
]

# Allow assume role permission for lambda
Expand All @@ -85,61 +146,6 @@ resource "aws_iam_role" "serverless_heimdall_pusher_lambda_role" {
}
]
})

# Allow READ access to Heimdall password SSM parameter
inline_policy {
name = "HeimdallPassSsmReadAccess"

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"ssm:GetParameter"
]
Effect = "Allow"
Resource = aws_ssm_parameter.heimdall_pass_ssm_param.arn
}
]
})
}

inline_policy {
name = "AllowHeimdallPassKmsKeyDecrypt"

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"kms:Decrypt"
]
Effect = "Allow"
Resource = aws_kms_key.HeimdallPassKmsKey.arn
}
]
})
}

# Allow S3 read and write access to InSpec results bucket
inline_policy {
name = "S3ResultsAccess"

policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Action = [
"s3:GetObject",
"s3:PutObject",
"s3:DeleteObject"
]
Effect = "Allow"
Resource = "${data.aws_s3_bucket.results_bucket.arn}/*"
}
]
})
}
}

resource "null_resource" "push_image" {
Expand Down Expand Up @@ -189,10 +195,14 @@ module "serverless-heimdall-pusher-lambda" {
image_uri = "${aws_ecr_repository.mitre_heimdall_pusher.repository_url}:${local.image_version}"
package_type = "Image"

cloudwatch_logs_kms_key_id = aws_kms_key.ServerlessHeimdallPusherLogsKmsKey.key_id
cloudwatch_logs_retention_in_days = 30

environment_variables = {
HEIMDALL_URL = var.heimdall_url
HEIMDALL_API_USER = var.heimdall_user
HEIMDALL_PASS_SSM_PARAM = aws_ssm_parameter.heimdall_pass_ssm_param.name
HEIMDALL_PUBLIC = var.heimdall_public
}
}

Expand All @@ -211,11 +221,12 @@ data "aws_s3_bucket" "results_bucket" {
# https://registry.terraform.io/providers/hashicorp/aws/latest/docs/resources/lambda_permission
#
resource "aws_lambda_permission" "allow_bucket" {
statement_id = "AllowHeimdallPusherExecutionFromS3Bucket"
action = "lambda:InvokeFunction"
function_name = module.serverless-heimdall-pusher-lambda.lambda_function_arn
principal = "s3.amazonaws.com"
source_arn = data.aws_s3_bucket.results_bucket.arn
statement_id = "AllowHeimdallPusherExecutionFromS3Bucket"
action = "lambda:InvokeFunction"
function_name = module.serverless-heimdall-pusher-lambda.lambda_function_arn
principal = "s3.amazonaws.com"
source_arn = data.aws_s3_bucket.results_bucket.arn
source_account = var.results_bucket_source_account_id != null ? var.results_bucket_source_account_id : data.aws_caller_identity.current.account_id
}

##
Expand Down
6 changes: 4 additions & 2 deletions src/lambda_function.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ def process_record(_event, bucket_name, object_key)
# Save to Heimdall
heimdall_user_password = heimdall_password
user_id, token = get_heimdall_api_token(heimdall_user_password)
push_to_heimdall(filename, hdf, user_id, token, record_contents['eval_tags'])
push_to_heimdall(filename, hdf, user_id, token, record_contents['eval_tags'], record_contents['groups'])

# Save to S3
save_results_to_bucket(record_contents, bucket_name, filename)
Expand Down Expand Up @@ -203,7 +203,7 @@ def get_heimdall_api_token(heimdall_user_password)
# -H "Authorization: Bearer <token>" \
# "http://my-heimdall/evaluations"
#
def push_to_heimdall(filename, hdf, user_id, token, eval_tags)
def push_to_heimdall(filename, hdf, user_id, token, eval_tags, groups)
$logger.info('Pushing HDF results to Heimdall Server...')
url = URI("#{ENV['HEIMDALL_URL']}/evaluations")
payload = {
Expand All @@ -213,6 +213,8 @@ def push_to_heimdall(filename, hdf, user_id, token, eval_tags)
public: ENV['HEIMDALL_PUBLIC'] || 'true',
evaluationTags: eval_tags
}
# Groups are broken out separately because groups may be nil/omitted
payload['groups'] = groups if groups
request = Net::HTTP::Post::Multipart.new(url.path, payload)
request['Authorization'] = "Bearer #{token}"
response = Net::HTTP.start(url.host, url.port) do |http|
Expand Down
14 changes: 13 additions & 1 deletion variables.tf
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@

variable "heimdall_public" {
description = "Set this to 'true' if results should be visible by anyone in Heimdall"
type = string
default = "false"
}

variable "heimdall_url" {
description = "The url to the Heimdall server in http://... format"
type = string
Expand All @@ -20,6 +26,12 @@ variable "results_bucket_id" {
type = string
}

variable "results_bucket_source_account_id" {
description = "The AWS account ID (without a hyphen) of the results S3 bucket source owner."
type = string
default = null
}

variable "subnet_ids" {
description = "The subnet ids to deploy the lambda to."
type = list(string)
Expand All @@ -41,5 +53,5 @@ variable "image_version" {
variable "lambda_name" {
description = "The name of the lambda function"
type = string
default = "serverless-inspec-lambda"
default = "ServerlessHeimdallPusher"
}
2 changes: 1 addition & 1 deletion version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.1.1
0.2.0

0 comments on commit 2bf8a16

Please sign in to comment.