{
  "AWSTemplateFormatVersion": "2010-09-09",
  "Description": "Connect your AWS account to InsertCart AWS Web using a revocable IAM role. No access keys required.",
  "Parameters": {
    "ManagementRoleArn": {
      "Type": "String",
      "AllowedPattern": "arn:aws:iam::\\d{12}:role/.+",
      "Description": "Verified management role shown by the website connection flow."
    },
    "ExternalId": {
      "Type": "String",
      "AllowedPattern": "[a-f0-9]{40}",
      "Description": "Unique connection value generated for your signed-in account."
    },
    "ConnectionId": {
      "Type": "String",
      "AllowedPattern": "[a-f0-9]{20}"
    },
    "AllowDomains": {
      "Type": "String",
      "Default": "Yes",
      "AllowedValues": [
        "Yes",
        "No"
      ],
      "Description": "Allow ACM certificates and Route 53 DNS changes for domains you choose."
    },
    "AllowMonitoring": {
      "Type": "String",
      "Default": "No",
      "AllowedValues": [
        "Yes",
        "No"
      ],
      "Description": "Allow optional account-wide budget alerts and website error alarms."
    }
  },
  "Conditions": {
    "DomainsEnabled": {
      "Fn::Equals": [
        {
          "Ref": "AllowDomains"
        },
        "Yes"
      ]
    },
    "MonitoringEnabled": {
      "Fn::Equals": [
        {
          "Ref": "AllowMonitoring"
        },
        "Yes"
      ]
    }
  },
  "Resources": {
    "ConnectionRole": {
      "Type": "AWS::IAM::Role",
      "Properties": {
        "RoleName": {
          "Fn::Sub": "AwsWebConnection-${ConnectionId}"
        },
        "MaxSessionDuration": 3600,
        "AssumeRolePolicyDocument": {
          "Version": "2012-10-17",
          "Statement": [
            {
              "Effect": "Allow",
              "Principal": {
                "AWS": {
                  "Ref": "ManagementRoleArn"
                }
              },
              "Action": "sts:AssumeRole",
              "Condition": {
                "StringEquals": {
                  "sts:ExternalId": {
                    "Ref": "ExternalId"
                  }
                }
              }
            }
          ]
        },
        "Policies": [
          {
            "PolicyName": "AwsWebWebsiteManagement",
            "PolicyDocument": {
              "Version": "2012-10-17",
              "Statement": [
                {
                  "Sid": "WebsiteBuckets",
                  "Effect": "Allow",
                  "Action": [
                    "s3:CreateBucket",
                    "s3:GetBucketLocation",
                    "s3:ListBucket",
                    "s3:ListBucketVersions",
                    "s3:PutBucketPublicAccessBlock",
                    "s3:GetBucketPublicAccessBlock",
                    "s3:PutBucketPolicy",
                    "s3:GetBucketPolicy",
                    "s3:PutBucketOwnershipControls",
                    "s3:PutBucketVersioning",
                    "s3:GetBucketVersioning",
                    "s3:PutBucketTagging",
                    "s3:GetBucketTagging"
                  ],
                  "Resource": {
                    "Fn::Sub": "arn:aws:s3:::awsweb-${AWS::AccountId}-*"
                  }
                },
                {
                  "Sid": "WebsiteObjects",
                  "Effect": "Allow",
                  "Action": [
                    "s3:GetObject",
                    "s3:GetObjectVersion",
                    "s3:PutObject"
                  ],
                  "Resource": {
                    "Fn::Sub": "arn:aws:s3:::awsweb-${AWS::AccountId}-*/*"
                  }
                },
                {
                  "Sid": "WebsiteDelivery",
                  "Effect": "Allow",
                  "Action": [
                    "cloudfront:CreateDistribution",
                    "cloudfront:GetDistribution",
                    "cloudfront:GetDistributionConfig",
                    "cloudfront:UpdateDistribution",
                    "cloudfront:ListDistributions",
                    "cloudfront:CreateInvalidation",
                    "cloudfront:GetInvalidation",
                    "cloudfront:CreateOriginAccessControl",
                    "cloudfront:GetOriginAccessControl",
                    "cloudfront:ListOriginAccessControls"
                  ],
                  "Resource": "*"
                },
                {
                  "Sid": "WebsiteMetrics",
                  "Effect": "Allow",
                  "Action": [
                    "cloudwatch:GetMetricData"
                  ],
                  "Resource": "*"
                },
                {
                  "Fn::If": [
                    "DomainsEnabled",
                    {
                      "Sid": "DomainCertificates",
                      "Effect": "Allow",
                      "Action": [
                        "acm:RequestCertificate",
                        "acm:DescribeCertificate",
                        "acm:AddTagsToCertificate"
                      ],
                      "Resource": "*"
                    },
                    {
                      "Ref": "AWS::NoValue"
                    }
                  ]
                },
                {
                  "Fn::If": [
                    "DomainsEnabled",
                    {
                      "Sid": "DomainDns",
                      "Effect": "Allow",
                      "Action": [
                        "route53:GetHostedZone",
                        "route53:ChangeResourceRecordSets"
                      ],
                      "Resource": "arn:aws:route53:::hostedzone/*"
                    },
                    {
                      "Ref": "AWS::NoValue"
                    }
                  ]
                },
                {
                  "Fn::If": [
                    "MonitoringEnabled",
                    {
                      "Sid": "BudgetAlerts",
                      "Effect": "Allow",
                      "Action": [
                        "budgets:ModifyBudget",
                        "budgets:ViewBudget"
                      ],
                      "Resource": {
                        "Fn::Sub": "arn:aws:budgets::${AWS::AccountId}:budget/AwsWeb-*"
                      }
                    },
                    {
                      "Ref": "AWS::NoValue"
                    }
                  ]
                },
                {
                  "Fn::If": [
                    "MonitoringEnabled",
                    {
                      "Sid": "ErrorAlarms",
                      "Effect": "Allow",
                      "Action": [
                        "cloudwatch:PutMetricAlarm"
                      ],
                      "Resource": {
                        "Fn::Sub": "arn:aws:cloudwatch:us-east-1:${AWS::AccountId}:alarm:AwsWeb-*"
                      }
                    },
                    {
                      "Ref": "AWS::NoValue"
                    }
                  ]
                },
                {
                  "Fn::If": [
                    "MonitoringEnabled",
                    {
                      "Sid": "AlertSubscriptions",
                      "Effect": "Allow",
                      "Action": [
                        "sns:CreateTopic",
                        "sns:SetTopicAttributes",
                        "sns:Subscribe",
                        "sns:ListSubscriptionsByTopic"
                      ],
                      "Resource": {
                        "Fn::Sub": "arn:aws:sns:us-east-1:${AWS::AccountId}:AwsWeb-*"
                      }
                    },
                    {
                      "Ref": "AWS::NoValue"
                    }
                  ]
                }
              ]
            }
          }
        ],
        "Tags": [
          {
            "Key": "ManagedBy",
            "Value": "InsertCart AWS Web"
          }
        ]
      }
    }
  },
  "Outputs": {
    "RoleArn": {
      "Description": "Copy this into the AWS Web connection form.",
      "Value": {
        "Fn::GetAtt": [
          "ConnectionRole",
          "Arn"
        ]
      }
    }
  }
}
