---
########################################################################################
# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.              #
#                                                                                      #
# Permission is hereby granted, free of charge, to any person obtaining a copy of this #
# software and associated documentation files (the "Software"), to deal in the Software#
# without restriction, including without limitation the rights to use, copy, modify,   #
# merge, publish, distribute, sublicense, and/or sell copies of the Software, and to   #
# permit persons to whom the Software is furnished to do so.                           #  
#                                                                                      #
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,  #
# INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A        #
# PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT   #
# HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION    #
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE       # 
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                               #
########################################################################################
AWSTemplateFormatVersion: 2010-09-09
Description: 'Sample spoke setup CloudFormation Template.(fdp-1oh0t6ngo)'
Mappings: 
  CostCenter: 
    "UPDATE_ACCOUNT_ID_HERE":
      ID: "UPDATE_COST_CENTER_HERE"
  PortfolioID: 
    us-east-1: 
      "ID": "UPDATE_US-EAST-1-PORTFOLIO_ID_HERE"
    us-east-2: 
      "ID": "UPDATE_US-EAST-2-PORTFOLIO_ID_HERE"
  EMRProductID: 
    us-east-1: 
      "ID": "UPDATE_US-EAST-1-PRODUCT_ID_HERE"
    us-east-2: 
      "ID": "UPDATE_US-EAST-2-PRODUCT_ID_HERE"
Parameters:
  IAMGroupName:
    Description: Enter IAM group name (not ARN) of End-User that will use Service Catalog to launch EMR cluster.
    Type: String
    Default: ""
Resources:
  AcceptedPortfolioShare:
    Type: "AWS::ServiceCatalog::AcceptedPortfolioShare"
    Properties:
      AcceptLanguage: "en"
      PortfolioId: !FindInMap [PortfolioID, !Ref "AWS::Region", 'ID'] 
  CostCenterTagOption:
    Type: "AWS::ServiceCatalog::TagOption"
    Properties:
      Key: "cost-center"
      Value: !FindInMap [CostCenter, !Ref "AWS::AccountId", 'ID']
  AdministratorPortfolio:
    Type: "AWS::ServiceCatalog::Portfolio"
    DependsOn: AcceptedPortfolioShare
    Properties:
      AcceptLanguage: "en"
      Description: "This portfolio enables end users to deploy EMR instances"
      DisplayName: "Sample-Spoke-Portfolio"
      ProviderName: "CCOE"
  AdminPortfolioPrincipalAssociation:
    Type: "AWS::ServiceCatalog::PortfolioPrincipalAssociation"
    Properties:
      AcceptLanguage: "en"
      PortfolioId: !Ref AdministratorPortfolio
      PrincipalARN: !Sub arn:aws:iam::${AWS::AccountId}:group/${IAMGroupName}
      PrincipalType: "IAM"
  EMRAdminPortfolioProductAssociation:
    Type: "AWS::ServiceCatalog::PortfolioProductAssociation"
    Properties:
      AcceptLanguage: "en"
      PortfolioId: !Ref AdministratorPortfolio
      ProductId: !FindInMap [EMRProductID, !Ref "AWS::Region", 'ID']  
      SourcePortfolioId:  !FindInMap [PortfolioID, !Ref "AWS::Region", 'ID'] 
  CostCenterAdminPortfolioTagOptionAssociation:
    Type: "AWS::ServiceCatalog::TagOptionAssociation"
    Properties:
      ResourceId: !Ref AdministratorPortfolio
      TagOptionId: !Ref CostCenterTagOption
  EMRTemplateConstraint:
    Type: "AWS::ServiceCatalog::LaunchTemplateConstraint"
    Properties:
      AcceptLanguage: "en"
      Description: "Only Large core nodes allowed"
      PortfolioId: !Ref AdministratorPortfolio
      ProductId: !FindInMap [EMRProductID, !Ref "AWS::Region", 'ID']  
      Rules: '{"CoreInstanceRule": {"Assertions": [{"Assert": {"Fn::Contains": [["m4.large","c4.large"],{"Ref": "MasterInstanceType"}]},"AssertDescription": "Master Instance type should be either t4.large or an m4.large"},{"Assert": {"Fn::Contains": [["m4.large","c4.large"],{"Ref": "CoreInstanceType"}]},"AssertDescription": "Core Instance type should be either c4.large or m4.large"}]}}'
  EMRAnalystLaunchConstraint:
    Type: "AWS::ServiceCatalog::LaunchRoleConstraint"
    DependsOn:
      - AdministratorPortfolio
      - SCEMRProductLaunchRole
    Properties:
      AcceptLanguage: "en"
      Description: "This launch constraint ensures that analysts can launch EMR cluster without any permissions"
      PortfolioId: !Ref AdministratorPortfolio
      ProductId: !FindInMap [EMRProductID, !Ref "AWS::Region", 'ID']  
      RoleArn: !GetAtt SCEMRProductLaunchRole.Arn
  SCEMRProductLaunchRole:
    Type: 'AWS::IAM::Role'
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
          - Effect: Allow
            Principal:
              Service:
                - servicecatalog.amazonaws.com
            Action:
              - 'sts:AssumeRole'
      Path: /
      Policies:
        - PolicyName: EMRLaunchPolicy
          PolicyDocument:
            Version: 2012-10-17
            Statement:
              - Sid: VisualEditor0
                Effect: Allow
                Action:
                  - 'elasticmapreduce:ListBootstrapActions'
                  - 's3:GetObjectVersionTagging'
                  - 'iam:RemoveRoleFromInstanceProfile'
                  - 's3:CreateBucket'
                  - 'iam:CreateRole'
                  - 'iam:AttachRolePolicy'
                  - 'iam:PutRolePolicy'
                  - 'elasticmapreduce:CreateSecurityConfiguration'
                  - 's3:ListObjects'
                  - 'iam:AddRoleToInstanceProfile'
                  - 'elasticmapreduce:ListInstanceGroups'
                  - 's3:GetObjectAcl'
                  - 'elasticmapreduce:ListInstance'
                  - 'iam:DetachRolePolicy'
                  - 'cloudformation:DescribeStackEvents'
                  - 'elasticmapreduce:ListSecurityConfigurations'
                  - 's3:PutLifecycleConfiguration'
                  - 's3:GetObjectVersionAcl'
                  - 'elasticmapreduce:DeleteSecurityConfiguration'
                  - 's3:PutBucketAcl'
                  - 'cloudformation:UpdateStack'
                  - 's3:HeadBucket'
                  - 'ec2:DescribeKeyPairs'
                  - 'iam:ListRolePolicies'
                  - 's3:GetIpConfiguration'
                  - 'elasticmapreduce:DescribeSecurityConfiguration'
                  - 's3:GetBucketWebsite'
                  - 'elasticmapreduce:ViewEventsFromAllClustersInConsole'
                  - 'elasticmapreduce:ListSteps'
                  - 'iam:UpdateRoleDescription'
                  - 'iam:DeleteRole'
                  - 's3:GetBucketNotification'
                  - 's3:DeleteBucketPolicy'
                  - 's3:GetReplicationConfiguration'
                  - 's3:ListMultipartUploadParts'
                  - 'cloudformation:DescribeStacks'
                  - 's3:GetObject'
                  - 'elasticmapreduce:RemoveAutoScalingPolicy'
                  - 'cloudformation:DeleteStack'
                  - 's3:GetAnalyticsConfiguration'
                  - 's3:GetObjectVersionForReplication'
                  - 'ec2:DescribeSubnets'
                  - 'ec2:CreateTags'
                  - 'ec2:DeleteTags'
                  - 'ec2:DescribeTags'
                  - 'iam:GetRolePolicy'
                  - 'cloudformation:ValidateTemplate'
                  - 'iam:CreateInstanceProfile'
                  - 's3:ListBucketByTags'
                  - 's3:GetLifecycleConfiguration'
                  - 's3:GetBucketTagging'
                  - 's3:GetInventoryConfiguration'
                  - 's3:ListBucketVersions'
                  - 's3:GetBucketLogging'
                  - 'iam:DeletePolicy'
                  - 's3:ListBucket'
                  - 's3:GetAccelerateConfiguration'
                  - 'elasticmapreduce:DescribeCluster'
                  - 's3:GetBucketPolicy'
                  - 's3:GetObjectVersionTorrent'
                  - 'iam:PassRole'
                  - 'elasticmapreduce:DescribeStep'
                  - 's3:PutBucketTagging'
                  - 's3:GetBucketRequestPayment'
                  - 'ec2:CreateSecurityGroup'
                  - 'iam:DeleteRolePolicy'
                  - 'elasticmapreduce:SetVisibleToAllUsers'
                  - 's3:GetObjectTagging'
                  - 'elasticmapreduce:ListClusters'
                  - 's3:GetMetricsConfiguration'
                  - 'iam:CreatePolicyVersion'
                  - 's3:DeleteBucket'
                  - 'elasticmapreduce:TerminateJobFlows'
                  - 'iam:DeleteInstanceProfile'
                  - 'cloudformation:SetStackPolicy'
                  - 's3:ListBucketMultipartUploads'
                  - 'elasticmapreduce:PutAutoScalingPolicy'
                  - 's3:GetBucketVersioning'
                  - 's3:GetBucketAcl'
                  - 'ec2:DescribeSecurityGroups'
                  - 'elasticmapreduce:AddInstanceGroups'
                  - 'cloudformation:GetTemplateSummary'
                  - 'iam:CreatePolicy'
                  - 's3:GetObjectTorrent'
                  - 's3:ListAllMyBuckets'
                  - 'ec2:DescribeSecurityGroupReferences'
                  - 'cloudformation:CreateStack'
                  - 'ec2:DescribeVpcs'
                  - 'elasticmapreduce:ModifyInstanceGroups'
                  - 's3:GetBucketCORS'
                  - 'elasticmapreduce:RemoveTags'
                  - 's3:PutBucketPolicy'
                  - 'elasticmapreduce:RunJobFlow'
                  - 'elasticmapreduce:AddTags'
                  - 's3:GetBucketLocation'
                  - 's3:GetObjectVersion'
                  - 'elasticmapreduce:DescribeJobFlows'
                Resource: '*'
              - Sid: VisualEditor1
                Effect: Allow
                Action:
                  - 'ec2:UpdateSecurityGroupRuleDescriptionsEgress'
                  - 'ec2:DeleteSecurityGroup'
                  - 'ec2:UpdateSecurityGroupRuleDescriptionsIngress'
                Resource: 'arn:aws:ec2:*:*:security-group/*'
              - Sid: VisualEditor2
                Effect: Allow
                Action: 'ec2:AuthorizeSecurityGroupIngress'
                Resource: 'arn:aws:ec2:*:*:security-group/*'
