IAM Role Setup
To make onboarding even more flexible, nOps now supports integration using an IAM Role-based approach. This method allows customers to grant access using their own IAM policies without deploying a CloudFormation stack.
Prerequisites
To successfully set up the IAM Role integration with nOps, ensure the following:
- You must have Administrator access to the AWS Management (Payer) account.
- You must be able to create IAM Policies and IAM Roles.
- You must have the Cost and Usage Report (CUR) enabled and configured to deliver data to an S3 bucket within your AWS account.
- The CUR must meet all of the following mandatory criteria:
- Granularity set to Hourly
- Overwrite existing report option is enabled
- Parquet selected as the compression format
- Schema elements must include both "RESOURCES" and "SPLIT_COST_ALLOCATION_DATA"
- The CUR must meet all of the following mandatory criteria:
- You will need an External ID which will be provided by nOps.
Onboarding Master Payer with Full Permissions
In order to grant the role the required permissions, we need to create custom Policy(-ies) depending on the access you want to give nOps.
please select Onboard with IAM in the Set Up nOps popup
Step 1: Create the Integration Policy
To give nOps full access to ReadOnlyAccess and other services, you only need to create custom integration Policy.
- Copy NopsIntegrationPolicy from the step 2.
- AWS Console:Go to IAM → Policies and click on Create Policy.
- Choose the JSON editor and paste the provided JSON.
- Click Next, specify a unique Policy Name, and click Create Policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cur:DescribeReportDefinitions",
"cur:DeleteReportDefinition",
"cur:PutReportDefinition",
"s3:ListBucket",
"support:CreateCase",
"events:CreateEventBus",
"ce:*"
],
"Resource": "*"
},
{
"Effect": "Deny",
"Action": [
"acm-pca:Describe*",
"acm-pca:Get*",
"acm-pca:List*",
"acm:Describe*",
"acm:Get*",
"acm:List*",
"apigateway:GET",
"appconfig:GetConfiguration*",
"appflow:DescribeConnector*",
"appflow:ListConnector*",
"appstream:DescribeDirectoryConfigs",
"appstream:DescribeUsers",
"appstream:DescribeSessions",
"appsync:Get*",
"appsync:List*",
"athena:Get*",
"athena:List*",
"backup:GetBackupVaultAccessPolicy",
"cassandra:Select",
"chime:Describe*",
"chime:Get*",
"chime:List*",
"cloud9:Describe*",
"cloud9:Get*",
"cloud9:List*",
"clouddirectory:Get*",
"clouddirectory:List*",
"cloudfront:GetCloudFrontOriginAccessIdentity",
"cloudfront:GetFieldLevelEncryption*",
"cloudfront:GetKeyGroupConfig",
"cloudwatch:GetMetricData",
"cloudwatch:GetMetricStream",
"cloudwatch:ListMetricStreams",
"codeartifact:GetAuthorizationToken",
"codeartifact:ReadFromRepository",
"codebuild:BatchGet*",
"codebuild:ListSourceCredentials",
"codecommit:BatchGet*",
"codecommit:Get*",
"codecommit:GitPull",
"codedeploy:BatchGet*",
"codedeploy:Get*",
"codestar:DescribeUserProfile",
"codestar:ListUserProfiles",
"cognito-identity:*",
"cognito-idp:*",
"cognito-sync:*",
"comprehend:Describe*",
"comprehend:List*",
"config:BatchGetAggregateResourceConfig",
"config:BatchGetResourceConfig",
"config:SelectAggregateResourceConfig",
"config:SelectResourceConfig",
"connect:Describe*",
"connect:Get*",
"connect:List*",
"datapipeline:DescribeObjects",
"datapipeline:EvaluateExpression",
"datapipeline:QueryObjects",
"dax:BatchGetItem",
"dax:GetItem",
"dax:Query",
"deepcomposer:Get*",
"deepcomposer:List*",
"devicefarm:GetRemoteAccessSession",
"devicefarm:ListRemoteAccessSessions",
"directconnect:Describe*",
"directconnect:List*",
"discovery:Describe*",
"discovery:Get*",
"discovery:List*",
"dms:Describe*",
"dms:List*",
"ds:Get*",
"dynamodb:GetItem",
"dynamodb:BatchGetItem",
"dynamodb:Query",
"dynamodb:Scan",
"ec2:GetConsoleScreenshot",
"ecr:BatchGetImage",
"ecr:GetAuthorizationToken",
"ecr:GetDownloadUrlForLayer",
"ecr-public:GetAuthorizationToken",
"eks:DescribeIdentityProviderConfig",
"elasticbeanstalk:DescribeConfigurationOptions",
"elasticbeanstalk:DescribeConfigurationSettings",
"es:ESHttpGet*",
"fis:GetExperimentTemplate",
"fms:GetAdminAccount",
"frauddetector:BatchGetVariable",
"frauddetector:Get*",
"gamelift:GetGameSessionLogUrl",
"gamelift:GetInstanceAccess",
"geo:ListDevicePositions",
"glue:GetSecurityConfiguration*",
"glue:SearchTables",
"glue:GetTable*",
"guardduty:GetIPSet",
"guardduty:GetMasterAccount",
"guardduty:GetMembers",
"guardduty:ListMembers",
"guardduty:ListOrganizationAdminAccounts",
"inspector2:GetConfiguration",
"imagebuilder:GetImage",
"iotsitewise:ListAccessPolicies",
"ivs:GetPlaybackKeyPair",
"ivs:GetStreamSession",
"kafka:GetBootstrapBrokers",
"kendra:Query*",
"kinesis:Get*",
"kms:DescribeKey",
"kms:GetPublicKey",
"lex:Get*",
"lambda:GetFunctionConfiguration",
"license-manager:GetGrant",
"license-manager:GetLicense",
"license-manager:ListTokens",
"lightsail:GetBucketAccessKeys",
"lightsail:GetCertificates",
"lightsail:GetContainerImages",
"lightsail:GetKeyPair",
"lightsail:GetRelationalDatabaseLogStreams",
"logs:GetLogEvents",
"logs:StartQuery",
"machinelearning:GetMLModel",
"macie2:GetAdministratorAccount",
"macie2:GetMember",
"macie2:GetMacieSession",
"macie2:SearchResources",
"macie2:GetSensitiveDataOccurrences",
"nimble:GetStreamingSession",
"polly:SynthesizeSpeech",
"proton:GetEnvironmentTemplate",
"proton:GetServiceTemplate",
"proton:ListServiceTemplates",
"proton:ListEnvironmentTemplates",
"qldb:GetBlock",
"qldb:GetDigest",
"rds:Download*",
"rekognition:CompareFaces",
"rekognition:Detect*",
"rekognition:Search*",
"resiliencehub:DescribeAppVersionTemplate",
"resiliencehub:ListRecommendationTemplates",
"robomaker:GetWorldTemplateBody",
"s3-object-lambda:GetObject",
"sagemaker:Search",
"schemas:GetDiscoveredSchema",
"sdb:Get*",
"sdb:Select*",
"secretsmanager:*",
"securityhub:GetFindings",
"securityhub:GetMembers",
"securityhub:ListMembers",
"ses:GetTemplate",
"ses:GetEmailTemplate",
"ses:GetContact",
"ses:GetContactList",
"ses:ListTemplates",
"ses:ListEmailTemplates",
"ses:ListVerifiedEmailAddresses",
"signer:GetSigningProfile",
"signer:ListProfilePermissions",
"signer:ListSigningProfiles",
"sms-voice:DescribeKeywords",
"sms-voice:DescribeOptedOutNumbers",
"sms-voice:DescribePhoneNumbers",
"sms-voice:DescribePools",
"snowball:Describe*",
"sqs:Receive*",
"ssm-contacts:*",
"ssm:DescribeParameters*",
"ssm:GetParameter*",
"sso:Describe*",
"sso:Get*",
"sso:List*",
"storagegateway:DescribeChapCredentials",
"support:DescribeCommunications",
"timestream:ListDatabases",
"timestream:ListTables",
"transcribe:Get*",
"transcribe:List*",
"transfer:Describe*",
"transfer:List*",
"waf-regional:GetChangeToken",
"workmail:DescribeUser",
"workmail:ListUsers"
],
"Resource": "*"
}
]
}
Step 2: Create the System Bucket Policy
To give nOps full access your bucket and reports generated, you need to create custom bucket Policy.
- Copy NopsSystemBucketPolicy from the step 2.
- AWS Console: Go to IAM → Policies and click on Create Policy.
- Choose the JSON editor and paste the provided JSON.
- Click Next, specify a unique Policy Name, and click Create Policy.
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"s3:ListBucket",
"s3:GetBucketPolicy",
"s3:GetEncryptionConfiguration",
"s3:GetBucketVersioning",
"s3:GetBucketPolicyStatus",
"s3:GetBucketLocation",
"s3:GetBucketAcl",
"s3:GetBucketLogging",
"s3:GetObject",
"s3:PutBucketPolicy",
"s3:PutObject"
],
"Resource": [
"arn:aws:s3:::<example-bucket-name>",
"arn:aws:s3:::<example-bucket-name>/*"
]
}
]
}
You should put the name of your bucket configured with CUR in the Policy above.
Step 3: Create the Role
Now we are ready to create an IAM Role.
- Copy the Trust Relationship of the IAM Role from step 1.
- AWS Console:Go to IAM → Roles, and click Create Role.
- Choose Custom trust policy, and paste the following:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::202279780353:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "<generated>"
}
}
}
]
}
The ExternalId
will be provided by nOps.
Full Permissions
In case of providing full read-only permissions, you should do the following:
- Attach the AWS managed policy
ReadOnlyAccess
- Attach the custom Integration Policy created earlier
- Attach the custom System Bucket Policy created earlier
After the role is created, share the following information via the nOps onboarding form and click on Set up Account:
- The IAM Role ARN
- Your S3 bucket name
- Your CUR export name
Onboarding Master Payer with Minimum Permissions
If you don’t want to provide nOps full permissions, you can create 1–3 policies depending on your usage and attach them to the role.
On a Set Up nOps please switch to Minimum Access
Platform Permissions (Required)
- Copy Platform Permissions from the step 2.
- AWS Console:Go to IAM → Policies and click on Create Policy.
- Choose the JSON editor and paste the provided JSON.
- Click Next, specify a unique Policy Name, and click Create Policy.
This basic policy is required for minimum permissions:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"autoscaling:DescribeAutoScalingGroups",
"autoscaling:DescribeAutoScalingInstances",
"autoscaling-plans:DescribeScalingPlans",
"autoscaling-plans:GetScalingPlanResourceForecastData",
"autoscaling-plans:DescribeScalingPlanResources",
"autoscaling:DescribePolicies",
"autoscaling:DescribeLaunchConfigurations",
"autoscaling:DescribeLoadBalancers",
"autoscaling:DescribeScalingActivities",
"autoscaling:DescribeAccountLimits",
"apigateway:GET",
"ce:DescribeCostCategoryDefinition",
"ce:DescribeNotificationSubscription",
"ce:DescribeReport",
"ce:GetAnomalies",
"ce:GetAnomalyMonitors",
"ce:GetAnomalySubscriptions",
"ce:GetApproximateUsageRecords",
"ce:GetCostAndUsage",
"ce:GetCostAndUsageWithResources",
"ce:GetCostCategories",
"ce:GetCostForecast",
"ce:GetDimensionValues",
"ce:GetPreferences",
"ce:GetReservationCoverage",
"ce:GetReservationPurchaseRecommendation",
"ce:GetReservationUtilization",
"ce:GetRightsizingRecommendation",
"ce:GetSavingsPlanPurchaseRecommendationDetails",
"ce:GetSavingsPlansCoverage",
"ce:GetSavingsPlansPurchaseRecommendation",
"ce:GetSavingsPlansUtilization",
"ce:GetSavingsPlansUtilizationDetails",
"ce:GetTags",
"ce:GetUsageForecast",
"ce:ListCostAllocationTagBackfillHistory",
"ce:ListCostAllocationTags",
"ce:ListCostCategoryDefinitions",
"ce:ListSavingsPlansPurchaseRecommendationGeneration",
"ce:ListTagsForResource",
"ce:StartSavingsPlansPurchaseRecommendationGeneration",
"ce:UpdateCostAllocationTagsStatus",
"cloudtrail:DescribeTrails",
"cloudtrail:LookupEvents",
"cloudwatch:GetMetricStatistics",
"compute-optimizer:DescribeRecommendationExportJobs",
"compute-optimizer:GetAutoScalingGroupRecommendations",
"compute-optimizer:GetEBSVolumeRecommendations",
"compute-optimizer:GetEC2InstanceRecommendations",
"compute-optimizer:GetEC2RecommendationProjectedMetrics",
"compute-optimizer:GetECSServiceRecommendationProjectedMetrics",
"compute-optimizer:GetECSServiceRecommendations",
"compute-optimizer:GetEffectiveRecommendationPreferences",
"compute-optimizer:GetEnrollmentStatus",
"compute-optimizer:GetEnrollmentStatusesForOrganization",
"compute-optimizer:GetLambdaFunctionRecommendations",
"compute-optimizer:GetLicenseRecommendations",
"compute-optimizer:GetRDSDatabaseRecommendationProjectedMetrics",
"compute-optimizer:GetRDSDatabaseRecommendations",
"compute-optimizer:GetRecommendationPreferences",
"compute-optimizer:GetRecommendationSummaries",
"config:DescribeConfigurationRecorders",
"consolidatedbilling:GetAccountBillingRole",
"consolidatedbilling:ListLinkedAccounts",
"cost-optimization-hub:GetPreferences",
"cost-optimization-hub:GetRecommendation",
"cost-optimization-hub:ListEnrollmentStatuses",
"cost-optimization-hub:ListRecommendations",
"cost-optimization-hub:ListRecommendationSummaries",
"cost-optimization-hub:UpdateEnrollmentStatus",
"cost-optimization-hub:UpdatePreferences",
"cur:GetClassicReport",
"cur:GetClassicReportPreferences",
"cur:GetUsageReport",
"cur:DescribeReportDefinitions",
"cur:PutReportDefinition",
"dynamodb:ListTables",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeNatGateways",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeRegions",
"ec2:DescribeReservedInstances",
"ec2:DescribeVolumes",
"ec2:DescribeVpcs",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeInstanceStatus",
"ec2:DescribeSnapshots",
"ec2:DescribeSecurityGroups",
"ecs:ListClusters",
"eks:ListTagsForResource",
"eks:ListClusters",
"eks:ListNodegroups",
"eks:DescribeCluster",
"eks:DescribeNodegroup",
"elasticache:DescribeCacheClusters",
"elasticache:DescribeCacheSubnetGroups",
"elasticfilesystem:DescribeFileSystems",
"elasticloadbalancing:DescribeLoadBalancers",
"es:DescribeElasticsearchDomains",
"es:ListDomainNames",
"events:ListRules",
"guardduty:ListDetectors",
"iam:GetRole",
"iam:GetAccountSummary",
"iam:ListAccountAliases",
"iam:ListAttachedUserPolicies",
"iam:ListRoles",
"iam:ListUsers",
"kms:Decrypt",
"lambda:GetFunction",
"lambda:GetPolicy",
"lambda:ListFunctions",
"rds:DescribeDBClusters",
"rds:DescribeDBInstances",
"rds:DescribeDBSnapshots",
"rds:DescribeDBClusterSnapshotAttributes",
"rds:DescribeDBClusterSnapshots",
"rds:DescribeDBRecommendations",
"rds:DescribeDBSecurityGroups",
"rds:ListTagsForResource",
"redshift:DescribeClusters",
"s3:ListAllMyBuckets",
"s3:GetBucketVersioning",
"savingsplans:DescribeSavingsPlanRates",
"savingsplans:DescribeSavingsPlans",
"savingsplans:DescribeSavingsPlansOfferingRates",
"savingsplans:DescribeSavingsPlansOfferings",
"savingsplans:ListTagsForResource",
"support:CreateCase",
"support:DescribeCases",
"tag:GetResources",
"tag:GetTagValues",
"tag:DescribeReportCreation",
"tag:GetTagKeys",
"tag:GetComplianceSummary",
"organizations:ListAccounts",
"organizations:DescribeOrganization",
"organizations:ListRoots"
],
"Resource": "*"
}
]
}
Scheduler Permissions
- Copy Scheduler Permissions from step 2.
- AWS Console: Go to IAM → Policies and click on Create Policy.
- Choose the JSON editor and paste the provided JSON.
- Click Next, specify a unique Policy Name, and click Create Policy.
Use this policy if you plan to use the Essentials solution. You can add this policy at any time:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cloudwatch:ListMetrics",
"events:CreateEventBus",
"scheduler:GetSchedule",
"scheduler:GetScheduleGroup",
"scheduler:ListScheduleGroups",
"scheduler:ListSchedules",
"scheduler:ListTagsForResource"
],
"Resource": "*"
}
]
}
Compute Copilot Permissions (EKS/ECS/ASG/BATCH)
- Copy Compute Copilot Permissions from step 2.
- AWS Console: Go to IAM → Policies and click on Create Policy.
- Choose the JSON editor and paste the provided JSON.
- Click Next, specify a unique Policy Name, and click Create Policy.
Use this policy if you plan to use Compute Copilot. You can add it whenever required:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeLaunchConfigurations",
"ec2:DescribeImages",
"ec2:DescribeInstances",
"ec2:DescribeInstanceTypes",
"ec2:DescribeReservedInstances",
"lambda:InvokeFunction",
"cloudformation:ListStacks",
"cloudformation:DescribeStacks",
"savingsplans:DescribeSavingsPlans"
],
"Resource": "*"
}
]
}
IAM Role Setup
Now that the policies are created, you’re ready to create an IAM Role.
- Copy Trust Relationship of the IAM Role from step 1.
- AWS Console: Go to IAM → Roles and click on Create role.
- Choose Custom trust policy and you can paste the JSON from here as well :
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::202279780353:root"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "<generated>"
}
}
}
]
}
The ExternalId
will be provided by nOps.
Minimum Permissions
Find and attach the following policies to the Role:
- The Platform Permissions policy you created above for basic usage.
- (Optional) The Essentials policy if you're using nOps Essentials.
- (Optional) The Compute Copilot policy if you're using Compute Copilot features.
Once the policies are attached:
- Specify any meaningful Role name.
- Click on Create role.
After the role is created, share the following information via the nOps onboarding form and click on Set up Account :
- The IAM Role name
- Your S3 bucket name
- Your CUR export name
This completes the minimum permissions onboarding setup for nOps.
Onboarding Child Accounts
- Go to Settings -> AWS Accounts.
- Click on Set up Account button of the child account you want to onboard.
- Select Set Up with IAM and proceed.
- Now please follow the same process for Child account onboarding as well — using either Full Permissions or Minimum Permissions, based on your organization's preference.