{
  "Parameters": {
    "YasuID": {
      "Description": "The Yasu customer ID to sync your account. Do not change or share this.",
      "MinLength": "1",
      "Type": "String"
    },
    "YasuIamRole": {
      "Description": "The IAM role that Yasu will use to access your account.",
      "MinLength": "1",
      "Type": "String"
    },
    "YasuHandshakeID": {
      "Description": "The Yasu external ID to authenticate your account. Do not change or share this.",
      "MinLength": "1",
      "Type": "String"
    },
    "YasuPingbackArn": {
      "Description": "The SNS topic ARN used to communicate back to Yasu.",
      "MinLength": "1",
      "Type": "String",
      "Default": "arn:aws:sns:us-east-1:686255963790:yasu-cf-connector"
    },
    "ReportName": {
      "Description": "The name of the Cost and Usage Report.",
      "MinLength": "1",
      "Type": "String"
    },
    "BucketName": {
      "Description": "The name of the bucket where the cost and usage reports will be stored.",
      "MinLength": "1",
      "Type": "String"
    },
    "YasuCURExportNotificationTopicArn": {
      "Description": "The topic to notify when the Cost and Usage Report is exported.",
      "MinLength": "1",
      "Type": "String",
      "Default": "arn:aws:sns:us-east-1:686255963790:yasu-cur-export"
    },
    "TemplateVersion": {
      "Description": "Version of this CloudFormation template",
      "Type": "String",
      "Default": "v0.0.1"
    },
    "TemplateUrl": {
      "Description": "URL of the CloudFormation template",
      "Type": "String",
      "Default": ""
    }
  },
  "Resources": {
    "CrossAccountRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": {
          "Fn::Sub": "YasuCostOptimizationRole-${YasuID}"
        },
        "Description": "Role for Yasu to access cost optimization data",
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Ref": "YasuIamRole"
                }
              },
              "Action": [
                "sts:AssumeRole"
              ],
              "Condition": {
                "StringEquals": {
                  "sts:ExternalId": {
                    "Ref": "YasuHandshakeID"
                  }
                }
              }
            }
          ]
        },
        "ManagedPolicyArns": [
          "arn:aws:iam::aws:policy/job-function/ViewOnlyAccess"
        ],
        "Path": "/",
        "Policies": [
          {
            "PolicyName": {
              "Fn::Sub": "YasuCostOptimizationPolicy-${YasuID}"
            },
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Action": [
                    "application-autoscaling:Describe*",
                    "aws-portal:ViewBilling",
                    "aws-portal:ViewUsage",
                    "budgets:Describe*",
                    "budgets:View*",
                    "ce:Describe*",
                    "ce:Get*",
                    "ce:List*",
                    "cloudwatch:Get*",
                    "cloudwatch:List*",
                    "cloudwatch:Describe*",
                    "cloudfront:GetDistribution",
                    "cloudfront:GetDistributionConfig",
                    "cloudfront:GetInvalidation",
                    "cloudfront:ListDistributions",
                    "cloudfront:ListInvalidations",
                    "cloudfront:ListTagsForResource",
                    "compute-optimizer:Describe*",
                    "compute-optimizer:Get*",
                    "cur:Describe*",
                    "directconnect:Describe*",
                    "ec2:Describe*",
                    "ec2:List*",
                    "ecr:Describe*",
                    "ecr:List*",
                    "eks:Describe*",
                    "eks:List*",
                    "elasticache:List*",
                    "elasticfilesystem:Describe*",
                    "elasticloadbalancing:Describe*",
                    "es:Describe*",
                    "es:List*",
                    "glacier:Describe*",
                    "kafka:Describe*",
                    "kafka:List*",
                    "lambda:Get*",
                    "lambda:List*",
                    "license-manager:List*",
                    "mediaconnect:Describe*",
                    "mediaconnect:List*",
                    "mediaconvert:List*",
                    "medialive:Describe*",
                    "medialive:List*",
                    "mediapackage:Describe*",
                    "mediapackage:List*",
                    "mediapackage-vod:Describe*",
                    "mediapackage-vod:List*",
                    "mediastore:Describe*",
                    "mediastore:List*",
                    "mediatailor:Describe*",
                    "mediatailor:List*",
                    "mq:Describe*",
                    "mq:List*",
                    "organizations:Describe*",
                    "organizations:List*",
                    "pi:Describe*",
                    "pi:Get*",
                    "pi:List*",
                    "pricing:*",
                    "rds:List*",
                    "redshift:Describe*",
                    "redshift:List*",
                    "resource-groups:Get*",
                    "resource-groups:List*",
                    "resource-groups:Search*",
                    "route53:Get*",
                    "route53:List*",
                    "route53domains:Check*",
                    "route53domains:Get*",
                    "route53domains:View*",
                    "sagemaker:Describe*",
                    "sagemaker:List*",
                    "s3:GetBucketLocation",
                    "s3:GetBucketTagging",
                    "s3:List*",
                    "savingsplans:Describe*",
                    "secretsmanager:Describe*",
                    "secretsmanager:List*",
                    "ses:Describe*",
                    "shield:Describe*",
                    "sqs:List*",
                    "ssm:Describe*",
                    "ssm:List*",
                    "storagegateway:Describe*",
                    "storagegateway:List*",
                    "support:*",
                    "tag:Get*",
                    "tag:GetResources",
                    "transfer:Describe*",
                    "transfer:List*",
                    "trustedadvisor:Get*",
                    "trustedadvisor:List*",
                    "rds:Describe*"
                  ],
                  "Resource": "*",
                  "Effect": "Allow",
                  "Sid": "YasuBillingReadOnly"
                },
                {
                  "Sid": "YasuAssumeMemberRoles",
                  "Effect": "Allow",
                  "Action": "sts:AssumeRole",
                  "Resource": {
                    "Fn::Sub": "arn:aws:iam::*:role/YasuCostOptimizationRole-${YasuID}"
                  }
                }
              ]
            }
          },
          {
            "PolicyName": {
              "Fn::Sub": "YasuCloudWatchMetricsReadOnly-${YasuID}"
            },
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Action": [
                    "logs:List*",
                    "logs:Describe*",
                    "logs:StartQuery",
                    "logs:StopQuery",
                    "logs:Filter*",
                    "logs:Get*"
                  ],
                  "Resource": "arn:aws:logs:*:*:log-group:/aws/containerinsights/*",
                  "Effect": "Allow",
                  "Sid": "YasuContainerInsightsReadOnly"
                },
                {
                  "Action": [
                    "logs:GetQueryResults",
                    "logs:DescribeLogGroups"
                  ],
                  "Resource": "arn:aws:logs:*:*:log-group::log-stream:*",
                  "Effect": "Allow",
                  "Sid": "YasuContainerInsightsLogStream"
                },
                {
                  "Action": [
                    "autoscaling:Describe*",
                    "cloudwatch:Describe*",
                    "cloudwatch:Get*",
                    "cloudwatch:List*"
                  ],
                  "Resource": "*",
                  "Effect": "Allow",
                  "Sid": "YasuContainerMetricsAccess"
                }
              ]
            }
          }
        ]
      }
    },
    "CostandUsageReportBucket": {
      "Type": "AWS::S3::Bucket",
      "DependsOn": "CrossAccountRole",
      "Properties": {
        "AccessControl": "Private",
        "PublicAccessBlockConfiguration": {
          "BlockPublicAcls": true,
          "BlockPublicPolicy": true,
          "IgnorePublicAcls": true,
          "RestrictPublicBuckets": true
        },
        "LifecycleConfiguration": {
          "Rules": [
            {
              "Id": "ExpireOldObjects",
              "Status": "Enabled",
              "ExpirationInDays": 200
            }
          ]
        },
        "NotificationConfiguration": {
          "TopicConfigurations": [
            {
              "Topic": {
                "Ref": "YasuCURExportNotificationTopicArn"
              },
              "Event": "s3:ObjectCreated:*",
              "Filter": {
                "S3Key": {
                  "Rules": [
                    {
                      "Name": "suffix",
                      "Value": ".gz"
                    }
                  ]
                }
              }
            }
          ]
        },
        "BucketName": {
          "Ref": "BucketName"
        }
      }
    },
    "CostandUsageReportBucketPolicy": {
      "Type": "AWS::S3::BucketPolicy",
      "DependsOn": "CostandUsageReportBucket",
      "Properties": {
        "Bucket": {
          "Ref": "CostandUsageReportBucket"
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Action": [
                "s3:GetBucketAcl",
                "s3:GetBucketPolicy"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::Sub": "arn:aws:s3:::${CostandUsageReportBucket}"
              },
              "Principal": {
                "Service": "billingreports.amazonaws.com"
              }
            },
            {
              "Action": [
                "s3:PutObject"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::Sub": "arn:aws:s3:::${CostandUsageReportBucket}/*"
              },
              "Principal": {
                "Service": "billingreports.amazonaws.com"
              }
            },
            {
              "Action": [
                "s3:GetObject",
                "s3:GetObjectAcl"
              ],
              "Effect": "Allow",
              "Resource": {
                "Fn::Sub": "arn:aws:s3:::${CostandUsageReportBucket}/*"
              },
              "Principal": {
                "AWS": {
                  "Fn::GetAtt": [
                    "CrossAccountRole",
                    "Arn"
                  ]
                }
              }
            }
          ]
        }
      }
    },
    "CostandUsageReport": {
      "Type": "AWS::CUR::ReportDefinition",
      "DependsOn": "CostandUsageReportBucketPolicy",
      "Properties": {
        "AdditionalArtifacts": [],
        "AdditionalSchemaElements": [
          "RESOURCES"
        ],
        "Compression": "GZIP",
        "Format": "textORcsv",
        "RefreshClosedReports": true,
        "ReportName": {
          "Ref": "ReportName"
        },
        "ReportVersioning": "OVERWRITE_REPORT",
        "S3Bucket": {
          "Ref": "CostandUsageReportBucket"
        },
        "S3Prefix": "hourly",
        "S3Region": "us-east-1",
        "TimeUnit": "HOURLY"
      }
    },
    "ObjectGetIAMPolicy": {
      "Type": "AWS::IAM::Policy",
      "DependsOn": "CostandUsageReportBucket",
      "Properties": {
        "PolicyName": {
          "Fn::Sub": "ObjectGetCostandUsageReports-${YasuID}"
        },
        "PolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Action": [
                "s3:GetObject",
                "s3:GetObjectAcl"
              ],
              "Resource": [
                {
                  "Fn::Sub": "arn:aws:s3:::${CostandUsageReportBucket}/*"
                }
              ]
            }
          ]
        },
        "Roles": [
          {
            "Ref": "CrossAccountRole"
          }
        ]
      }
    },
    "YasuPingResource": {
      "Type": "Custom::YasuPingResource",
      "DeletionPolicy": "Retain",
      "Version": "1.0",
      "Properties": {
        "ServiceToken": {
          "Ref": "YasuPingbackArn"
        },
        "RoleArn": {
          "Fn::GetAtt": [
            "CrossAccountRole",
            "Arn"
          ]
        },
        "BucketArn": {
          "Fn::GetAtt": [
            "CostandUsageReportBucket",
            "Arn"
          ]
        },
        "YasuID": {
          "Ref": "YasuID"
        },
        "TemplateVersion": {
          "Ref": "TemplateVersion"
        },
        "TemplateUrl": {
          "Ref": "TemplateUrl"
        }
      }
    }
  },
  "Outputs": {
    "RoleArn": {
      "Value": {
        "Fn::GetAtt": [
          "CrossAccountRole",
          "Arn"
        ]
      },
      "Description": "The ARN value of the Cross-Account Role with IAM read-only permissions. Add this ARN value to Yasu."
    },
    "TemplateVersion": {
      "Value": {
        "Ref": "TemplateVersion"
      },
      "Description": "Version of the deployed template"
    },
    "TemplateUrl": {
      "Value": {
        "Ref": "TemplateUrl"
      },
      "Description": "URL of the deployed template"
    }
  }
}