provider "aws" {
  region = "${var.aws_region}"
}

# Create IAM roles for lambda functions
data "aws_iam_policy_document" "assume_lambda_role" {
  statement {
    actions = [
      "sts:AssumeRole"]
    principals {
      type = "Service"
      identifiers = [
        "lambda.amazonaws.com"]
    }
  }
}

### Backup function
resource "aws_iam_role" "lambda_backup_role" {
  name = "${var.function_prefix}-backup"
  assume_role_policy = "${data.aws_iam_policy_document.assume_lambda_role.json}"
}

data "aws_iam_policy_document" "lambda_backup_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "logs:CreateLogGroup"
    ]
    resources = [
      "arn:aws:logs:*:*:*"
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "logs:CreateLogStream",
      "logs:PutLogEvents"
    ]
    resources = [
      "arn:aws:logs:*:*:*"
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "ec2:DescribeSnapshots",
      "ec2:DescribeVolumes",
      "ec2:CreateSnapshot"
    ]
    resources = [
      "*"
    ]
  }
  statement {
    effect = "Allow"
    actions = [

      "ec2:CreateTags"
    ]
    resources = [
      "*"
    ]
  }
}

resource "aws_iam_policy" "lambda_backup_policy" {
  name = "${var.aws_volume_tag}-policy"
  policy = "${data.aws_iam_policy_document.lambda_backup_policy_document.json}"
}

resource "aws_iam_role_policy_attachment" "lambda_backup_policy_attachment" {
  policy_arn = "${aws_iam_policy.lambda_backup_policy.arn}"
  role = "${aws_iam_role.lambda_backup_role.name}"
}

resource "aws_lambda_function" "lambda_backup" {
  filename = "${path.module}/lambda_backup.zip"
  function_name = "${var.function_prefix}_lambda"
  role = "${aws_iam_role.lambda_backup_role.arn}"
  handler = "lambda_backup.handler"
  source_code_hash = "${base64sha256(file("${path.module}/lambda_backup.zip"))}"
  runtime = "python3.6"

  environment {
    variables = {
      VOLUME_TAG = "${var.aws_volume_tag}"
    }
  }

  tags {
    terraformed = "true"
  }
}

resource "aws_cloudwatch_event_rule" "lambda_backup_daily" {
  name = "${var.function_prefix}_daily"
  schedule_expression = "rate(${var.aws_rate})"
  description = "Create snapshots for volumes"
}

resource "aws_cloudwatch_event_target" "lambda_backup_target" {
  rule = "${aws_cloudwatch_event_rule.lambda_backup_daily.name}"
  target_id = "${var.function_prefix}_backup_target"
  arn = "${aws_lambda_function.lambda_backup.arn}"
}

resource "aws_lambda_permission" "allow_cloudwatch_to_call_lambda_backup" {
  statement_id = "AllowExecutionFromCloudWatch"
  action = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.lambda_backup.function_name}"
  principal = "events.amazonaws.com"
  source_arn = "${aws_cloudwatch_event_rule.lambda_backup_daily.arn}"
}

### Retention function
resource "aws_iam_role" "lambda_retention_role" {
  name = "${var.function_prefix}-retention"
  assume_role_policy = "${data.aws_iam_policy_document.assume_lambda_role.json}"
}

data "aws_iam_policy_document" "lambda_retention_policy_document" {
  statement {
    effect = "Allow"
    actions = [
      "logs:CreateLogGroup"
    ]
    resources = [
      "arn:aws:logs:*:*:*"
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "logs:CreateLogStream",
      "logs:PutLogEvents"
    ]
    resources = [
      "arn:aws:logs:*:*:*"
    ]
  }
  statement {
    effect = "Allow"
    actions = [
      "ec2:DescribeVolumes",
      "ec2:DescribeSnapshots",
      "ec2:DeleteSnapshot"
    ]
    resources = [
      "*"
    ]
  }
}

resource "aws_iam_policy" "lambda_retention_policy" {
  name = "${var.aws_volume_tag}-retention-policy"
  policy = "${data.aws_iam_policy_document.lambda_retention_policy_document.json}"
}

resource "aws_iam_role_policy_attachment" "lambda_retention_policy_attachment" {
  policy_arn = "${aws_iam_policy.lambda_retention_policy.arn}"
  role = "${aws_iam_role.lambda_retention_role.name}"
}

resource "aws_lambda_function" "lambda_retention" {
  filename = "${path.module}/lambda_retention.zip"
  function_name = "snapshot_retention_lambda"
  role = "${aws_iam_role.lambda_retention_role.arn}"
  handler = "lambda_retention.handler"
  source_code_hash = "${base64sha256(file("${path.module}/lambda_retention.zip"))}"
  runtime = "python3.6"

  environment {
    variables = {
      VOLUME_TAG = "${var.aws_volume_tag}"
    }
  }

  tags {
    terraformed = "true"
  }
}

resource "aws_cloudwatch_event_rule" "lambda_retention" {
  name = "${var.function_prefix}_retention"
  event_pattern = <<PATTERN
{
  "source": [
    "aws.ec2"
  ],
  "detail-type": [
    "EBS Snapshot Notification"
  ],
  "detail": {
    "event": [
      "createSnapshot"
    ],
    "result": [
      "succeeded"
    ]
  }
}
PATTERN
  description = "Invoke retention lambda"
}

resource "aws_cloudwatch_event_target" "lambda_retention_target" {
  rule = "${aws_cloudwatch_event_rule.lambda_retention.name}"
  target_id = "${var.function_prefix}_retention_target"
  arn = "${aws_lambda_function.lambda_retention.arn}"
  input_path = "$.detail.snapshot_id"
}

resource "aws_lambda_permission" "allow_cloudwatch_to_call_lambda_retention" {
  statement_id = "AllowExecutionFromCloudWatch"
  action = "lambda:InvokeFunction"
  function_name = "${aws_lambda_function.lambda_retention.function_name}"
  principal = "events.amazonaws.com"
  source_arn = "${aws_cloudwatch_event_rule.lambda_retention.arn}"
}
