Skip to content

Commit

Permalink
feat(aws): scrape cloudformation stacks
Browse files Browse the repository at this point in the history
  • Loading branch information
adityathebe committed Jul 2, 2024
1 parent 200f585 commit 61c1ed8
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 28 deletions.
57 changes: 29 additions & 28 deletions api/v1/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,34 +43,35 @@ type CostReporting struct {
}

const (
AWSECSCluster = "AWS::ECS::Cluster"
AWSECSService = "AWS::ECS::Service"
AWSECSTaskDefinition = "AWS::ECS::TaskDefinition"
AWSEKSFargateProfile = "AWS::EKS::FargateProfile"
AWSElastiCacheCluster = "AWS::ElastiCache::CacheCluster"
AWSLambdaFunction = "AWS::Lambda::Function"
AWSSNSTopic = "AWS::SNS::Topic"
AWSSQS = "AWS::SQS::Queue"
AWSRegion = "AWS::Region"
AWSZone = "AWS::Route53::HostedZone"
AWSEC2Instance = "AWS::EC2::Instance"
AWSEKSCluster = "AWS::EKS::Cluster"
AWSS3Bucket = "AWS::S3::Bucket"
AWSLoadBalancer = "AWS::ElasticLoadBalancing::LoadBalancer"
AWSLoadBalancerV2 = "AWS::ElasticLoadBalancingV2::LoadBalancer"
AWSEBSVolume = "AWS::EBS::Volume"
AWSRDSInstance = "AWS::RDS::DBInstance"
AWSEC2VPC = "AWS::EC2::VPC"
AWSEC2Subnet = "AWS::EC2::Subnet"
AWSAccount = "AWS::::Account"
AWSAvailabilityZone = "AWS::AvailabilityZone"
AWSAvailabilityZoneID = "AWS::AvailabilityZoneID"
AWSEC2SecurityGroup = "AWS::EC2::SecurityGroup"
AWSIAMUser = "AWS::IAM::User"
AWSIAMRole = "AWS::IAM::Role"
AWSIAMInstanceProfile = "AWS::IAM::InstanceProfile"
AWSEC2AMI = "AWS::EC2::AMI"
AWSEC2DHCPOptions = "AWS::EC2::DHCPOptions"
AWSCloudFormationStack = "AWS::CloudFormation::Stack"
AWSECSCluster = "AWS::ECS::Cluster"
AWSECSService = "AWS::ECS::Service"
AWSECSTaskDefinition = "AWS::ECS::TaskDefinition"
AWSEKSFargateProfile = "AWS::EKS::FargateProfile"
AWSElastiCacheCluster = "AWS::ElastiCache::CacheCluster"
AWSLambdaFunction = "AWS::Lambda::Function"
AWSSNSTopic = "AWS::SNS::Topic"
AWSSQS = "AWS::SQS::Queue"
AWSRegion = "AWS::Region"
AWSZone = "AWS::Route53::HostedZone"
AWSEC2Instance = "AWS::EC2::Instance"
AWSEKSCluster = "AWS::EKS::Cluster"
AWSS3Bucket = "AWS::S3::Bucket"
AWSLoadBalancer = "AWS::ElasticLoadBalancing::LoadBalancer"
AWSLoadBalancerV2 = "AWS::ElasticLoadBalancingV2::LoadBalancer"
AWSEBSVolume = "AWS::EBS::Volume"
AWSRDSInstance = "AWS::RDS::DBInstance"
AWSEC2VPC = "AWS::EC2::VPC"
AWSEC2Subnet = "AWS::EC2::Subnet"
AWSAccount = "AWS::::Account"
AWSAvailabilityZone = "AWS::AvailabilityZone"
AWSAvailabilityZoneID = "AWS::AvailabilityZoneID"
AWSEC2SecurityGroup = "AWS::EC2::SecurityGroup"
AWSIAMUser = "AWS::IAM::User"
AWSIAMRole = "AWS::IAM::Role"
AWSIAMInstanceProfile = "AWS::IAM::InstanceProfile"
AWSEC2AMI = "AWS::EC2::AMI"
AWSEC2DHCPOptions = "AWS::EC2::DHCPOptions"
)

func (aws AWS) Includes(resource string) bool {
Expand Down
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ require (
github.com/aws/aws-sdk-go-v2 v1.18.0
github.com/aws/aws-sdk-go-v2/config v1.18.25
github.com/aws/aws-sdk-go-v2/credentials v1.13.24
github.com/aws/aws-sdk-go-v2/service/cloudformation v1.26.6
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.24.4
github.com/aws/aws-sdk-go-v2/service/configservice v1.30.1
github.com/aws/aws-sdk-go-v2/service/ec2 v1.92.1
Expand Down
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,8 @@ github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34 h1:gGLG7yKaXG02/jBlg210R7VgQIo
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34/go.mod h1:Etz2dj6UHYuw+Xw830KfzCfWGMzqvUTCjUj5b76GVDc=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.25 h1:AzwRi5OKKwo4QNqPf7TjeO+tK8AyOK3GVSwmRPo7/Cs=
github.com/aws/aws-sdk-go-v2/internal/v4a v1.0.25/go.mod h1:SUbB4wcbSEyCvqBxv/O/IBf93RbEze7U7OnoTlpPB+g=
github.com/aws/aws-sdk-go-v2/service/cloudformation v1.26.6 h1:vCcKEElNC5rJtgYtoUm6pimyJgfM6LWVyMgWzNkrovY=
github.com/aws/aws-sdk-go-v2/service/cloudformation v1.26.6/go.mod h1:YxmrPfRqDEQ1pD7c+iGkrZoTHsN4vyL+uA2lPYcXzE4=
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.24.4 h1:4n6EhYGGPyNHffNcz1glTQWa7jU5yLfCgDCb2fmXPno=
github.com/aws/aws-sdk-go-v2/service/cloudtrail v1.24.4/go.mod h1:qv5TNLKArfckMdJqnZ2Wy6DiZBoYbn8OXhf6Si1IUGg=
github.com/aws/aws-sdk-go-v2/service/configservice v1.30.1 h1:DhsNbCEiM8JJ2YiilbKrt3XCq+mbOLX9vTk1P54F/ug=
Expand Down
37 changes: 37 additions & 0 deletions scrapers/aws/aws.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (

"github.com/Jeffail/gabs/v2"
"github.com/aws/aws-sdk-go-v2/aws"
"github.com/aws/aws-sdk-go-v2/service/cloudformation"
"github.com/aws/aws-sdk-go-v2/service/configservice"
ec2 "github.com/aws/aws-sdk-go-v2/service/ec2"
ec2Types "github.com/aws/aws-sdk-go-v2/service/ec2/types"
Expand Down Expand Up @@ -183,6 +184,39 @@ func (aws Scraper) sqs(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResults
}
}

func (aws Scraper) cloudformationStacks(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResults) {
if !config.Includes("cloudformation") {
return
}

ctx.Logger.V(2).Infof("scraping CloudFormation stacks")

client := cloudformation.NewFromConfig(*ctx.Session)
stacks, err := client.ListStacks(ctx, &cloudformation.ListStacksInput{})
if err != nil {
results.Errorf(err, "failed to list CloudFormation stacks")
return
}

for _, stack := range stacks.StackSummaries {
stackName := lo.FromPtr(stack.StackName)

*results = append(*results, v1.ScrapeResult{
Type: v1.AWSCloudFormationStack,
BaseScraper: config.BaseScraper,
Properties: []*types.Property{getConsoleLink(ctx.Session.Region, v1.AWSCloudFormationStack, stackName)},
Config: stack,
Status: string(stack.StackStatus),
DeletedAt: stack.DeletionTime,
DeleteReason: v1.DeletedReasonFromAttribute,
ConfigClass: "Stack",
Name: stackName,
ID: stackName,
Parents: []v1.ConfigExternalKey{{Type: v1.AWSAccount, ExternalID: lo.FromPtr(ctx.Caller.Account)}},
})
}
}

func (aws Scraper) snsTopics(ctx *AWSContext, config v1.AWS, results *v1.ScrapeResults) {
if !config.Includes("sns") {
return
Expand Down Expand Up @@ -1528,6 +1562,7 @@ func (aws Scraper) Scrape(ctx api.ScrapeContext) v1.ScrapeResults {
}

ctx.Logger.V(1).Infof("scraping %s", awsCtx)
aws.cloudformationStacks(awsCtx, awsConfig, results)
aws.ecsClusters(awsCtx, awsConfig, results)
aws.ecsTasks(awsCtx, awsConfig, results)
aws.elastiCache(awsCtx, awsConfig, results)
Expand Down Expand Up @@ -1616,6 +1651,8 @@ func getConsoleLink(region, resourceType, resourceID string) *types.Property {

var url string
switch resourceType {
case v1.AWSCloudFormationStack:
url = fmt.Sprintf("https://%s.console.aws.amazon.com/cloudformation/home?region=%s#/stacks/detail/%s", region, region, resourceID)
case v1.AWSEKSFargateProfile:
url = fmt.Sprintf("https://%s.console.aws.amazon.com/ecs/home?region=%s#/clusters/%s/fargate-profiles/%s", region, region, resourceID, resourceID)
case v1.AWSECSTaskDefinition:
Expand Down

0 comments on commit 61c1ed8

Please sign in to comment.