--- policy: /ce/ca/aws/ec2/instance-iam-role logic: /ce/ca/aws/ec2/instance-iam-role/prod.logic.yaml executionTime: 2026-06-06T12:02:43.029984626Z generationMs: 52 executionMs: 992 rows: - id: a01 match: true status: expected: DISAPPEARED actual: DISAPPEARED conditionIndex: expected: 99 actual: 99 conditionText: expected: isDisappeared(CA10__disappearanceTime__c) actual: isDisappeared(CA10__disappearanceTime__c) runtimeError: {} - id: a02 match: true status: expected: COMPLIANT actual: COMPLIANT conditionIndex: expected: 199 actual: 199 conditionText: expected: CA10A1__iamInstanceProfile__r.CA10A1__roleArn__c.isNotEmpty() actual: CA10A1__iamInstanceProfile__r.CA10A1__roleArn__c.isNotEmpty() runtimeError: {} - id: a03 match: true status: expected: INCOMPLIANT actual: INCOMPLIANT conditionIndex: expected: 200 actual: 200 conditionText: expected: otherwise actual: otherwise runtimeError: {} - id: a04 match: true status: expected: INCOMPLIANT actual: INCOMPLIANT conditionIndex: expected: 200 actual: 200 conditionText: expected: otherwise actual: otherwise runtimeError: {} usedFiles: - path: /ce/ca/aws/ec2/instance-iam-role/policy.yaml md5Hash: 8B476A80EC6CEE47EA33466C9F52F67E content: | --- names: full: AWS EC2 Instance IAM role is not attached contextual: Instance IAM role is not attached description: AWS access from within AWS instances can be done by either encoding AWS keys into AWS API calls or by assigning the instance to a role which has an appropriate permissions policy for the required access. 'AWS Access' means accessing the APIs of AWS in order to access AWS resources or manage AWS account resources. type: COMPLIANCE_POLICY categories: - SECURITY frameworkMappings: - "/frameworks/cis-aws-v7.0.0/02/16" - "/frameworks/cloudaware/resource-security/secure-access" - "/frameworks/aws-well-architected/cost/02/04" similarPolicies: internal: - dec-x-6c93750d cloudConformity: - url: https://www.trendmicro.com/cloudoneconformity-staging/knowledge-base/aws/EC2/ec2-instance-using-iam-roles.html name: EC2 Instance Using IAM Roles - path: /ce/ca/aws/ec2/instance-iam-role/prod.logic.yaml md5Hash: D50B710C30333B670D1C9A6E7C454FFE content: | --- inputType: "CA10__CaAwsInstance__c" testData: - file: test-data.json importExtracts: - file: /types/CA10__CaAwsInstance__c/object.extracts.yaml conditions: - status: "COMPLIANT" currentStateMessage: "The instance has an IAM role attached through its instance profile." check: NOT_EMPTY: arg: FIELD: path: "CA10A1__iamInstanceProfile__r.CA10A1__roleArn__c" otherwise: status: "INCOMPLIANT" currentStateMessage: "The instance does not have an IAM role attached." remediationMessage: "Attach an IAM role to the instance." - path: /ce/ca/aws/ec2/instance-iam-role/test-data.json md5Hash: 82158A0BAC6C4A61DE1FFDDCF0ED5C35 content: | [ { "expectedResult": { "status": "DISAPPEARED", "conditionIndex": "99", "conditionText": "isDisappeared(CA10__disappearanceTime__c)", "runtimeError": null }, "context": { "snapshotTime": "2024-06-19T07:55:48Z" }, "Id": "a01", "CA10__disappearanceTime__c": "2024-06-18T13:02:29Z", "CA10__iamInstanceProfileArn__c": "", "CA10A1__iamInstanceProfile__c": null, "CA10A1__iamInstanceProfile__r": { "Id": null, "CA10A1__disappearanceTime__c": null, "CA10A1__role__c": null, "CA10A1__role__r": { "Id": null, "CA10__disappearanceTime__c": null } } }, { "expectedResult": { "status": "COMPLIANT", "conditionIndex": "199", "conditionText": "CA10A1__iamInstanceProfile__r.CA10A1__roleArn__c.isNotEmpty()", "runtimeError": null }, "context": { "snapshotTime": "2024-06-19T07:55:48Z" }, "Id": "a02", "CA10__disappearanceTime__c": null, "CA10__iamInstanceProfileArn__c": "arn:aws:iam::1234567890:instance-profile/ProfileArn", "CA10A1__iamInstanceProfile__c": "profile1", "CA10A1__iamInstanceProfile__r": { "Id": "profile1", "CA10A1__disappearanceTime__c": null, "CA10A1__role__c": "role1", "CA10A1__roleArn__c": "arn:aws:iam::1234567890:role/role1", "CA10A1__role__r": { "Id": "role1", "CA10__disappearanceTime__c": null } } }, { "expectedResult": { "status": "INCOMPLIANT", "conditionIndex": "200", "conditionText": "otherwise", "runtimeError": null }, "context": { "snapshotTime": "2024-06-19T07:55:48Z" }, "Id": "a03", "CA10__disappearanceTime__c": null, "CA10__iamInstanceProfileArn__c": "arn:aws:iam::1234567890:instance-profile/ProfileWithoutRoleArn", "CA10A1__iamInstanceProfile__c": "profile2", "CA10A1__iamInstanceProfile__r": { "Id": "profile2", "CA10A1__disappearanceTime__c": null, "CA10A1__role__c": null, "CA10A1__roleArn__c": "", "CA10A1__role__r": { "Id": null, "CA10__disappearanceTime__c": null } } }, { "expectedResult": { "status": "INCOMPLIANT", "conditionIndex": "200", "conditionText": "otherwise", "runtimeError": null }, "context": { "snapshotTime": "2024-06-19T07:55:48Z" }, "Id": "a04", "CA10__disappearanceTime__c": null, "CA10__iamInstanceProfileArn__c": "", "CA10A1__iamInstanceProfile__c": null, "CA10A1__iamInstanceProfile__r": { "Id": null, "CA10A1__disappearanceTime__c": null, "CA10A1__role__c": null, "CA10A1__roleArn__c": "", "CA10A1__role__r": { "Id": null, "CA10__disappearanceTime__c": null } } } ] - path: /types/CA10__CaAwsInstance__c/object.extracts.yaml md5Hash: 91EF62776BC2E60A02CA42F4B2811688 content: "---\nextracts:\n# Values pending, applied. Not nullable. Can't have\ \ no access, retrieved via ec2:DescribeInstances\n - name: \"CA10__metadataState__c\"\ \n value: \n FIELD:\n path: \"CA10__metadataState__c\"\n \ \ undeterminedIf:\n isEmpty: \"Corrupted data. EC2 Instances Metadata\ \ State cannot be empty.\"\n# Values: optional, required. Not nullable. Can't\ \ have no access, retrieved via ec2:DescribeInstances\n - name: \"CA10__metadataHttpTokens__c\"\ \n value: \n FIELD:\n path: \"CA10__metadataHttpTokens__c\"\n\ \ undeterminedIf:\n isEmpty: \"Corrupted data. EC2 Instances\ \ Metadata Http Token cannot be empty.\"\n - name: CA10__iamInstanceProfileArn__c\n\ \ value:\n FIELD: \n path: CA10__iamInstanceProfileArn__c\n#\ \ Nullable. Can't have no access, retrieved via ec2:DescribeInstances\n - name:\ \ \"CA10__publicIpAddress__c\"\n value: \n FIELD:\n path: \"\ CA10__publicIpAddress__c\"\n# Values: enabled, disabled. Not nullable. Can't\ \ have no access, retrieved via ec2:DescribeInstances\n - name: \"CA10__monitoringState__c\"\ \n value: \n FIELD:\n path: \"CA10__monitoringState__c\"\n \ \ undeterminedIf:\n isEmpty: \"Corrupted data. EC2 Instances Detailed\ \ Monitoring State cannot be empty.\"\n# Values: pending | running | shutting-down\ \ | terminated | stopping | stopped. Not nullable.\n - name: \"CA10__stateName__c\"\ \n value: \n FIELD:\n path: \"CA10__stateName__c\"\n undeterminedIf:\n\ \ noAccessDelegate:\n path: \"CA10__stateName__c\"\n \ \ currentStateMessage: \"Unable to determine EC2 Instances State Name.\ \ Possible permission issue with ec2:DescribeInstanceStatus\"\n# Number of Days.\ \ Nullable. Can't have no access, retrieved via ec2:DescribeInstances\n - name:\ \ \"CA10__currentRunningTime__c\"\n value: \n FIELD:\n path:\ \ \"CA10__currentRunningTime__c\" \n# Nullable.\n - name: \"CA10__averageCpuTwoWeeks__c\"\ \n value: \n FIELD:\n path: \"CA10__averageCpuTwoWeeks__c\" \ \ \n# Nullable.\n - name: \"CA10__maxCpuTwoWeeks__c\"\n value: \n \ \ FIELD:\n path: \"CA10__maxCpuTwoWeeks__c\" \n# Nullable.\n\ \ - name: \"CA10__sumTwoWeekNetworkOutMb__c\"\n value: \n FIELD:\n\ \ path: \"CA10__sumTwoWeekNetworkOutMb__c\" \n# Nullable.\n - name:\ \ \"CA10__sumTwoWeekNetworkInMb__c\"\n value: \n FIELD:\n path:\ \ \"CA10__sumTwoWeekNetworkInMb__c\" \n # Nullable.\n - name: \"CA10N__newRelicHost__c\"\ \n value:\n FIELD:\n path: \"CA10N__newRelicHost__c\"\n # Nullable.\ \ \n - name: \"CA10N__newRelicHostCpuUsed__c\"\n value:\n FIELD:\n\ \ path: \"CA10N__newRelicHostCpuUsed__c\"\n # Nullable.\n - name: \"\ CA10N__newRelicHostMemoryUsed14Day__c\"\n value:\n FIELD:\n path:\ \ \"CA10N__newRelicHostMemoryUsed14Day__c\"\n # Nullable.\n - name: \"CA10__averageMemoryUsedTwoWeeks__c\"\ \n value:\n FIELD:\n path: \"CA10__averageMemoryUsedTwoWeeks__c\"\ \n # Nullable.\n - name: \"CA10__nagiosMemoryUtilization__c\"\n value:\n\ \ FIELD:\n path: \"CA10__nagiosMemoryUtilization__c\"\n # Nullable.\n\ \ - name: \"CA10N__newRelicHostDiskUtilization__c\"\n value:\n FIELD:\n\ \ path: \"CA10N__newRelicHostDiskUtilization__c\"\n # Nullable.\n -\ \ name: \"CA10N__newRelicHostDiskReadUtilization__c\"\n value:\n FIELD:\n\ \ path: \"CA10N__newRelicHostDiskReadUtilization__c\"\n # Nullable.\n\ \ - name: \"CA10N__newRelicHostDiskWriteUtilization__c\"\n value:\n \ \ FIELD:\n path: \"CA10N__newRelicHostDiskWriteUtilization__c\"\n #\ \ Nullable.\n - name: \"CA10__regionName__c\"\n value:\n FIELD:\n \ \ path: \"CA10__regionName__c\"\n# Values: paravirtual | hvm. Not nullable.\ \ Can't have no access, retrieved via ec2:DescribeInstances\n - name: \"CA10__virtualizationType__c\"\ \n value: \n FIELD:\n path: \"CA10__virtualizationType__c\"\n\ \ undeterminedIf:\n isEmpty: \"Corrupted data. EC2 Instances\ \ Virtualization Type cannot be empty.\"\n" script: |- CREATE TEMP FUNCTION mock_ExpectedResult() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "Id" : "a01", "expectedResult" : { "status" : "DISAPPEARED", "conditionIndex" : "99", "conditionText" : "isDisappeared(CA10__disappearanceTime__c)", "runtimeError" : null } }, { "Id" : "a02", "expectedResult" : { "status" : "COMPLIANT", "conditionIndex" : "199", "conditionText" : "CA10A1__iamInstanceProfile__r.CA10A1__roleArn__c.isNotEmpty()", "runtimeError" : null } }, { "Id" : "a03", "expectedResult" : { "status" : "INCOMPLIANT", "conditionIndex" : "200", "conditionText" : "otherwise", "runtimeError" : null } }, { "Id" : "a04", "expectedResult" : { "status" : "INCOMPLIANT", "conditionIndex" : "200", "conditionText" : "otherwise", "runtimeError" : null } } ]; """; CREATE TEMP FUNCTION mock_CA10__CaAwsInstance__c() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "context" : { "snapshotTime" : new Date("2024-06-19T07:55:48Z") }, "CA10__disappearanceTime__c" : new Date("2024-06-18T13:02:29Z"), "Id" : "a01", "CA10A1__iamInstanceProfile__c" : null }, { "context" : { "snapshotTime" : new Date("2024-06-19T07:55:48Z") }, "Id" : "a02", "CA10A1__iamInstanceProfile__c" : "profile1" }, { "context" : { "snapshotTime" : new Date("2024-06-19T07:55:48Z") }, "Id" : "a03", "CA10A1__iamInstanceProfile__c" : "profile2" }, { "context" : { "snapshotTime" : new Date("2024-06-19T07:55:48Z") }, "Id" : "a04", "CA10A1__iamInstanceProfile__c" : null } ]; """; CREATE TEMP FUNCTION mock_CA10A1__CaAwsIamInstanceProfile__c() RETURNS ARRAY >> DETERMINISTIC LANGUAGE js AS r""" return [ { "context" : { "snapshotTime" : new Date("2024-06-19T07:55:48Z") }, "CA10A1__roleArn__c" : "", "Id" : null }, { "context" : { "snapshotTime" : new Date("2024-06-19T07:55:48Z") }, "CA10A1__roleArn__c" : "arn:aws:iam::1234567890:role/role1", "Id" : "profile1" }, { "context" : { "snapshotTime" : new Date("2024-06-19T07:55:48Z") }, "CA10A1__roleArn__c" : "", "Id" : "profile2" } ]; """; CREATE TEMP FUNCTION process_CA10__CaAwsInstance__c( obj STRUCT< CA10__disappearanceTime__c TIMESTAMP, CA10A1__iamInstanceProfile__r STRUCT< CA10A1__roleArn__c STRING, Id STRING >, Id STRING, CA10A1__iamInstanceProfile__c STRING >, snapshotTime TIMESTAMP ) RETURNS STRUCT DETERMINISTIC LANGUAGE js AS r""" var TextLib = new function () { this.normalize = function(arg) { return arg == null ? '' : arg.replace(/\s+/g, ' ').trim().toLowerCase(); }; this.isEmpty = function(arg) { return this.normalize(arg) == ''; }; this.isNotEmpty = function(arg) { return this.normalize(arg) != ''; }; this.equal = function(left, right) { return this.normalize(left) == this.normalize(right); }; this.notEqual = function(left, right) { return this.normalize(left) != this.normalize(right); }; this.startsWith = function(arg, substring) { return this.normalize(arg).startsWith(this.normalize(substring)); }; this.endsWith = function(arg, substring) { return this.normalize(arg).endsWith(this.normalize(substring)); }; this.contains = function(arg, substring) { return this.normalize(arg).includes(this.normalize(substring)); }; this.containsAll = function(arg, substrings) { if (substrings == null || substrings.length === 0) return false; let normalizedArg = this.normalize(arg); return substrings.every(sub => normalizedArg.includes(this.normalize(sub))); }; this.containsAny = function(arg, substrings) { if (substrings == null || substrings.length === 0) return false; let normalizedArg = this.normalize(arg); return substrings.some(sub => normalizedArg.includes(this.normalize(sub))); }; }(); var references1 = []; // condition[0], conditionIndex:[0..99] references1.push('Deleted From AWS [CA10__disappearanceTime__c]: ' + obj.CA10__disappearanceTime__c); if (obj.CA10__disappearanceTime__c != null) { return {status: 'DISAPPEARED', conditionIndex: 99, conditionText: "isDisappeared(CA10__disappearanceTime__c)", currentStateMessage: "Object is deleted in the source", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } // condition[1], conditionIndex:[100..199] references1.push('Role ARN [obj.CA10A1__iamInstanceProfile__r.CA10A1__roleArn__c]: ' + obj.CA10A1__iamInstanceProfile__r.CA10A1__roleArn__c); if (TextLib.isNotEmpty(obj.CA10A1__iamInstanceProfile__r.CA10A1__roleArn__c)) { return {status: 'COMPLIANT', conditionIndex: 199, conditionText: "CA10A1__iamInstanceProfile__r.CA10A1__roleArn__c.isNotEmpty()", currentStateMessage: "The instance has an IAM role attached through its instance profile.", currentStateReferences: references1.join('\n'), remediation: null, runtimeError: null}; } return {status: 'INCOMPLIANT', conditionIndex: 200, conditionText: "otherwise", currentStateMessage: "The instance does not have an IAM role attached.", currentStateReferences: references1.join('\n'), remediation: "Attach an IAM role to the instance.", runtimeError: null}; """; SELECT expectedResult.Id as Id, IF ( IFNULL(expectedResult.expectedResult.status, '') = IFNULL(sObject.result.status, '') AND IFNULL(expectedResult.expectedResult.conditionIndex, -1) = IFNULL(sObject.result.conditionIndex, -1) AND IFNULL(expectedResult.expectedResult.conditionText, '') = IFNULL(sObject.result.conditionText, '') AND IFNULL(expectedResult.expectedResult.runtimeError, '') = IFNULL(sObject.result.runtimeError, ''), "MATCH", "FAIL" ) as match, expectedResult.expectedResult.status as expectedStatus, sObject.result.status as actualStatus, expectedResult.expectedResult.conditionIndex as expectedConditionIndex, sObject.result.conditionIndex as actualConditionIndex, expectedResult.expectedResult.conditionText as expectedConditionText, sObject.result.conditionText as actualConditionText, expectedResult.expectedResult.runtimeError as expectedRuntimeError, sObject.result.runtimeError as actualRuntimeError FROM UNNEST(mock_ExpectedResult()) expectedResult LEFT JOIN ( SELECT sObject.CA10__disappearanceTime__c AS CA10__disappearanceTime__c, STRUCT ( `CA10A1__iamInstanceProfile__r`.CA10A1__roleArn__c AS CA10A1__roleArn__c, `CA10A1__iamInstanceProfile__r`.Id AS Id ) AS CA10A1__iamInstanceProfile__r, sObject.Id AS Id, sObject.CA10A1__iamInstanceProfile__c AS CA10A1__iamInstanceProfile__c, process_CA10__CaAwsInstance__c( STRUCT( sObject.CA10__disappearanceTime__c AS CA10__disappearanceTime__c, STRUCT ( `CA10A1__iamInstanceProfile__r`.CA10A1__roleArn__c AS CA10A1__roleArn__c, `CA10A1__iamInstanceProfile__r`.Id AS Id ) AS CA10A1__iamInstanceProfile__r, sObject.Id AS Id, sObject.CA10A1__iamInstanceProfile__c AS CA10A1__iamInstanceProfile__c ), sObject.context.snapshotTime ) as result FROM UNNEST(mock_CA10__CaAwsInstance__c()) AS sObject LEFT JOIN UNNEST(mock_CA10A1__CaAwsIamInstanceProfile__c()) AS `CA10A1__iamInstanceProfile__r` ON sObject.CA10A1__iamInstanceProfile__c = `CA10A1__iamInstanceProfile__r`.Id ) sObject ON sObject.Id = expectedResult.Id;