Organizing AWS resources to find resources, reduce errors, plan for growth, and handle security incidents more efficiently
This is a continuation of my series on Automating Cybersecurity Metrics.
We’ve been creating a lot of things with CloudFormation throughout this blog series. It’s time to pause a bit and think about how we might better organize these resources — especially for those in a large organization.
Let’s say you are searching through your account for all the resources related to a particular project. Wouldn’t it be nice if you could easily sort a list by name and see all the related items together? If you are at a large company, would you like to see all the items in a particular department grouped together? What if you are looking at CloudFormation stacks and you want to find all the templates that create a role?
AWS Tags are often touted as the solution to all your problems when organizing resources for governance and billing. AWS Tags are useful, but they are also problematic. I’ve worked in an organization with 11,000 developers who were told to tag things a certain way. Let’s just say that’s not gonna happen. If you want things tagged correctly you have to automate it. That’s what I did at the next company I went to. I got my DevOps team to build out a deployment system that automatically tagged resources with user names based on Active Directory login names.
Tags have other cons as well. Although you can use tags to try to categorize and search on items, not all items can be tagged. It’s also more complicated to search the list of CloudFormation stacks by tag than name. If you’re trying to base your billing off of tags there will be things that fall between the cracks. Tags just aren’t comprehensive and they are error prone.
Additionally, it’s simply harder to search on tags then just sorting resources by name for people who are using the AWS Console. Now some developers out there will scoff and say, “I can just run an AWS CLI query and easily get this information!” Yes, you can.
But it’s easier to just log into the console and type “role” and have all the templates come up. There may be a case where a person less technical than you such as an auditor, a security person who doesn’t know how to program, or someone else needs to quickly find that information. Tags are possible, but they are not as easy as a good naming convention.
AWS Resource Groups
You can also use something called AWS Resource Groups to organize your resources. This seems like an idea that got off the ground but was never completed.
Once again, you will be limited to the resources that work with Resource Groups and there are a lot of resources missing from this list.
Unlike Azure Resource Groups, AWS resources are not required to define a resource groups. Resource groups also are not used for assigning policies to a set of resources. They are simply for grouping and querying related items.
One of the nicest things about Resource Groups on Azure is the ability to delete a resource group and automatically everything in that resource group is deleted. AWS Resource Groups don’t have that functionality or anything like it that I know of — you’ll need to create scripts to create and delete resources in a project. I created such a script in this GitHub repo but it was much improved by the time I delivered it in class. It will give you an idea of what I am talking about however:
Grouping resources by accounts
Although the above methods of grouping resources are interesting and may be helpful in some cases, I find it easier to put similar items in the same account when security is an issue. AWS accounts provide the governance functionality of management groups and resource groups on Azure. They define IAM boundaries that people within them cannot cross. It’s easier to ensure a person does not go outside of that boundary within an account than trying to create complicated policies based on tags and conditions within an account.
The only downside is when someone needs cross-account access things can get tricky, and I’m not convinced the logging is always sufficient. I’m still exploring that topic. The other thing is that if you’re sending traffic cross-account you’ll need to send it outside the account. If you send it over the Internet which is less secure, it will cost more. It will be more secure over a peering connection, but you will need to keep it within a single availability zone to avoid additional fees:
Adding new accounts may also increase fees when using something like AWS Control Tower that charges you based on the number of Config Rules you create in each account.
One of the reasons I’m looking into batch jobs and lambda functions to trigger actions across accounts is to overcome this permission boundary issue. Stay tuned as I explore this idea as we proceed through this series of blog posts. Research is occurring before your very reading eyes.
Naming conventions can help us organize and find our resources. Different organizations may have different naming conventions based on their size. For example, a startup my organize items by projects. A larger organization may also organize resources based lines of business and departments within each line of business.
One thing I mentioned before is that you may want to add a region name to your CloudFormation templates that name resources. Not only will this help you quickly identify the region where a resources exists, it will also ensure that you have unique names across regions which is usually a requirement on AWS.
What sort of naming convention do you want? I have recently been finding that naming conventions with a period (.) are easier to read. Hold that thought and read the next section before you start naming your resources. First let’s consider what words we might want in our names.
Let’s say I have two departments — training and pentesting. I have projects (classes and tests) within those departments. I might have naming convention like:
Now let’s say I’m on the security team and I want to create batch jobs to run reports for — security metrics. I have a number of batch jobs that run different tools and batch jobs that formulate the final report. Maybe I want to have a naming convention that distinguishers batch jobs from other projects. My naming convention could look something like this:
If you plan to have failover to another region, then you would have to add a region name to most resources like this:
or perhaps like this:
There’s no one right answer as to how you should name your resources.
Caveat: AWS Naming Conventions are Completely Incosistent!
I like to name my CloudFormation templates the same name as the resource it creates, but include the type of resource. Or I might put the resource type in the resource name. I would love to use the same naming conventions within my CloudFormation templates.
That’s lovely but here’s where we run into a problem. AWS naming conventions are completely inconsistent so it’s pretty much impossible to do that. Before you decide on a naming convention take a look at the name restrictions for all the resources we created and some additional resources we plant to create:
- S3 buckets
- Lambda Functions
- Stack Names
- CloudFormation Resources, StackNames, Parameters Outputs
- CloudFormation Outputs
- IAM Users, Groups, Roles, Policies
- KMS Keys
- Key Aliases
- VPCs, Security Groups, Subnets, Route Tables
- Secrets, Parameter Store Parameters
I put this together in a spreadsheet which is a bit hard to read here but let me sum it up for you below.
If you want to use a naming convention that works across all those types of names you have one option: all lower case.
There’s one character which seems to be allowed in all resources except those inside a CloudFormation template: a dash (-).
So for everything except the resources within a CloudFormation template we can use lowercase and a dash.
For the items within a template we can use a CamelCaseNamingConvention.
Also note that many AWS resources have to start and end with a letter. That’s a bummer for my company, 2nd Sight Lab. I can’t start most resource names with a 2.
So for our batch jobs we might end up with something like this:
Of course, that is a little confusing because us-west-2 has dashes in it so we’re not really delineating the region. But at least it looks kind of consistent.
What about the resources we create like IAM roles and KMS keys. Do we want to see those associated with our batch jobs? Or do we want then name of each resource to start or end the resource it is? (role, key, user, job, lamba). In my case, I run the jobs for different customers so a key name might have a specific customer associated with it. An IAM role might be related to a specific test. So I’ll probably end up sticking with the first naming convention.
I was just creating a Lambda function to retrieve the credentials I encrypted earlier. The Lambda function name was TriggerBatchJob. I’ll probably camel case the resource name in the CloudFormation stack to keep it together but make it more readable. Likely I will drop the resource type at the end in the name of the resource.
The only thing that won’t work for would be an S3 bucket. The CloudFormation stack could remain consistent above. The S3 bucket would look something like this (dropping the resource name on the actual resource):
What about generic IAM policies? We have KMS admins and the related policy. Those aren’t associated with a particular project, class, or penetration test. We can name IAM resources not associated with a project or application with an iam prefix:
If I started hiring lots of penetration testers, developers, interns, and trainers to help me out I might add roles like this:
Those individuals would be able to assume roles for a specific penetration test, class, or development project.
I haven’t completely decided that this is the final naming convention, but that looks like it decently keeps resources together. I’ll need to do some refactoring again to try it out and make sure it works.
And for my next #awswishlist requests:
- Allow customers to use the same naming convention everywhere including uppercase letters and periods at least.
- Create something like an Azure resource group to which customers can apply policies to a group of resources and easily delete them all at once.
If you liked this story please clap and follow:
Medium: Teri Radichel or Email List: Teri Radichel
Twitter: @teriradichel or @2ndSightLab
Requests services via LinkedIn: Teri Radichel or IANS Research
© 2nd Sight Lab 2022
All the posts in this series:
Need Cloud Security Training? 2nd Sight Lab Cloud Security Training
Cybersecurity & Cloud Security Resources by Teri Radichel: Cybersecurity and Cloud security classes, articles, white papers, presentations, and podcasts