Skip to content

Commit

Permalink
Merge pull request #375 from ekristen/oct-various-changes
Browse files Browse the repository at this point in the history
feat: various fixes and features - october
  • Loading branch information
ekristen authored Oct 14, 2024
2 parents 103715b + dced127 commit 5d5a720
Show file tree
Hide file tree
Showing 15 changed files with 392 additions and 31 deletions.
107 changes: 107 additions & 0 deletions docs/config-contrib.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Config Contributions

## Community Presets

These are a collection of presets from the community.

!!! warning
These presets are built from feedback from the community, they are not routinely tested. Use at your own risk.

### Filter SSO Resources

This is a preset to filter out AWS SSO resources.

```yaml
presets:
sso:
filters:
IAMSAMLProvider:
- type: "regex"
value: "AWSSSO_.*_DO_NOT_DELETE"
IAMRole:
- type: "glob"
value: "AWSReservedSSO_*"
IAMRolePolicyAttachment:
- type: "glob"
value: "AWSReservedSSO_*"
```
### Filter Control Tower
This is a preset to filter out AWS Control Tower resources.
```yaml
presets:
controltower:
filters:
CloudTrailTrail:
- type: "contains"
value: "aws-controltower"
CloudWatchEventsRule:
- type: "contains"
value: "aws-controltower"
- property: "Name"
type: glob
value: "AWSControlTower*"
EC2VPCEndpoint:
- type: "contains"
value: "aws-controltower"
EC2VPC:
- type: "contains"
value: "aws-controltower"
OpsWorksUserProfile:
- type: "contains"
value: "AWSControlTowerExecution"
CloudWatchLogsLogGroup:
- type: "contains"
value: "aws-controltower"
- type: "contains"
value: "AWSControlTowerBP"
CloudWatchEventsTarget:
- type: "contains"
value: "aws-controltower"
- type: "glob"
value: "Rule: AWSControlTower*"
SNSSubscription:
- type: "contains"
value: "aws-controltower"
SNSTopic:
- type: "contains"
value: "aws-controltower"
EC2Subnet:
- type: "contains"
value: "aws-controltower"
ConfigServiceDeliveryChannel:
- type: "contains"
value: "aws-controltower"
ConfigServiceConfigurationRecorder:
- type: "contains"
value: "aws-controltower"
CloudFormationStack:
- type: "contains"
value: "AWSControlTower"
EC2RouteTable:
- type: "contains"
value: "aws-controltower"
LambdaFunction:
- type: "contains"
value: "aws-controltower"
EC2DHCPOption:
- type: "contains"
value: "aws-controltower"
IAMRole:
- type: "contains"
value: "aws-controltower"
- type: "contains"
value: "AWSControlTower"
IAMRolePolicyAttachment:
- type: "contains"
value: "aws-controltower"
- type: "contains"
value: "AWSControlTower"
IAMRolePolicy:
- type: "contains"
value: "aws-controltower"
- type: glob
value: "AWSReservedSSO_*"
```
36 changes: 36 additions & 0 deletions docs/resources/ec2-image.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# EC2 Image

This will remove all EC2 Images (AMI) in an AWS account.

## Resource

```text
EC2Image
```

## Settings

- `IncludeDisabled`
- `IncludeDeprecated`
- `DisableDeregistrationProtection`

### IncludeDisabled

This will include any EC2 Images (AMI) that are disabled in the deletion process. By default, disabled images are excluded
from the discovery process.

Default is `false`.

### IncludeDeprecated

This will include any EC2 Images (AMI) that are deprecated in the deletion process. By default, deprecated images are excluded
from the discovery process.

Default is `false`.

### DisableDeregistrationProtection

This will disable the deregistration protection on the EC2 Image (AMI) prior to deletion. By default, deregistration protection
is not disabled.

Default is `false`.
6 changes: 6 additions & 0 deletions docs/resources/iam-role.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

This will remove all IAM Roles an AWS account.

## Resource

```text
IAMRole
```

## Settings

- `IncludeServiceLinkedRoles`
Expand Down
5 changes: 5 additions & 0 deletions docs/resources/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Resources Overview

This is the start of the documentation for all resources handled by aws-nuke. Eventually each resource will have its own
page with detailed information on how to use it, what settings are available, and what the resource does.

6 changes: 6 additions & 0 deletions docs/resources/s3-bucket.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@ This will remove all S3 buckets from an AWS account. The following actions are p
- This will include bypassing any Object Lock governance retention settings if the `BypassGovernanceRetention`
setting is set to `true`

## Resource

```text
S3Bucket
```

## Settings

- `BypassGovernanceRetention`
Expand Down
22 changes: 22 additions & 0 deletions docs/resources/s3-object.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# S3Object

!!! warning
**You should exclude this resource by default.** Not doing so can lead to deadlocks and hung runs of the tool. In
the next major version of aws-nuke, this resource will be excluded by default.

!!! important
This resource is **NOT** required to remove a [S3Bucket](./s3-bucket.md). The `S3Bucket` resource will remove all
objects in the bucket as part of the deletion process using a batch removal process.

This removes all objects from S3 buckets in an AWS account while retaining the S3 bucket itself. This resource is
useful if you want to remove a single object from a bucket, or a subset of objects without removing the entire bucket.

## Resource

```text
S3Object
```

## Settings

**No settings available.**
4 changes: 4 additions & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,14 @@ nav:
- Presets: config-presets.md
- Custom Endpoints: config-custom-endpoints.md
- Migration Guide: config-migration.md
- Examples & Presets: config-contrib.md
- Resources:
- Overview: resources/overview.md
- Cognito User Pool: resources/cognito-user-pool.md
- EC2 Image: resources/ec2-image.md
- IAM Role: resources/iam-role.md
- S3 Bucket: resources/s3-bucket.md
- S3 Object: resources/s3-object.md
- Development:
- Overview: development.md
- Contributing: contributing.md
Expand Down
10 changes: 10 additions & 0 deletions resources/apigateway-api-key.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"time"

"go.uber.org/ratelimit"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/apigateway"

Expand All @@ -16,6 +18,12 @@ import (

const APIGatewayAPIKeyResource = "APIGatewayAPIKey"

// Rate limit to avoid throttling when deleting API Gateway Rest APIs
// The API Gateway Delete Rest API has a limit of 1 request per 30 seconds for each account
// https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html
// Note: due to time drift, set to 31 seconds to be safe.
var deleteAPIKeyLimit = ratelimit.New(1, ratelimit.Per(32*time.Second))

func init() {
registry.Register(&registry.Registration{
Name: APIGatewayAPIKeyResource,
Expand Down Expand Up @@ -72,6 +80,8 @@ type APIGatewayAPIKey struct {
}

func (r *APIGatewayAPIKey) Remove(_ context.Context) error {
deleteAPIKeyLimit.Take()

_, err := r.svc.DeleteApiKey(&apigateway.DeleteApiKeyInput{
ApiKey: r.apiKey,
})
Expand Down
10 changes: 10 additions & 0 deletions resources/apigateway-restapis.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"time"

"go.uber.org/ratelimit"

"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/apigateway"

Expand All @@ -16,6 +18,12 @@ import (

const APIGatewayRestAPIResource = "APIGatewayRestAPI"

// Rate limit to avoid throttling when deleting API Gateway Rest APIs
// The API Gateway Delete Rest API has a limit of 1 request per 30 seconds for each account
// https://docs.aws.amazon.com/apigateway/latest/developerguide/limits.html
// Note: due to time drift, set to 31 seconds to be safe.
var deleteRestAPILimit = ratelimit.New(1, ratelimit.Per(32*time.Second))

func init() {
registry.Register(&registry.Registration{
Name: APIGatewayRestAPIResource,
Expand Down Expand Up @@ -73,6 +81,8 @@ func (l *APIGatewayRestAPILister) List(_ context.Context, o interface{}) ([]reso
}

func (f *APIGatewayRestAPI) Remove(_ context.Context) error {
deleteRestAPILimit.Take()

_, err := f.svc.DeleteRestApi(&apigateway.DeleteRestApiInput{
RestApiId: f.restAPIID,
})
Expand Down
39 changes: 17 additions & 22 deletions resources/ec2-eip.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@ package resources
import (
"context"

"github.com/gotidy/ptr"

"github.com/aws/aws-sdk-go/service/ec2"

"github.com/ekristen/libnuke/pkg/registry"
Expand Down Expand Up @@ -40,26 +38,28 @@ func (l *EC2AddressLister) List(_ context.Context, o interface{}) ([]resource.Re
resources := make([]resource.Resource, 0)
for _, out := range resp.Addresses {
resources = append(resources, &EC2Address{
svc: svc,
eip: out,
id: ptr.ToString(out.AllocationId),
ip: ptr.ToString(out.PublicIp),
svc: svc,
AllocationID: out.AllocationId,
PublicIP: out.PublicIp,
Tags: out.Tags,
})
}

return resources, nil
}

type EC2Address struct {
svc *ec2.EC2
eip *ec2.Address
id string
ip string
svc *ec2.EC2
AllocationID *string
PublicIP *string
NetworkBorderGroup *string
Tags []*ec2.Tag
}

func (e *EC2Address) Remove(_ context.Context) error {
_, err := e.svc.ReleaseAddress(&ec2.ReleaseAddressInput{
AllocationId: &e.id,
func (r *EC2Address) Remove(_ context.Context) error {
_, err := r.svc.ReleaseAddress(&ec2.ReleaseAddressInput{
AllocationId: r.AllocationID,
NetworkBorderGroup: r.NetworkBorderGroup,
})
if err != nil {
return err
Expand All @@ -68,15 +68,10 @@ func (e *EC2Address) Remove(_ context.Context) error {
return nil
}

func (e *EC2Address) Properties() types.Properties {
properties := types.NewProperties()
for _, tagValue := range e.eip.Tags {
properties.SetTag(tagValue.Key, tagValue.Value)
}
properties.Set("AllocationID", e.id)
return properties
func (r *EC2Address) Properties() types.Properties {
return types.NewPropertiesFromStruct(r)
}

func (e *EC2Address) String() string {
return e.ip
func (r *EC2Address) String() string {
return *r.PublicIP
}
12 changes: 12 additions & 0 deletions resources/kms-key.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,17 @@ func (l *KMSKeyLister) List(_ context.Context, o interface{}) ([]resource.Resour
}
}

keyAliases, err := svc.ListAliases(&kms.ListAliasesInput{
KeyId: key.KeyId,
})
if err != nil {
logrus.WithError(err).Error("unable to list aliases")
}

if len(keyAliases.Aliases) > 0 {
kmsKey.Alias = keyAliases.Aliases[0].AliasName
}

resources = append(resources, kmsKey)
}

Expand All @@ -118,6 +129,7 @@ type KMSKey struct {
ID *string
State *string
Manager *string
Alias *string
Tags []*kms.Tag
}

Expand Down
Loading

0 comments on commit 5d5a720

Please sign in to comment.