More SIEM vendors are offering Infrastructure as Code (IaC) deployment for ingesting logs, but the guides are often written in a way that makes them difficult to use within an existing IaC environment. This can get especially “fun” when you have multiple logging systems in place, which is not that uncommon. Following the stock suggestions can also lead to more resource sprawl than necessary because multiple roles may be created when a single role would suffice. Having done this a couple times, I wanted to make a few notes on how to deploy AWS resources in a way that is flexible and solution agnostic. Basically, a setup that will let you set up access to the S3 bucket(s) of your choosing for multiple solutions. The goal was both to have a solution that would make it easy to track what resources were associated with centralized logging and could be used with one or more solutions. The added benefit is having a setup that makes it easier to avoid vendor lock-in. There’s nothing wrong with the docs – they are just written to be deployed in isolation. While you could hand those docs off to DevOps for deployment, that can be a fairly big blocker and result in a fair amount of back and forth to get a clean understanding of what the requirements are because the pattern is likely a bit different from the typical pipeline.
I’ll be using Panther and Scanner as examples because those are two that I’m familiar with. The two have slightly different approaches to how they deal with the trust relationship. My hope is that showing the two will help detection engineers understand how logging architecture can be set up via code. Plus both have documentation that makes this easy to follow for someone less familiar with IaC. I would implement these as modules so you can deploy to multiple AWS accounts and keep things uniform.
These should serve as a starting point to help avoid sprawl and avoid having to manually deploy resources (which requires permissions in AWS accounts that really should be locked down). You could use the repo as a module, but that may not work well in your environment. Have a conversation with your DevOps team about how to best fit this in with your existing code.
The key components are:
- SIEM general resources
- SNS module
- S3 module
- Panther resources
- IAM
- Bucket access
- SQS subscription
- Scanner resources
- IAM
- Index bucket
- Bucket access
- SQS subscription
You will use the SIEM resources as building blocks to deploy the SNS topic and provide access to the S3 buckets to the IAM resources created from the Panther and Scanner sections.
You could use Terragrunt stacks or data blocks to avoid having to hard code buckets, keys, roles, etc. That’s not necessary, but it can be really helpful if something changes or you end up deploying in multiple environments. Which option works will largely depend on your overall IaC setup. Data blocks may be easiest and avoid having to learn a new tool. Carefully consider the repo structure used for IaC to determine how you can reduce manual toil for resource deployment both now and in the future.
For Panther, you will need to set up the SQS queue to allow your AWS account by adding an initial resource. You could do this through the UI and using one of the provided CloudFormation stacks, but that kind of defeats the whole purpose of this approach – you don’t want anything done manually. Plus there’s a decent chance that you won’t have the required permissions to deploy that way in all of your environments. There are two ways to work around this. If you are in a more strictly controlled environment and cannot run a manual apply (whether through CI/CD or CLI), you will need to split the code into multiple PRs. First create the IAM resources and bucket access and go through the CI/CD process for those, then create a log source in Panther using that role info to register the account. Once that log source has been successfully created, you can then add the code for the SQS subscription in a new PR.
If you are responsible for deploying the resources yourself and have the option to only go through the CI/CD process once, that can be a little “easier”. It just depends on where your organization is and what your role/responsibilities are. It can be the better choice to reduce the burden on your teammates by only sending through a single PR when you know there will be multiple steps. You would create all the code and deploy your infrastructure, expecting the error on your SQS resource. Then manually add a log source using the account in Panther as above, deploy again, and complete the CI/CD process.
For Scanner, you need to create the source to get the external ID and then deploy with that info. Depending on timing, you may have to go through adding the account again and update the external ID if setup times out. Hopefully with this guide you won’t need to. If you are within 24h and keep the browser tab with the account setup open, it should be fine, beyond that, you may need to reset the information. Also consider how you want to protect the Scanner index bucket in your environment,
Please note, if you don’t have things set up to deploy to AWS via Terraform, whether via CLI or CI/CD, this code will not work. And if you do, there will likely be some tweaks needed to fit your environment and naming conventions. But it should get you most of the way there. Hashicorp has a walkthrough on automating Terraform with GitHub Actions that would help you get set up if you need to start from nothing.
This approach could easily be extended to grant access to other vendors needing S3 access. As more teams try to extract more value from logs, it’s not uncommon to need access from multiple tools. Applying IaC to manage this access makes it much easier to track what access a tool has and remove that access if the time comes. An added benefit is it’s equally easy to grant a new tool access to buckets.


