Configuring Amazon SQS queues using terraform
Published: 2022-03-31 01:54:05

[Amazon SQS](https://aws.amazon.com/sqs/) is a lightweight, fully-managed message queuing service. We can use SQS to decouple and scale microservices, 
serverless applications, and distributed systems. 
SQS makes it easy to store, receive, and send messages between software components.

In this blog you will see how we can configure an S3 bucket as source of event for a SQS Queue to be consumed by [Microsoft Sentinel](https://docs.microsoft.com/en-us/azure/sentinel/overview);a scalable, cloud-native, security information and event management (SIEM) and security orchestration, automation, and response (SOAR) solution. In our case we will showcase how we can make use of SQS to push all the CloudTrail data generated in our account to Microsoft Sentinel there by establising communication between two major cloud providers. 

For this to happen we will need an **IAM assumed role** with necessary permissions to grant Microsoft Sentinel access to your CloudTrail logs stored in S3 Bucket and the message generated in SQS as a result of object creation in the bucket.

Resource: `aws_iam_role` is used to create an assumed role `AzureSentinelRole` to grant permissions to your Microsoft Sentinel account (ExternalId) to access your AWS resources. We also need to attach appropriate IAM permissions policies to grant Microsoft Sentinel access to the appropriate resources such as S3 bucket, SQS etc.

```
data "aws_iam_policy_document" "assume_role" {
  statement {
    effect  = "Allow"
    actions = ["sts:AssumeRole"]
    principals {
      type        = "AWS"
      identifiers = ["arn:aws:iam::197857026523:root"]
    }
    condition {
      test     = "StringEquals"
      variable = "sts:ExternalId"
      values   = ["65d3595c-c730-4a11-5e37-5115bae05e5e"]
    }
  }
}

resource "aws_iam_role" "this" {
  name                  = "AzureSentinelRole"
  description           = "Azure Sentinel Integration"
  assume_role_policy    = data.aws_iam_policy_document.assume_role.json
  managed_policy_arns = [
    "arn:aws:iam::aws:policy/AmazonSQSReadOnlyAccess",
    "arn:aws:iam::aws:policy/AmazonS3ReadOnlyAccess",
    "arn:aws:iam::aws:policy/service-role/AWSLambdaSQSQueueExecutionRole"
  ]
}
```

- `65d3595c-c730-4a11-5e37-5115bae05e5e` : [Log Analytics workspace](https://docs.microsoft.com/en-us/azure/azure-monitor/logs/log-analytics-workspace-overview) id 

- `197857026523` : Microsoft Sentinel's service account ID for AWS

- AmazonSQSReadOnlyAccess, AWSLambdaSQSQueueExecutionRole, AmazonS3ReadOnlyAccess permission policies attached to the Sentinel role.

Resource: `aws_sqs_queue` is used to create the SQS queue named `awscbcloudtrailqueue` 

Resource: `aws_sqs_queue_policy` is used to create SQS Policy that grants `AzureSentinelRole` necessary permission to carry out required actions on the newly created SQS queue.

```
resource "aws_sqs_queue" "sqs_queue" {
  name                      = var.trailQueueName
  delay_seconds             = 90
  max_message_size          = 2048
  message_retention_seconds = 86400
  receive_wait_time_seconds = 10
  kms_master_key_id         = aws_kms_key.primary.arn

  depends_on = [
    aws_s3_bucket.cloudtrailbucket,
    aws_kms_key.primary
  ]
}

resource "aws_sqs_queue_policy" "sqs_queue_policy" {
  queue_url = aws_sqs_queue.sqs_queue.id
  policy    = <<POLICY
{
  "Version": "2012-10-17",
  "Id": "sqspolicy",
  "Statement": [
    {
      "Sid": "CloudTrailSQS",
      "Effect": "Allow",
      "Principal": {
          "Service": "s3.amazonaws.com"
      },
      "Action": [
          "SQS:SendMessage"
      ],
      "Resource": "${aws_sqs_queue.sqs_queue.arn}",
      "Condition": {
          "ArnLike": {
              "aws:SourceArn": "${aws_s3_bucket.cloudtrailbucket.arn}"
          },
          "StringEquals": {
              "aws:SourceAccount": "${data.aws_caller_identity.current.account_id}"
          }
      }
    },
    {
      "Sid": "CloudTrailSQS",
      "Effect": "Allow",
      "Principal": {
           "AWS": "arn:aws:iam::${data.aws_caller_identity.current.account_id}:role/AzureSentinelRole"
      },
      "Action": [
        "SQS:ChangeMessageVisibility",
        "SQS:DeleteMessage",
        "SQS:ReceiveMessage",
        "SQS:GetQueueUrl"
      ],
      "Resource": "${aws_sqs_queue.sqs_queue.arn}" 
    }
  ]
}
POLICY
}
```
![SQS Queue access policy](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6jnluq2quut2utmymbg7.png)

We need to configure CloudTrail S3 bucket `awscbcloudtrail` to send notifications to your SQS queue when an object is created in it. 

Resource: `aws_s3_bucket_notification` is used to create a notification named `awscbtrail-log-event` on the bucket `awscbcloudtrail` with the destination as the SQS queue we created above.

```
resource "aws_s3_bucket_notification" "bucket_notification" {
  bucket = aws_s3_bucket.cloudtrailbucket.id
  queue {
    id        = "${var.trailName}-log-event"
    queue_arn = aws_sqs_queue.sqs_queue.arn
    events    = ["s3:ObjectCreated:*"]
  }
  depends_on = [
    aws_sqs_queue.sqs_queue
  ]
}
```

![s3 bucket notification](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/crdv4wc1tgwjh8m4j7k5.png)

Once the s3 bucket notification is in place and with the proper permission set we will see the messages arriving in the queue. Shown below is the queue received 1 message -
 
![SQS Queue receiving message](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/haybhjojc8el6no5atkj.png)

Let's put the url for the sqs queue and the arn for the Sentinel Role that we created above as an output in terraform:
```
output "sentinelrole" {
    value = aws_iam_role.this.arn
}

output "sqsurl" {
  value = aws_sqs_queue.sqs_queue.url
}

....
Changes to Outputs:
  + sentinelrole = "arn:aws:iam::123456789012:role/AzureSentinelRole"
  + sqsurl       = "https://sqs.ap-southeast-1.amazonaws.com/123456789012/awscbcloudtrailqueue"
```

Source code for above setup is [here](https://github.com/sujaypillai/awscb001/tree/sqs)

In the next blog we will see how we can connect Microsoft Sentinel to your AWS Account to consume the above message created in SQS queue, thus allowing us to ingest the CloudTrail data to Azure.