in lib/aws-region-restriction.ts [19:117]
constructor(scope: cdk.Construct, id: string, props: RegionRestrictionProps) {
super(scope, id);
const serviceControlPolicyContent = JSON.parse(fs.readFileSync("scripts/policy-regionrestrictions-servicecontrolpolicy.json", {
encoding: "utf-8",
}));
const permissionBoundaryPolicyContent = JSON.parse(fs.readFileSync("scripts/policy-regionrestrictions-permissionboudary.json", {
encoding: "utf-8",
}));
serviceControlPolicyContent['Statement'][0]['Condition']['StringNotEquals']['aws:RequestedRegion'] = props.AllowedRegions;
permissionBoundaryPolicyContent['Statement'][3]['Condition']['StringEquals']['aws:RequestedRegion'] = props.AllowedRegions;
const enabledSCP = new ScpEnabledPromise(this, 'scpPromise', {});
new ServiceControlPolicy(this, 'regionRestriction', {
ScpsEnabledPromise: enabledSCP,
PolicyName: "RegionRestriction",
Policy: JSON.stringify(serviceControlPolicyContent)
});
const customPolicyDocument = iam.PolicyDocument.fromJson(permissionBoundaryPolicyContent);
const customManagedPolicy = new iam.ManagedPolicy(this, "Region-Restriction-Permissions-Boundary-Policy", {
document: customPolicyDocument
});
const sampleRole = new iam.Role(this, "RegionRestricted-Sample-Role", {
assumedBy: new iam.ServicePrincipal('ec2.amazonaws.com'),
});
iam.PermissionsBoundary.of(sampleRole).apply(customManagedPolicy);
const enforceRegionConfigLambdaRole = new iam.Role( this, "enforceRegionConfigLambdaRole", {
assumedBy: new iam.ServicePrincipal("lambda.amazonaws.com"),
}
);
enforceRegionConfigLambdaRole.addManagedPolicy( iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSLambdaBasicExecutionRole"));
enforceRegionConfigLambdaRole.addManagedPolicy( iam.ManagedPolicy.fromAwsManagedPolicyName("service-role/AWSConfigRulesExecutionRole"));
const enforceRegionalPermissionBoundaryLambda = new lambda.SingletonFunction(this, "scpEnabledPromiseSingleton", {
role: enforceRegionConfigLambdaRole,
uuid: "enforceRegionalPermissionBoundaryLambda",
code: new lambda.InlineCode(
fs.readFileSync("scripts/config-enforcepermissionboundary.min.js", {
encoding: "utf-8",
})
),
handler: "index.handler",
timeout: cdk.Duration.seconds(60),
runtime: lambda.Runtime.NODEJS_12_X,
});
const boundaryMissingRemediationDoc = this.createBoundaryRemediationAutomationDoc();
const configServicePrincipal = new iam.ServicePrincipal('config.amazonaws.com');
const configPrincipalGrant = enforceRegionalPermissionBoundaryLambda.grantInvoke(configServicePrincipal);
const enforceRegionalPermissionBoundary = new config.CustomRule(this, 'enforceRegionalPermissionBoundary', {
lambdaFunction: enforceRegionalPermissionBoundaryLambda,
configurationChanges: true,
inputParameters: {
desiredBoundaryPolicyArn: customManagedPolicy.managedPolicyArn
},
ruleScope: config.RuleScope.fromResources([config.ResourceType.IAM_ROLE, config.ResourceType.IAM_USER]), // restrict to all CloudFormation stacks and S3 buckets
});
enforceRegionalPermissionBoundary.node.addDependency(configPrincipalGrant);
enforceRegionalPermissionBoundary.node.addDependency(enforceRegionalPermissionBoundaryLambda);
const permissionBoundaryMissingRemediationConfig = new config.CfnRemediationConfiguration(this, 'permissionBoundaryMissingRemediationConfig', {
configRuleName: enforceRegionalPermissionBoundary.configRuleName,
targetId: boundaryMissingRemediationDoc.ref,
targetType: 'SSM_DOCUMENT',
automatic: false,
parameters: {
'permissionBoundaryPolicyArn': {
'StaticValue': {
'Values' : [ customManagedPolicy.managedPolicyArn ]
}
},
'offendingIamPrincipal': {
'ResourceValue': {
'Value' : 'RESOURCE_ID'
}
}
}
});
}