New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add config option for complex matching against s3 buckets #113
Conversation
IIRC,
Given that, I think it would probably be better to repeat the args for each subcommand for CLI consistency. |
@yorinasub17 Updated the description to reflect that. Thanks for explaining why that's important. |
Yaml makes sense to me!
I prefer being more explicit, e.g.
|
NIT:
|
So, the yaml format could be something like this:
Maybe we assume plaintext matching if they only specify About the ec2_instance:
include_tags_regex:
- ^test_.* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like a good start! I think having this in a config file makes sense and being able to specify regions would be useful. I could use a bit more clarification around the edge cases though, as mentioned in the comments below.
Well, tags are key-value pairs so what you want to do is filter by tags that match keys and values. So you either need to be specific about matching the tag keys (which I think is what you were going for in the alternative proposal), or matching values of specific tags (which is what I was going for in my suggestion). Does that make sense? EDIT: To put another way, I think you need two kinds of tags filters. One for matching keys, and one for matching the key-value pair. This is similar to the AWS filters system. |
I think assuming |
Okay, I get it now about the key-value pair matching, for tags. Updating the description now. |
Supporting I think everything else feels consistent enough. Let me know if we want to move forward with implementing something for nuking s3 buckets by name. |
+1 to focusing on just the s3 names filter and punting on supporting regions! |
@yorinasub17 Okay! Great. Updated the description with what we've discussed. |
The updated description LGTM! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Implementation looks like a good start! Had one minor suggestion in terms of organization but overall the end to end direction looks good.
Global style nit: Use go fmt
to format the code to be consistent with the rest of the repo (e.g., consistent tabbing).
@yorinasub17 Thanks so much for your comments! I don't have time to take care of those concerns at the moment. But they will be helpful for the future. I've updated the PR description with wrap-up comments (collapsed in a Summary). 🎉 Thanks, all! |
|
Co-authored-by: Yevgeniy Brikman <brikis98@users.noreply.github.com>
@brikis98 @yorinasub17 Could use another review, possibly someone to pull and run this, too. I noticed we can't delete s3 buckets that have no region, such as the two buckets that are currently stuck in our nuclear wasteland account. Even the AWS UI doesn't let me delete them. |
Happy to guinea pig this at some point. I haven't used cloud-nuke yet so it would be good learning for me. LMK if there are specific configs / accounts you'd like flexed! |
@zackproser I'm using the nuclear wasteland account, and if you look at s3_test.go, search for I'd love if we found a config file that actually breaks functionality. I have updated the description to describe how to pull and run and test this out! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Only had minor nits regarding testing, and one feature improvement for the future.
Let me kick off a build now so you get one test cycle. I'll give you the instructions for kicking off forks in slack.
|
||
if !reflect.DeepEqual(configObj, emptyConfig()) { | ||
assert.Fail(t, "Config should be empty, %+v\n", configObj) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not for this PR, but perhaps in the next iteration we should look into seeing if this can be thrown as an error? It would be useful to catch typos (e.g., if I mistyped include
, I would want it to give me an error than move along as if it didn't exist!)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this would be awesome. Any unparseable key in the config file should raise an informative error.
Looks like the CI build failed on
This runs in phxdevops, so perhaps there's a bucket in there that is matching? |
When I run this locally against phxdevops there are 191 buckets matching houston exec dev -- go run main.go aws --resource-type s3 --dry-run \
--config config/mocks/s3_exclude_names.yaml |
Just fyi, we are running against the sandbox account, I believe. Unless these labels are wrong..
|
This last test run passed. Rerunning. |
Running these tests locally against both phxdevops and sandbox. e.g.: cd cloud-nuke/aws
houston exec sandbox -- go test -v -run TestFilterS3
houston exec phx -- go test -v -run TestFilterS3 Okay, figured it out. It's related to which random region is chosen to create these test buckets and filter against. So we need to choose a non-random region for this test, or else first nuke all test buckets in whatever random region the test chooses. |
Thanks for updating with testing instructions! Just a quick update to say the happy paths you specified are working for me and I had zero issues running this against |
// Create test buckets | ||
awsParams, err := newS3TestAWSParams() | ||
// Create AWS session in ca-central-1 | ||
awsParams, err := newS3TestAWSParams("ca-central-1") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hardcode the region for this test only.
cleanupBuckets, err := getAllS3Buckets(awsParams.awsSession, time.Now().Add(1*time.Hour), []string{awsParams.region}, "", 100, *configObj) | ||
require.NoError(t, err, "Failed to list S3 Buckets in ca-central-1") | ||
|
||
nukeAllS3Buckets(awsParams.awsSession, cleanupBuckets[awsParams.region], 1000) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there another way to do this other than 1. list all the buckets, 2. nuke the listed buckets?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIK, this is the model of how cloud nuke works, so unfortunately, no this is the only way for now.
Addresses #108
Purpose
Allow terminating AWS resources via more complex matching rules via a config file.
Scope
This PR is scoped to support nuking s3 buckets based on matching by name.
CLI changes
I propose we allow something like this:
Yaml config format
The structure of the config should reflect the way AWS describes resources. S3 buckets have names and regions, so for the scope of this project:
The proposed format at a meta level is this:
where
resource_type
can bes3
,iam_role
, etc. We are punting on supportingregion
for now.include
has rules that a resource must match to be nukedexclude
has rules that a resource must not match to be nukedtags_regex
: would accept a list of regular expressionsnames_regex
: would accept a list of regular expressionsregions
(assumes plaintext, exact matching)ec2_instance
, we need to support key-value mapsName: ^test_.*
Looking Ahead
[expand]
Eventually, we might support something like:
The following would nuke only s3 buckets matching the
names_regex
but that are not inus-west-1
, if called withcloud-nuke aws --resource-type s3 --config path/to/config.yaml
:How to test locally
[expand]
go run main.go aws --resource-type s3 --config config/mocks/s3_cleanup.yaml
resource-type
optionconfig
optionSummary of trial project
[expand]
Notably completed today:
--config path/to/file.yaml
support to the command line.go run main.go aws
: nuke all s3 bucketsgo run main.go aws --config ./config/mocks/s3_include_names.yaml
: nuke only s3 buckets in all regions that match any of the regexps.go run main.go aws --config ./config/mocks/s3_include_names.yaml --region us-east-1
: nuke only s3 buckets in us-east-1 that match any of the regexps.Notably not done:
config/config_test.go
exclude_names_regex
,exclude_names
, andinclude_names
.Of course this is still far from complete, but might set some ground work for the future. There are still a few TODOs in the code that signal what might be worth checking. One caveat to mention: I haven't written
go
in years and was never an expert, so some of the conventions might be lost on me. (But that doesn't make it any less fun for me!)