Skip to content

Commit 97616df

Browse files
author
Christopher Brandt
authored
Merge pull request #24 from cloudgraphdev/feature/CG-1056
feat(asg): add iam role connection
2 parents 5e8e82d + 06285db commit 97616df

File tree

6 files changed

+55
-2
lines changed

6 files changed

+55
-2
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
7474
| apiGatewayStage | apiGatewayRestApi |
7575
| apiGatewayResource | apiGatewayRestApi |
7676
| appSync | cognitoUserPool, dynamodb, iamRole, lambda, rdsCluster, wafV2WebAcl |
77-
| asg | ebs, ec2, securityGroup, subnet |
77+
| asg | ebs, ec2, iamRole, securityGroup, subnet |
7878
| athenaDataCatalog | |
7979
| clientVpnEndpoint | securityGroup |
8080
| cloud9 | |
@@ -124,7 +124,7 @@ CloudGraph AWS Provider will ask you what regions you would like to crawl and wi
124124
| iamServerCertificate | |
125125
| iamUser | iamGroup |
126126
| iamPolicy | iamRole, iamGroup |
127-
| iamRole | appSync, cloudformationStackSet, codebuild, configurationRecorder, ec2, iamInstanceProfile, iamPolicy, eksCluster, ecsService, flowLog, glueJob, managedAirflow, s3, sageMakerNotebookInstance, systemsManagerInstance guardDutyDetector, lambda, kinesisFirehose, rdsCluster |
127+
| iamRole | appSync, asg, cloudformationStackSet, codebuild, configurationRecorder, ec2, iamInstanceProfile, iamPolicy, eksCluster, ecsService, flowLog, glueJob, managedAirflow, s3, sageMakerNotebookInstance, systemsManagerInstance guardDutyDetector, lambda, kinesisFirehose, rdsCluster |
128128
| iamGroup | iamUser, iamPolicy |
129129
| igw | vpc |
130130
| iot | |

src/services/asg/connections.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import { SecurityGroup, Volume } from 'aws-sdk/clients/ec2'
1010
import { isEmpty } from 'lodash'
1111
import services from '../../enums/services'
1212
import { RawAwsSubnet } from '../subnet/data'
13+
import { RawAwsIamRole } from '../iamRole/data'
14+
import { globalRegionName } from '../../enums/regions'
1315

1416
/**
1517
* ASG
@@ -34,6 +36,7 @@ export default ({
3436
AutoScalingGroupARN: id,
3537
Instances: instances = [],
3638
VPCZoneIdentifier: commaSeparatedSubnetIds = '',
39+
ServiceLinkedRoleARN: roleArn,
3740
} = asg
3841

3942
const { SecurityGroups: sgIds = [] } = asg.LaunchConfiguration
@@ -142,6 +145,29 @@ export default ({
142145
}
143146
}
144147

148+
/**
149+
* Find related IAM Roles
150+
*/
151+
const roles: { name: string; data: { [property: string]: any[] } } =
152+
data.find(({ name }) => name === services.iamRole)
153+
if (roles?.data?.[globalRegionName]) {
154+
const dataAtRegion: RawAwsIamRole[] = roles.data[globalRegionName].filter(
155+
role => role.Arn === roleArn
156+
)
157+
if (!isEmpty(dataAtRegion)) {
158+
for (const instance of dataAtRegion) {
159+
const { Arn: arn }: RawAwsIamRole = instance
160+
161+
connections.push({
162+
id: arn,
163+
resourceType: services.iamRole,
164+
relation: 'child',
165+
field: 'iamRole',
166+
})
167+
}
168+
}
169+
}
170+
145171
const asgResult = {
146172
[id]: connections,
147173
}

src/services/asg/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,4 +134,5 @@ type awsAsg implements awsBaseService @key(fields: "arn") {
134134
securityGroups: [awsSecurityGroup] @hasInverse(field: asg)
135135
ebs: [awsEbs] @hasInverse(field: asg)
136136
subnet: [awsSubnet] @hasInverse(field: asg) #change to plural
137+
iamRole: [awsIamRole] @hasInverse(field: asg)
137138
}

src/services/iamRole/schema.graphql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,4 +33,5 @@ type awsIamRole implements awsBaseService @key(fields: "id") {
3333
@hasInverse(field: monitoringIamRole)
3434
rdsClusterIamRoles: [awsRdsCluster] @hasInverse(field: iamRoles)
3535
cloudFormationStackSet: [awsCloudFormationStackSet] @hasInverse(field: iamRoles)
36+
asg: [awsAsg] @hasInverse(field: iamRole)
3637
}

src/types/generated.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -472,6 +472,7 @@ export type AwsAsg = AwsBaseService & {
472472
enabledMetrics?: Maybe<Array<Maybe<AwsEnabledMetrics>>>;
473473
healthCheckGracePeriod?: Maybe<Scalars['Int']>;
474474
healthCheckType?: Maybe<Scalars['String']>;
475+
iamRole?: Maybe<Array<Maybe<AwsIamRole>>>;
475476
launchConfiguration?: Maybe<AwsLaunchConfiguration>;
476477
launchConfigurationName?: Maybe<Scalars['String']>;
477478
launchTemplateId?: Maybe<Scalars['String']>;
@@ -3048,6 +3049,7 @@ export type AwsIamPolicy = AwsBaseService & {
30483049

30493050
export type AwsIamRole = AwsBaseService & {
30503051
appSync?: Maybe<Array<Maybe<AwsAppSync>>>;
3052+
asg?: Maybe<Array<Maybe<AwsAsg>>>;
30513053
assumeRolePolicy?: Maybe<AwsIamJsonPolicy>;
30523054
cloudFormationStack?: Maybe<Array<Maybe<AwsCloudFormationStack>>>;
30533055
cloudFormationStackSet?: Maybe<Array<Maybe<AwsCloudFormationStackSet>>>;

tests/aws_asg.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import CloudGraph, { ServiceConnection } from '@cloudgraph/sdk'
33
import EC2Service from '../src/services/ec2'
44
import SGService from '../src/services/securityGroup'
55
import EBSService from '../src/services/ebs'
6+
import IAMRoleService from '../src/services/iamRole'
67
import AsgClass from '../src/services/asg'
78
import { RawAwsAsg } from '../src/services/asg/data'
89
import { initTestConfig } from '../src/utils'
@@ -26,6 +27,7 @@ describe.skip('ASG Service Test: ', () => {
2627
const ec2Class = new EC2Service({ logger: CloudGraph.logger })
2728
const sgService = new SGService({ logger: CloudGraph.logger })
2829
const ebsService = new EBSService({ logger: CloudGraph.logger })
30+
const iamRoleService = new IAMRoleService({ logger: CloudGraph.logger })
2931

3032
getDataResult = await asgClass.getData({
3133
credentials,
@@ -52,6 +54,12 @@ describe.skip('ASG Service Test: ', () => {
5254
regions: region,
5355
})
5456

57+
// Get IAM Role data
58+
const iamRoleData = await iamRoleService.getData({
59+
credentials,
60+
regions: region,
61+
})
62+
5563
const [asg] = getDataResult[region]
5664
asgId = asg.AutoScalingGroupARN
5765

@@ -76,6 +84,12 @@ describe.skip('ASG Service Test: ', () => {
7684
account,
7785
region,
7886
},
87+
{
88+
name: services.iamRole,
89+
data: iamRoleData,
90+
account,
91+
region,
92+
}
7993
],
8094
region,
8195
})
@@ -150,5 +164,14 @@ describe.skip('ASG Service Test: ', () => {
150164
expect(ebsConnections).toBeDefined()
151165
expect(ebsConnections.length).toBe(1)
152166
})
167+
168+
test('should verify the connection to iam', async () => {
169+
const iamConnections = asgConnections[asgId].filter(
170+
connection => connection.resourceType === services.iamRole
171+
)
172+
173+
expect(iamConnections).toBeDefined()
174+
expect(iamConnections.length).toBe(1)
175+
})
153176
})
154177
})

0 commit comments

Comments
 (0)