Using Terraform for managining Amazon Web Service infrastructure

In the last days I tested Terraform (Use Infrastructure as Code to provision and manage any cloud, infrastructure, or service) for managing some resources in a AWS cloud ebvironemnt.

In this sample I’ll create and schedule a lambda function

Create a file "variables.tf" with the content:

variable "aws_region" {default = "eu-west-1"}
variable "aws_profile" {default = ""}
variable "project" {default = "my_project"}

variable "vpc" {default= "XXXXX"}
variable "subnets" {default= "XXXX"}
variable "aws_account" {default= "XXX"}
variable "security_groups" {default= "XXXX"}
#
variable "db_redshift_host" {default= ""}
variable "db_redshift_port" {default= ""}
variable "db_redshift_name" {default= ""}
variable "db_redshift_username" {default= ""}
variable "db_redshift_password" {default= ""}
Create a file lambda.tf as follow:

provider "aws" {
  region  = "${var.aws_region}"
  profile = "${var.aws_profile}"
}
# ############################################################################
# CLOUDWATCH
# ############################################################################
resource "aws_cloudwatch_log_group" "log_group" {
  name              = "/aws/lambda/${var.project}"
  retention_in_days = 14
}

# ############################################################################
# CLOUDWATCH rules
# ############################################################################
resource "aws_cloudwatch_event_rule" "rule" {
  name        = "${var.project}-rule"
  description = "scheduler for ${var.project}"
  schedule_expression = "cron(0 10 * * ? *)"
}
resource "aws_cloudwatch_event_target" "trigger_lambda" {
  rule  = "${aws_cloudwatch_event_rule.rule.name}"
  arn   = "${aws_lambda_function.lambda.arn}"
}

# ############################################################################
# iam
# ############################################################################
resource "aws_iam_role" "role" {
  name = "${var.project}_role"
  #assume_role_policy = "${file("assumerolepolicy.json")}"
  assume_role_policy = <<EOF
{
"Version": "2012-10-17",
"Statement": [
  {
    "Action": "sts:AssumeRole",
    "Principal": {
      "Service": "lambda.amazonaws.com"
    },
    "Effect": "Allow",
    "Sid": ""
  }
]
}
EOF
}

resource "aws_iam_policy" "logging" {
  name = "${var.project}_logging"
  path = "/"
  description = "${var.project} IAM policy for logging"

  policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*",
      "Effect": "Allow"
    }
  ]
}
EOF
}

resource "aws_iam_role_policy_attachment" "logging" {
  role = "${aws_iam_role.role.name}"
  policy_arn = "${aws_iam_policy.logging.arn}"
}

resource "aws_iam_role_policy_attachment" "policy_attachment_vpc" {
  #name       = "${var.project}_attachment_vpc"
  role       = "${aws_iam_role.role.name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonVPCFullAccess"
}

resource "aws_iam_role_policy_attachment" "policy_attachment_rds" {
  role       = "${aws_iam_role.role.name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonRDSReadOnlyAccess"
}

resource "aws_iam_role_policy_attachment" "policy_attachment_redshift" {
  role       = "${aws_iam_role.role.name}"
  policy_arn = "arn:aws:iam::aws:policy/AmazonRedshiftReadOnlyAccess"
}

# ###############################################
# lambda_action
# ###############################################

resource "aws_lambda_function" "lambda" {
  function_name = "${var.project}_lambda"
  depends_on    = ["aws_iam_role_policy_attachment.logging", "aws_cloudwatch_log_group.log_group"]
  filename      = "lambda.zip"
  role          = "${aws_iam_role.role.arn}"
  handler       = "lambda_function.lambda_handler"
  source_code_hash = "${filebase64sha256("lambda.zip")}"
  runtime = "python3.7"
  timeout          = "30"
  memory_size      = 256
  publish          = true
  vpc_config {
    subnet_ids = "${var.subnets}"
    security_group_ids = "${var.security_groups}"
  }

  environment {
    variables = {
      db_redshift_host= "${var.db_redshift_host}"
      db_redshift_port= var.db_redshift_port
      db_redshift_name= "${var.db_redshift_name}"
      db_redshift_username= "${var.db_redshift_username}"
      db_redshift_password= "${var.db_redshift_password}"
    }
  }
}

Now you can run

terraform init 
terraform  plan -var aws_profile=myprofile
terraform  apply -var aws_profile=myprofile 
terraform  destroy -var aws_profile=myprofile