AWSTemplateFormatVersion: "2010-09-09"
Description: "Ownstak IAM Roles for Lambda and ECS"

Parameters:

  Principals:
    Type: CommaDelimitedList
    Description: "AWS principal (ARNs) that can assume the OwnstakCloudCredentialsRole. Do not change unless you want to use a non-production Ownstak instance."
    Default: "arn:aws:iam::452764013502:role/OwnstakConsoleProd"




Resources:
  ExternalIdSecret:
    Type: AWS::SecretsManager::Secret
    Properties:
      Name: ownstak/external-id
      Description: "External ID for Ownstak cross-account access"
      GenerateSecretString:
        SecretStringTemplate: '{"ExternalId":""}'
        GenerateStringKey: "ExternalId"
        PasswordLength: 32
        ExcludePunctuation: true

  OwnstakCloudCredentialsPolicy:
    Type: AWS::IAM::ManagedPolicy
    Properties:
      ManagedPolicyName: ownstak-cloud-credentials-policy
      Description: Policy for Ownstak services
      PolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Sid: AdminAccessesToServices
            Effect: Allow
            Action:
              - acm:*
              - ec2:*
              - cloudfront:*
              - elasticloadbalancing:*
              - ecs:*
              - application-autoscaling:*
              - autoscaling:*
              - logs:*
              - cloudwatch:*
              - lambda:*
              - s3:*
              - iam:GetRole
              - iam:GetInstanceProfile
              - ssm:GetParameter # to retrieve AMI ID for single instance mode
              - secretsmanager:*
            Resource: "*"
          - Sid: IAMALB
            Effect: Allow
            Action:
              - iam:CreateServiceLinkedRole
            Resource: "*"
            Condition:
              StringEquals:
                iam:AWSServiceName:
                  - autoscaling.amazonaws.com
                  - elasticloadbalancing.amazonaws.com
          - Sid: IAMAssign
            Effect: Allow
            Action:
              - iam:passRole
            Resource:
              - "arn:aws:iam::*:role/ownstak-lambda-execution-role"
              - "arn:aws:iam::*:role/ownstak-ecs-execution-role"
              - "arn:aws:iam::*:role/ownstak-ecs-task-role"
              - "arn:aws:iam::*:role/ownstak-ec2-instance-profile-role"
      
  OwnstakCloudCredentialsRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: OwnstakCloudCredentialsRole
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              AWS: !Ref Principals
            Action: sts:AssumeRole
            Condition:
              StringEquals:
                sts:ExternalId: !Sub '{{resolve:secretsmanager:${ExternalIdSecret}:SecretString:ExternalId}}'
      ManagedPolicyArns:
        - !Ref OwnstakCloudCredentialsPolicy

  LambdaExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: ownstak-lambda-execution-role
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AWSLambdaVPCAccessExecutionRole
        - arn:aws:iam::aws:policy/service-role/AWSLambdaBasicExecutionRole
      Policies:
        - PolicyName: S3Access
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - s3:GetObject
                  - s3:PutObject
                  - s3:ListObjects
                  - s3:DeleteObject
                Resource:
                  - "arn:aws:s3:::ownstak-*"

  ECSExecutionRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: ownstak-ecs-execution-role
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy

  ECSTaskRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: ownstak-ecs-task-role
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ecs-tasks.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly
      Policies:
        - PolicyName: LambdaProxyPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                Resource: "arn:aws:lambda:*:*:function:ownstak-*"

  Ec2InstanceProfileRole:
    Type: AWS::IAM::Role
    Properties:
      RoleName: ownstak-ec2-instance-profile-role
      AssumeRolePolicyDocument:
        Version: "2012-10-17"
        Statement:
          - Effect: Allow
            Principal:
              Service: ec2.amazonaws.com
            Action: sts:AssumeRole
      ManagedPolicyArns:
        - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Policies:
        - PolicyName: LambdaProxyPolicy
          PolicyDocument:
            Version: "2012-10-17"
            Statement:
              - Effect: Allow
                Action:
                  - lambda:InvokeFunction
                Resource: "arn:aws:lambda:*:*:function:ownstak-*"

  Ec2InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      InstanceProfileName: ownstak-ec2-instance-profile
      Roles:
        - !Ref Ec2InstanceProfileRole
