in installer/resources/src/cdk_construct.py [0:0]
def iam_roles(self):
"""
Configure IAM roles & policies for the various resources
"""
# Specify if customers want to re-use existing IAM role for scheduler/compute nodes/spotfleet
if user_specified_variables.scheduler_role_name:
use_existing_roles = True
else:
use_existing_roles = False
# Create IAM roles
self.soca_resources["backup_role"] = iam.Role(self, 'BackupRole', description="IAM role to manage AWS Backup & Restore jobs", assumed_by=iam.ServicePrincipal(principals_suffix["backup"]))
self.soca_resources["acm_certificate_lambda_role"] = iam.Role(self, 'ACMCertificateLambdaRole', description="IAM role assigned to the ACMCertificate Lambda function", assumed_by=iam.ServicePrincipal(principals_suffix["lambda"]))
self.soca_resources["solution_metrics_lambda_role"] = iam.Role(self, 'SolutionMetricsLambdaRole', description="IAM role assigned to the SolutionMetrics Lambda function", assumed_by=iam.ServicePrincipal(principals_suffix["lambda"]))
# Create Role for EFS Throughput Lambda function only when deploying a new EFS for /apps
if not user_specified_variables.fs_apps_provider or user_specified_variables.fs_apps_provider == "efs":
self.soca_resources["fs_apps_lambda_role"] = iam.Role(self, 'EFSAppsLambdaRole', description="IAM role assigned to the EFSApps Lambda function", assumed_by=iam.ServicePrincipal(principals_suffix["lambda"]))
# CreateRole for GetESPrivateIPLambdaRole when creating a new ElasticSearch
if not user_specified_variables.es_endpoint:
self.soca_resources["get_es_private_ip_lambda_role"] = iam.Role(self, 'GetESPrivateIPLambdaRole', description="IAM role assigned to the EFSApps Lambda function", assumed_by=iam.ServicePrincipal(principals_suffix["lambda"]))
if use_existing_roles is False:
# Create Scheduler/ComputeNode/SpotFleet roles if not specified by the user
self.soca_resources["scheduler_role"] = iam.Role(self, "SchedulerRole", description="IAM role assigned to the scheduler host", assumed_by=iam.CompositePrincipal(iam.ServicePrincipal(principals_suffix["ssm"]), iam.ServicePrincipal(principals_suffix["ec2"])))
self.soca_resources["compute_node_role"] = iam.Role(self, "ComputeNodeRole", description="IAM role assigned to the compute nodes", assumed_by=iam.CompositePrincipal(iam.ServicePrincipal(principals_suffix["ssm"]), iam.ServicePrincipal(principals_suffix["ec2"])))
self.soca_resources["spot_fleet_role"] = iam.Role(self, "SpotFleetRole", description="IAM role to manage SpotFleet requests", assumed_by=iam.ServicePrincipal(principals_suffix["spotfleet"]))
self.soca_resources["spot_fleet_role"].add_managed_policy(iam.ManagedPolicy.from_aws_managed_policy_name("service-role/AmazonEC2SpotFleetTaggingRole"))
self.soca_resources["compute_node_instance_profile"] = iam.CfnInstanceProfile(self, "ComputeNodeInstanceProfile", roles=[self.soca_resources["compute_node_role"].role_name])
else:
# Reference existing Scheduler/ComputeNode/SpotFleet roles
self.soca_resources["scheduler_role"] = iam.Role.from_role_arn(self, "SchedulerRole", role_arn=user_specified_variables.scheduler_role_arn)
self.soca_resources["compute_node_role"] = iam.Role.from_role_arn(self, "ComputeNodeRole", role_arn=user_specified_variables.compute_node_role_arn)
self.soca_resources["spot_fleet_role"] = iam.Role.from_role_arn(self, "SpotFleetRole", role_arn=user_specified_variables.spotfleet_role_arn)
self.soca_resources["compute_node_instance_profile"] = iam.CfnInstanceProfile(self, "ComputeNodeInstanceProfile", roles=[user_specified_variables.compute_node_role_name])
# Add SSM Managed Policy
self.soca_resources["scheduler_role"].add_managed_policy(iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSSMManagedInstanceCore"))
self.soca_resources["compute_node_role"].add_managed_policy(iam.ManagedPolicy.from_aws_managed_policy_name("AmazonSSMManagedInstanceCore"))
# Generate IAM inline policies
policy_substitutes = {"%%AWS_ACCOUNT_ID%%": core.Aws.ACCOUNT_ID,
"%%AWS_PARTITION%%": core.Aws.PARTITION,
"%%AWS_URL_SUFFIX%%": core.Aws.URL_SUFFIX,
"%%AWS_REGION%%": core.Aws.REGION,
"%%BUCKET%%": user_specified_variables.bucket,
"%%COMPUTE_NODE_ROLE_ARN%%": self.soca_resources["compute_node_role"].role_arn if not user_specified_variables.compute_node_role_arn else user_specified_variables.compute_node_role_arn,
"%%SCHEDULER_ROLE_ARN%%": self.soca_resources["scheduler_role"].role_arn if not user_specified_variables.scheduler_role_arn else user_specified_variables.scheduler_role_arn,
"%%SPOTFLEET_ROLE_ARN%%": self.soca_resources["spot_fleet_role"].role_arn if not user_specified_variables.spotfleet_role_arn else user_specified_variables.spotfleet_role_arn,
"%%VPC_ID%%": self.soca_resources["vpc"].vpc_id,
"%%CLUSTER_ID%%": user_specified_variables.cluster_id}
policy_templates = {"ACMCertificateLambdaPolicy": {"template": "../policies/ACMCertificateLambda.json", "attach_to_role": "acm_certificate_lambda_role"},
"BackupPolicy": {"template": "../policies/Backup.json", "attach_to_role": "backup_role"},
"SolutionMetricsLambdaPolicy": {"template": "../policies/SolutionMetricsLambda.json", "attach_to_role": "solution_metrics_lambda_role"}}
if not user_specified_variables.es_endpoint:
policy_templates["GetESPrivateIPLambdaPolicy"] = {"template": "../policies/GetESPrivateIPLambda.json", "attach_to_role": "get_es_private_ip_lambda_role"}
if use_existing_roles is False:
policy_templates["ComputeNodePolicy"] = {"template": "../policies/ComputeNode.json", "attach_to_role": "compute_node_role"}
policy_templates["SchedulerPolicy"] = {"template": "../policies/Scheduler.json", "attach_to_role": "scheduler_role"}
policy_templates["SpotFleetPolicy"] = {"template": "../policies/SpotFleet.json", "attach_to_role": "spot_fleet_role"}
else:
# Append required policies if IAM specified by user have not been generated by SOCA
if user_specified_variables.scheduler_role_from_previous_soca_deployment:
policy_templates["SchedulerPolicyNewCluster"] = {"template": "../policies/SchedulerAppendToExistingRole.json", "attach_to_role": "scheduler_role"}
else:
policy_templates["SchedulerPolicyNewCluster"] = {"template": "../policies/Scheduler.json", "attach_to_role": "scheduler_role"}
if not user_specified_variables.compute_node_role_from_previous_soca_deployment:
policy_templates["ComputeNodePolicy"] = {"template": "../policies/ComputeNode.json", "attach_to_role": "compute_node_role"}
if not user_specified_variables.spotfleet_role_from_previous_soca_deployment:
policy_templates["SpotFleetPolicy"] = {"template": "../policies/SpotFleet.json", "attach_to_role": "spot_fleet_role"}
if not user_specified_variables.fs_apps:
policy_templates["EFSAppsLambdaPolicy"] = {"template": "../policies/EFSAppsLambda.json", "attach_to_role": "fs_apps_lambda_role"}
# Create additional IAM Role/Policy if we use Active Directory. This role is used by ResetDsLambda
if install_props.Config.directoryservice.provider == "activedirectory":
self.soca_resources["reset_ds_password_lambda_role"] = iam.Role(self, 'ResetDsLambdaLambdaRole', assumed_by=iam.ServicePrincipal(principals_suffix["lambda"]))
policy_templates["ResetDSPasswordPolicy"] = {"template": "../policies/ResetDSPassword.json", "attach_to_role": "reset_ds_password_lambda_role"}
# Create all policies and attach them to their respective role
for policy_name, policy_data in policy_templates.items():
with open(policy_data["template"]) as json_file:
policy_content = json_file.read()
for k, v in policy_substitutes.items():
policy_content = policy_content.replace(k, v)
self.soca_resources[policy_data["attach_to_role"]].attach_inline_policy(iam.Policy(self, f"{user_specified_variables.cluster_id}-{policy_name}", document=iam.PolicyDocument.from_json(json.loads(policy_content))))