Building on IaC for better Developer experience
Tags: cloud, cloudcomputing, devops, programming
Published: 2023-07-10 19:31:35

Introducing an Infrastructure as Code (IaC) framework into your development workflow can bring numerous benefits and streamline your software development process.

**Terraform** acts as an abstraction layer that simplifies infrastructure provisioning and management by providing a consistent and declarative approach across different cloud providers and platforms. It allows you to focus on defining the desired state of your infrastructure without getting into the intricacies of the underlying implementations.

**Nitric** abstracts over _Pulumi_ and _Terraform_ to further eliminate the fine-grained configuration details.

In my experience as a software developer, convenience has almost always been more important than control, accounting for about 99% of the time. Especially since we're all developers with time constraints and real-world consequences ...

Let's take a look at an example of using both to create a scheduled job.

## Schedule Job with AWS & Nitric

```javascript
import { schedule } from '@nitric/sdk'

// every 15 minutes
schedule('check for updates').cron('0/15 * * * *', async (ctx) => {
  console.log('checking for updates')
})
```

And the configuration required for the CLI to deploy it to AWS:

```yaml
name: my-cron-job
provider: nitric/aws@0.24.0
region: us-east-1
```

> Note: Nitric automatically creates your containerized Lambda image at deploy time.

## Schedule Job with AWS, Terraform & Lambda Function

> Note: The Lambda function code and packaging are maintained in a separate project.

```hcl
# Define AWS provider
provider "aws" {
  region = "us-east-1"  # Replace with your desired AWS region
}

# Create AWS Lambda function
resource "aws_lambda_function" "my_lambda_function" {
  filename         = "lambda_function.zip"  # Replace with the path to your Lambda function code
  function_name    = "my-lambda-function"
  role             = aws_iam_role.lambda_role.arn
  handler          = "index.handler"
  runtime          = "nodejs14.x"  # Replace with the desired runtime
}

# Create IAM role for the Lambda function
resource "aws_iam_role" "lambda_role" {
  name = "lambda-role"

  assume_role_policy = <<EOF
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "lambda.amazonaws.com"
      },
      "Action": "sts:AssumeRole"
    }
  ]
}
EOF
}

# Attach the required policies to the IAM role
resource "aws_iam_role_policy_attachment" "lambda_policy_attachment" {
  policy_arn = "arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole"
  role       = aws_iam_role.lambda_role.name
}

# Create CloudWatch Events rule for scheduling the cron job
resource "aws_cloudwatch_event_rule" "cron_job_rule" {
  name        = "my-cron-job-rule"
  description = "Scheduled rule for cron job"
  schedule_expression = "cron(0 0 * * ? *)"  # Replace with your desired cron schedule

  # Add a target to trigger the Lambda function
  target {
    id         = "my-lambda-function"
    arn        = aws_lambda_function.my_lambda_function.arn
  }
}

# Add permissions for CloudWatch Events to invoke the Lambda function
resource "aws_lambda_permission" "cloudwatch_permission" {
  statement_id  = "AllowExecutionFromCloudWatch"
  action        = "lambda:InvokeFunction"
  function_name = aws_lambda_function.my_lambda_function.arn
  principal     = "events.amazonaws.com"
  source_arn    = aws_cloudwatch_event_rule.cron_job_rule.arn
}
```

In this example, you'll need to replace the placeholders with your own values:
- Replace `"us-east-1"` with your desired AWS region.
- Replace `"lambda_function.zip"` with the path to your Lambda function code, assuming it's in a zip file.
- Modify the `"function_name"` and `"runtime"` parameters of the `aws_lambda_function` resource according to your preferences.
- Adjust the cron expression in the `schedule_expression` parameter of the `aws_cloudwatch_event_rule` resource to schedule the cron job as desired.

This Terraform code creates an AWS Lambda function, an IAM role with the required policies, a CloudWatch Events rule to schedule the cron job, and the necessary permissions for CloudWatch Events to invoke the Lambda function.

Remember to run `terraform init`, `terraform plan`, and `terraform apply` to initialize, plan, and apply the Terraform configuration.