---
AWSTemplateFormatVersion: 2010-09-09

# Copyright 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.

Description: Creates the Harvest and Grafana environment to monitor your Amazon FSx for Netapp ONTAP resources.

Metadata:
  Authors:
    Description: Shrinath Kurdekar (kurdekar@amazon.com)
  AWS::CloudFormation::Interface:
    ParameterGroups:
    - Label:
        default: Harvest and Grafana Instance parameters
      Parameters:
        - InstanceType
        - KeyPair
        - SecurityGroup
        - SubnetType
        - Subnet
    - Label:
        default: Amazon FSx for Netapp ONTAP file system parameters
      Parameters:
        - FSxEndPoint
        - SecretName
    ParameterLabels:
      InstanceType:
        default: Instance Type
      KeyPair:
        default: Key Pair
      LatestLinuxAmiId:
        default: Latest Amazon Linux AMI ID
      SecurityGroup:
        default: Security group ID
      SubnetType:
        default: Subnet Type
      Subnet:
        default: Subnet ID
      FSxEndPoint:
        default: Management endpoint IP address
      SecretName:
        default: AWS Secrets Manager Secret Name


Parameters:
  InstanceType:
    Description: Select the instance type. Recommended config for every 10 file system's (CPU - 2 cores, Memory - 1GB, Disk - 500MB)
    AllowedValues:
    - t3.micro
    - t3.small
    - t3.medium
    - t3.large
    - t3.xlarge
    - t3.2xlarge
    - m5.large
    - m5.xlarge
    - m5.2xlarge
    - m5.4xlarge
    - m5n.large
    - m5n.xlarge
    - m5n.2xlarge
    - m5n.4xlarge
    - c5.large
    - c5.xlarge
    - c5.2xlarge
    - c5.4xlarge
    - c5.9xlarge
    - c5.12xlarge
    - c5.18xlarge
    - c5n.xlarge
    - c5n.2xlarge
    - c5n.4xlarge
    - r5n.large
    - r5n.xlarge
    - r5n.2xlarge
    - r5n.4xlarge
    Default: t3.micro
    Type: String
  KeyPair:
    Type: AWS::EC2::KeyPair::KeyName
  SecurityGroup:
    Description: Security group ID for the Harvest/Grafana Instance. Ensure Inbound ports 3000 and 9090 are open.
    Type: List<AWS::EC2::SecurityGroup::Id>
  SubnetType:
    Description: Choose between public or private subnet based on the preferred subnet of your Amazon FSx for NetApp ONTAP file system.
    Type: String
    AllowedValues:
    - public
    - private
  Subnet:
    Type: AWS::EC2::Subnet::Id
    Description: Subnet ID. Specify the same subnet as your Amazon FSx for NetApp ONTAP file system's preferred subnet.
  LatestLinuxAmiId:
    Type: 'AWS::SSM::Parameter::Value<AWS::EC2::Image::Id>'
    Default: '/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2'
  FSxEndPoint:
    Description: File system management endpoint IP address
    Type: String
  SecretName:
    Description: 'AWS Secrets Manager Secret Name containing password for the file system "fsxadmin user". Validate secret is stored in format {"username" : "fsxadmin", "password" : "<your password>"}'
    Type: String

Conditions:
  CreatePublicIP: !Equals [!Ref SubnetType, public]
  CreatePrivateIP: !Equals [!Ref SubnetType, private]

Resources:
  Instance:
    Type: AWS::EC2::Instance
    Properties:
      IamInstanceProfile: !Ref InstanceProfile
      ImageId: !Ref LatestLinuxAmiId
      InstanceType: !Ref InstanceType
      KeyName: !Ref KeyPair
      Monitoring: true
      SecurityGroupIds: !Ref SecurityGroup
      SubnetId: !Ref Subnet
      #NetworkInterfaces:
      #  - AssociatePublicIpAddress: "true"
      #    DeviceIndex: "0"
      Tags:
        - Key: Name
          Value: Harvest/Grafana Instance for Amazon FSx for NetApp ONTAP
      UserData:
        'Fn::Base64': !Sub |
          #Cloud-config
          repo_update: true
          repo_upgrade: all

          packages:
            - docker
            - git
            - jq

          write_files:
            - content: |
                #! /bin/bash

                FSxAdminPassword=`aws secretsmanager get-secret-value --secret-id ${SecretName} --region ${AWS::Region} | jq --raw-output .SecretString | jq -r .password`

                cat <<__EOF__ >> /home/ec2-user/harvest_install/harvest/harvest.yml
                  cluster-2:
                    datacenter: ${AWS::Region}
                    addr: ${FSxEndPoint}
                    auth_style: basic_auth
                    username: fsxadmin
                    password: $FSxAdminPassword
                    ansible_port: 25002
                __EOF__

                chmod 500 /home/ec2-user/harvest_install/harvest/harvest.yml
                cd /home/ec2-user/harvest_install
                ansible-playbook manage_harvest.yml
                ansible-playbook manage_harvest.yml --tags api
                sleep 10
                /opt/aws/bin/cfn-signal -e $? --stack ${AWS::StackName} --resource Instance --region ${AWS::Region}
              owner: root:root
              path: /home/ec2-user/harvest-grafana.sh
              permissions: '0766'

          runcmd:
            - amazon-linux-extras install python3.8 -y
            - export PATH=$PATH:/usr/local/bin
            - curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
            - python3.8 get-pip.py
            - systemctl start docker
            - chkconfig docker on
            - pip3 install ansible
            - pip3 install docker
            - pip3 install six
            - pip3 install urllib3==1.26.6
            - export PATH=$PATH:/usr/local/bin
            - ansible-galaxy collection install community.docker
            - git clone https://www.github.com/netapp-automation/harvest_install /home/ec2-user/harvest_install
            - /home/ec2-user/harvest-grafana.sh
    CreationPolicy: 
      ResourceSignal:
        Timeout: PT15M

  InstanceProfile:
    Type: AWS::IAM::InstanceProfile
    Properties:
      Path: '/'
      Roles:
      - !Ref InstanceRole
  InstanceRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Version: 2012-10-17
        Statement:
        - Effect: Allow
          Principal:
            Service:
            - ec2.amazonaws.com
          Action:
          - sts:AssumeRole
      ManagedPolicyArns:
      - arn:aws:iam::aws:policy/AmazonSSMManagedInstanceCore
      Path: "/"
      Policies:
      - PolicyName: secretsmanager
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
          - Effect: Allow
            Action:
            - secretsmanager:GetSecretValue
            Resource: arn:aws:secretsmanager:*:*:secret:*

Outputs:
    PublicURL:
        Condition: CreatePublicIP
        Description: Use below Public IP URL to connect to the Grafana endpoint
        Value: !Join [ "", ["http://",!GetAtt Instance.PublicIp,":3000" ]]
    PrivateURL:
        Condition: CreatePrivateIP
        Description: Use below Private IP URL to connect to the Grafana endpoint
        Value: !Join [ "", ["http://",!GetAtt Instance.PrivateIp,":3000" ]]


