Merge "Configure ulimits for gerrit file descriptors"
diff --git a/single-master/README.md b/single-master/README.md
index d47f899..422513d 100644
--- a/single-master/README.md
+++ b/single-master/README.md
@@ -59,7 +59,11 @@
 
 ### 0 - Prerequisites
 
-Follow the steps described in the [Prerequisites](../Prerequisites.md) section
+Follow the steps described in the [Prerequisites](../Prerequisites.md) section.
+
+Additionally, whilst it is possible to do so by using an admin user, consider
+limiting access only to what is required by using a dedicated role or user to do
+so.
 
 ### 1 - Configuration
 
@@ -124,3 +128,14 @@
 ### Docker
 
 Refer to the [Docker](../Docker.md) section for information on how to setup docker or how to publish images
+
+### Permissions
+
+In order to deploy and destroy a single-master recipe the invoking user needs to
+have the relevant permissions to perform actions on AWS resources.
+
+The list of actions can be found [here](resources/permission.policy.json).
+The document can be used to create a permission policy directly in AWS.
+
+The policy then needs to be attached to the invoking user group or alternatively
+to the invoking user directly.
\ No newline at end of file
diff --git a/single-master/resources/permission.policy.json b/single-master/resources/permission.policy.json
new file mode 100644
index 0000000..b020cff
--- /dev/null
+++ b/single-master/resources/permission.policy.json
@@ -0,0 +1,131 @@
+{
+  "Version": "2012-10-17",
+  "Statement": [
+    {
+      "Sid": "Stmt1605188574000",
+      "Effect": "Allow",
+      "Action": [
+        "autoscaling:AttachLoadBalancerTargetGroups",
+        "autoscaling:CreateAutoScalingGroup",
+        "autoscaling:CreateLaunchConfiguration",
+        "autoscaling:CreateOrUpdateTags",
+        "autoscaling:DeleteAutoScalingGroup",
+        "autoscaling:DeleteLaunchConfiguration",
+        "autoscaling:DeleteTags",
+        "autoscaling:DescribeAutoScalingGroups",
+        "autoscaling:DescribeAutoScalingInstances",
+        "autoscaling:DescribeLaunchConfigurations",
+        "autoscaling:DescribeLoadBalancerTargetGroups",
+        "autoscaling:DescribeScalingActivities",
+        "autoscaling:DetachLoadBalancerTargetGroups",
+        "autoscaling:UpdateAutoScalingGroup",
+        "cloudformation:*",
+        "cloudwatch:DeleteDashboards",
+        "cloudwatch:GetDashboard",
+        "cloudwatch:ListDashboards",
+        "cloudwatch:PutDashboard",
+        "ec2:AssociateRouteTable",
+        "ec2:AttachInternetGateway",
+        "ec2:AttachVolume",
+        "ec2:AuthorizeSecurityGroupEgress",
+        "ec2:AuthorizeSecurityGroupIngress",
+        "ec2:CreateInternetGateway",
+        "ec2:CreateKeyPair",
+        "ec2:CreateRoute",
+        "ec2:CreateRouteTable",
+        "ec2:CreateSecurityGroup",
+        "ec2:CreateSubnet",
+        "ec2:CreateVolume",
+        "ec2:CreateVpc",
+        "ec2:DeleteInternetGateway",
+        "ec2:DeleteRoute",
+        "ec2:DeleteRouteTable",
+        "ec2:DeleteSecurityGroup",
+        "ec2:DeleteSubnet",
+        "ec2:DeleteVolume",
+        "ec2:DeleteVpc",
+        "ec2:DescribeAccountAttributes",
+        "ec2:DescribeAvailabilityZones",
+        "ec2:DescribeHosts",
+        "ec2:DescribeImages",
+        "ec2:DescribeInstanceAttribute",
+        "ec2:DescribeInstances",
+        "ec2:DescribeInternetGateways",
+        "ec2:DescribeKeyPairs",
+        "ec2:DescribeRouteTables",
+        "ec2:DescribeSecurityGroups",
+        "ec2:DescribeSubnets",
+        "ec2:DescribeVolumes",
+        "ec2:DescribeVpcs",
+        "ec2:DetachInternetGateway",
+        "ec2:DetachVolume",
+        "ec2:DisassociateRouteTable",
+        "ec2:ModifySubnetAttribute",
+        "ec2:ModifyVolumeAttribute",
+        "ec2:ModifyVpcAttribute",
+        "ec2:RevokeSecurityGroupEgress",
+        "ec2:RevokeSecurityGroupIngress",
+        "ecr:BatchCheckLayerAvailability",
+        "ecr:BatchGetImage",
+        "ecr:CompleteLayerUpload",
+        "ecr:DescribeImages",
+        "ecr:GetAuthorizationToken",
+        "ecr:GetDownloadUrlForLayer",
+        "ecr:InitiateLayerUpload",
+        "ecr:ListImages",
+        "ecr:PutImage",
+        "ecr:UploadLayerPart",
+        "ecs:CreateCluster",
+        "ecs:CreateService",
+        "ecs:DeleteCluster",
+        "ecs:DeleteService",
+        "ecs:DeregisterTaskDefinition",
+        "ecs:DescribeClusters",
+        "ecs:DescribeContainerInstances",
+        "ecs:DescribeServices",
+        "ecs:DescribeTaskDefinition",
+        "ecs:DescribeTasks",
+        "ecs:ListClusters",
+        "ecs:ListServices",
+        "ecs:ListTaskDefinitionFamilies",
+        "ecs:ListTaskDefinitions",
+        "ecs:ListTasks",
+        "ecs:RegisterTaskDefinition",
+        "elasticloadbalancing:*",
+        "iam:AddRoleToInstanceProfile",
+        "iam:AttachRolePolicy",
+        "iam:CreateInstanceProfile",
+        "iam:CreateRole",
+        "iam:DeleteInstanceProfile",
+        "iam:DeleteRole",
+        "iam:DeleteRolePolicy",
+        "iam:GetRole",
+        "iam:GetRolePolicy",
+        "iam:ListAttachedRolePolicies",
+        "iam:ListRolePolicies",
+        "iam:ListRoles",
+        "iam:PassRole",
+        "iam:PutRolePolicy",
+        "iam:RemoveRoleFromInstanceProfile",
+        "logs:*",
+        "route53:ChangeResourceRecordSets",
+        "route53:GetChange",
+        "route53:GetHostedZone",
+        "route53:ListHostedZones",
+        "route53:ListHostedZonesByName",
+        "route53:ListResourceRecordSets",
+        "s3:CreateBucket",
+        "s3:GetObject",
+        "s3:ListBucket",
+        "s3:PutObject",
+        "ssm:DescribeParameters",
+        "ssm:GetParameter",
+        "ssm:GetParameters",
+        "ssm:PutParameter"
+      ],
+      "Resource": [
+        "*"
+      ]
+    }
+  ]
+}
\ No newline at end of file