diff --git a/infra/modules/deployer-access/manage-ecs-service-policy.tf b/infra/modules/deployer-access/manage-ecs-service-policy.tf deleted file mode 100644 index 3491d2fa2..000000000 --- a/infra/modules/deployer-access/manage-ecs-service-policy.tf +++ /dev/null @@ -1,308 +0,0 @@ -data "aws_iam_policy_document" "ecs_service" { - source_policy_documents = [ - data.aws_iam_policy_document.ecs.json, - data.aws_iam_policy_document.alb.json, - data.aws_iam_policy_document.autoscaling.json, - data.aws_iam_policy_document.logs.json, - ] -} - -resource "aws_iam_policy" "ecs_service" { - policy = data.aws_iam_policy_document.ecs_service.json -} - -resource "aws_iam_role_policy_attachment" "ecs_service" { - policy_arn = aws_iam_policy.ecs_service.arn - role = aws_iam_role.deployer.id -} - -data "aws_iam_policy_document" "ecs" { - #checkov:skip=CKV_AWS_111: allow write access without constraint when needed - #checkov:skip=CKV_AWS_356: allow resource * when needed - - statement { - sid = "ManageS3" - actions = [ - "s3:PutObject", - "s3:GetObject", - "s3:ListBucket" - ] - resources = [ - "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate/*", - "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate", - ] - effect = "Allow" - } - - statement { - sid = "ReleaseTerraformStateLock" - actions = [ - "s3:DeleteObject", - ] - resources = [ - "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate/*.tflock" - ] - effect = "Allow" - } - - statement { - sid = "DescribeECSClustersAndServices" - actions = [ - "ecs:Describe*", - "ecs:List*", - ] - resources = ["*"] - effect = "Allow" - } - - statement { - sid = "ManageECSClustersAndServices" - actions = [ - "ecs:*Cluster", - "ecs:*Service", - "ecs:TagResource", - "ecs:UntagResource", - "ecs:ListTagsForResource", - ] - resources = ["arn:aws:ecs:eu-west-2:${var.account_id}:*"] - effect = "Allow" - } - - statement { - sid = "ManageEcsTaskDefinitions" - actions = [ - "ecs:*TaskDefinition", - "ecs:*TaskSet", - "ecs:RunTask", - "ecs:DescribeTasks" - ] - resources = ["*"] - effect = "Allow" - } - - statement { - sid = "ManageTaskAndTaskExecutionRoles" - actions = [ - "iam:AttachRolePolicy", - "iam:CreateRole", - "iam:DeleteRolePolicy", - "iam:DetachRolePolicy", - "iam:PassRole", - "iam:PutRolePermissionsBoundary", - "iam:PutRolePolicy", - "iam:GetRole", - "iam:GetRolePolicy", - "iam:ListRolePolicies", - "iam:ListAttachedRolePolicies", - "iam:UpdateAssumeRolePolicy", - "iam:TagRole" - ] - resources = [ - "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-admin-ecs-task", - "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-runner-ecs-task", - "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-product-page-ecs-task", - "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-admin-ecs-task-execution", - "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-runner-ecs-task-execution", - "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-product-page-ecs-task-execution", - "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-runner-queue-worker-ecs-task-execution" - ] - effect = "Allow" - } - - statement { - sid = "ManageEcsExecutionPolicies" - actions = [ - "iam:*Policy", - "iam:*PolicyVersion", - "iam:*PolicyVersions", - "iam:*RolePolicy", - "iam:*AssumeRolePolicy" - ] - resources = [ - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-admin-ecs-task-execution-additional", - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-runner-ecs-task-execution-additional", - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-product-page-ecs-task-execution-additional", - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-runner-queue-worker-ecs-task-execution-additional" - ] - effect = "Allow" - } - - statement { - sid = "ManageEcsTaskPolicies" - actions = [ - "iam:*Policy", - "iam:*PolicyVersion", - "iam:*PolicyVersions", - "iam:*RolePolicy", - "iam:*AssumeRolePolicy" - ] - resources = [ - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-admin-ecs-task-policy", - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-admin-adot-collector", - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-runner-ecs-task-policy", - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-runner-adot-collector", - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-product-page-ecs-task-policy", - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-product-page-adot-collector" - ] - effect = "Allow" - } - - - statement { - sid = "ManageSecurityGroups" - actions = [ - "ec2:*SecurityGroup*", - ] - resources = [ - "arn:aws:ec2:eu-west-2:${var.account_id}:*/*" - ] - effect = "Allow" - } - - statement { - sid = "DescribeEC2" - actions = [ - "ec2:Describe*" - ] - resources = [ - "*" - ] - effect = "Allow" - } - - statement { - sid = "ManageEC2Tags" - actions = [ - "ec2:CreateTags" - ] - resources = [ - "arn:aws:ec2:eu-west-2:${var.account_id}:*/*" - ] - effect = "Allow" - } -} - -data "aws_iam_policy_document" "alb" { - #checkov:skip=CKV_AWS_111: allow write access without constraint when needed - #checkov:skip=CKV_AWS_356: allow resource * when needed - - statement { - sid = "ManageAlb" - actions = [ - "elasticloadbalancing:*Tags", - "elasticloadbalancing:*TargetGroup*", - "elasticloadbalancing:RegisterTargets", - "elasticloadbalancing:*Listener", - "elasticloadbalancing:*Rule*", - "elasticloadbalancing:*LoadBalancer*", - "elasticloadbalancing:SetWebACL", - ] - resources = [ - "arn:aws:elasticloadbalancing:eu-west-2:${var.account_id}:*" - ] - effect = "Allow" - } - - statement { - sid = "ListAlbResources" - actions = [ - "elasticloadbalancing:Describe*", - ] - resources = [ - "*" - ] - effect = "Allow" - } -} - -data "aws_iam_policy_document" "autoscaling" { - #checkov:skip=CKV_AWS_111: allow write access without constraint when needed - #checkov:skip=CKV_AWS_356: allow resource * when needed - - statement { - sid = "ManageApplicationAutoScaling" - actions = [ - "application-autoscaling:*" - ] - resources = ["*"] - effect = "Allow" - } - - statement { - sid = "ManageServiceLinkedRoleForAutoscaling" - actions = [ - "iam:CreateServiceLinkedRole" - ] - resources = ["arn:aws:iam::*:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService" - ] - effect = "Allow" - condition { - test = "StringLike" - variable = "iam:AWSServiceName" - values = ["ecs.application-autoscaling.amazonaws.com"] - } - } - - statement { - sid = "AllowPassingServiceLinkedRole" - actions = [ - "iam:PassRole" - ] - resources = [ - "arn:aws:iam::*:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService" - ] - effect = "Allow" - } - - statement { - sid = "ManageCloudWatchAlarms" - actions = [ - "cloudwatch:*Alarms", - "cloudwatch:*Alarm", - "cloudwatch:ListTagsForResource", - "cloudwatch:TagResource" - ] - resources = [ - "arn:aws:cloudwatch:eu-west-2:${var.account_id}:*", - "arn:aws:cloudwatch:us-east-1:${var.account_id}:*", - ] - effect = "Allow" - } -} - -data "aws_iam_policy_document" "logs" { - #checkov:skip=CKV_AWS_111: allow write access without constraint when needed - #checkov:skip=CKV_AWS_356: allow resource * when needed - statement { - sid = "CreateLogs" - actions = [ - "logs:*LogEvents", - "logs:*LogStream", - "logs:*SubscriptionFilters", - "logs:*SubscriptionFilter", - "logs:*LogGroup" - ] - resources = [ - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-admin-${var.environment_name}:*", - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-admin-${var.environment_name}/adot-collector:*", - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-runner-${var.environment_name}:*", - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-runner-${var.environment_name}/adot-collector:*", - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-runner-queue-worker-${var.environment_name}:*", - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-runner-queue-worker-${var.environment_name}/adot-collector:*", - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-product-page-${var.environment_name}:*", - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-product-page-${var.environment_name}/adot-collector:*", - ] - effect = "Allow" - } - - statement { - sid = "DescribeLogGroups" - actions = [ - "logs:DescribeLogGroups" - ] - resources = [ - "*" - ] - effect = "Allow" - } -} diff --git a/infra/modules/deployer-access/manage-environment-policy.tf b/infra/modules/deployer-access/manage-environment-policy.tf deleted file mode 100644 index d0043fb32..000000000 --- a/infra/modules/deployer-access/manage-environment-policy.tf +++ /dev/null @@ -1,278 +0,0 @@ -data "aws_iam_policy_document" "environment" { - source_policy_documents = [ - data.aws_iam_policy_document.acm_cert_with_dns_validation.json, - data.aws_iam_policy_document.cloudfront.json, - data.aws_iam_policy_document.public_bucket.json, - data.aws_iam_policy_document.secure_bucket.json, - data.aws_iam_policy_document.network.json, - ] -} - -resource "aws_iam_policy" "environment" { - policy = data.aws_iam_policy_document.environment.json -} - -resource "aws_iam_role_policy_attachment" "environment" { - policy_arn = aws_iam_policy.environment.arn - role = aws_iam_role.deployer.id -} - -data "aws_iam_policy_document" "acm_cert_with_dns_validation" { - statement { - sid = "ManageCertificates" - effect = "Allow" - actions = [ - "acm:*Certificate*", - ] - resources = [ - # TODO: Why does it need both regions? - # https://trello.com/c/enOX8GRF/3454-investigate-why-policy-document-acmcertwithdnsvalidation-needs-access-to-both-eu-west-2-and-us-east-1 - "arn:aws:acm:eu-west-2:${var.account_id}:certificate/*", - "arn:aws:acm:us-east-1:${var.account_id}:certificate/*" - ] - } - - statement { - sid = "ListHostedZones" - effect = "Allow" - actions = [ - "route53:ListHostedZones", - ] - resources = [ - "*" - ] - } - - # duplicate - statement { - sid = "ManageRoute53RecordSets" - effect = "Allow" - actions = [ - "route53:ChangeResourceRecordSets", - "route53:GetHostedZone", - "route53:ListResourceRecordSets", - "route53:ListTagsForResource", - ] - resources = [ - "arn:aws:route53:::hostedzone/${var.hosted_zone_id}", - "arn:aws:route53:::hostedzone/${var.private_internal_zone_id}" - ] - } -} - -data "aws_iam_policy_document" "cloudfront" { - #checkov:skip=CKV_AWS_356 - statement { - sid = "ManageCloudfrontDistribution" - effect = "Allow" - actions = [ - "cloudfront:AssociateAlias", - "cloudfront:TagResource", - "cloudfront:UntagResource", - "cloudfront:*Distribution*", - ] - resources = [ - "arn:aws:cloudfront::${var.account_id}:distribution/*" - ] - } - - statement { - sid = "GetPoliciesCloudfront" - effect = "Allow" - actions = [ - "cloudfront:GetResponseHeadersPolicy", - "cloudfront:GetCachePolicy", - "cloudfront:GetOriginRequestPolicy", - "cloudfront:ListResponseHeadersPolicies", - "cloudfront:ListCachePolicies", - "cloudfront:ListOriginRequestPolicies", - ] - resources = [ - "arn:aws:cloudfront::${var.account_id}:*" - ] - } - - statement { - sid = "ManageWAFv2WebACL" - effect = "Allow" - actions = [ - "wafv2:*WebACL", - "wafv2:*LoggingConfiguration", - "wafv2:ListTagsForResource", - "wafv2:TagResource", - "wafv2:UntagResource", - "wafv2:*RuleGroup", - "wafv2:*RegexPatternSet", - ] - # TODO: The scope of this should be cloudfront but for some reason it needs global - # https://trello.com/c/JCyMcRip/3455-investigate-why-managewafv2webacl-needs-global-scope-instead-of-just-cloudfront - resources = [ - "arn:aws:wafv2:us-east-1:${var.account_id}:global/webacl/cloudfront_waf_${var.environment_name}/*", - "arn:aws:wafv2:eu-west-2:${var.account_id}:regional/webacl/alb_${var.environment_name}/*", - "arn:aws:wafv2:us-east-1:${var.account_id}:global/ipset/${var.environment_name}-*", - "arn:aws:wafv2:eu-west-2:${var.account_id}:regional/ipset/${var.environment_name}-*", - "arn:aws:wafv2:us-east-1:${var.account_id}:global/rulegroup/${var.environment_name}-*/*", - "arn:aws:wafv2:us-east-1:${var.account_id}:global/regexpatternset/${var.environment_name}-*", - - # This ARN pattern is owned by AWS, but we make a change to it when we override part of the rule - "arn:aws:wafv2:us-east-1:153427709519:global/rulegroup/ShieldMitigationRuleGroup_*" - ] - } - - statement { - sid = "ManageWAFRuleSet" - effect = "Allow" - actions = [ - "wafv2:CreateWebACL", - "wafv2:PutManagedRuleSetVersions", - "wafv2:UpdateWebACL", - ] - resources = [ - "arn:aws:wafv2:us-east-1:${var.account_id}:global/managedruleset/*" - ] - } - - statement { - sid = "ManageIPSets" - effect = "Allow" - actions = [ - "wafv2:DeleteIPSet", - "wafv2:CreateIPSet", - "wafv2:UpdateIPSet", - "wafv2:TagResource", - "wafv2:UntagResource", - ] - resources = [ - "arn:aws:wafv2:us-east-1:${var.account_id}:global/ipset/*", - "arn:aws:wafv2:us-east-1:${var.account_id}:regional/ipset/*", - "arn:aws:wafv2:eu-west-2:${var.account_id}:global/ipset/*", - "arn:aws:wafv2:eu-west-2:${var.account_id}:regional/ipset/*", - ] - } - - statement { - sid = "ManageWebACL" - effect = "Allow" - actions = [ - "wafv2:*LoggingConfiguration", - "wafv2:CreateWebACL", - "wafv2:DeleteWebACL", - "wafv2:UpdateWebACL", - ] - resources = [ - "arn:aws:wafv2:us-east-1:${var.account_id}:regional/webacl/*", - "arn:aws:wafv2:eu-west-2:${var.account_id}:regional/webacl/*" - ] - } - - statement { - sid = "ManageCloudwatchLogsWAF" - effect = "Allow" - actions = [ - "logs:*LogEvents", - "logs:*LogStream", - "logs:*SubscriptionFilters", - "logs:*SubscriptionFilter", - "logs:*LogGroup", - "logs:PutRetentionPolicy", - ] - resources = [ - "arn:aws:logs:us-east-1:${var.account_id}:log-group:aws-waf-logs-${var.environment_name}*", - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:aws-waf-logs-alb-${var.environment_name}*" - ] - } - - statement { - sid = "ManageCloudwatchLogs" - effect = "Allow" - actions = [ - "logs:DescribeLogGroups", - "logs:*LogDelivery", - "logs:PutResourcePolicy", - "logs:DescribeResourcePolicies", - "logs:TagResource" - ] - resources = [ - "*", - ] - } - - statement { - sid = "CreateServiceLinkedRoleForWAF" - effect = "Allow" - actions = [ - "iam:CreateServiceLinkedRole" - ] - resources = [ - "arn:aws:iam::${var.account_id}:role/*" - ] - condition { - test = "StringLike" - variable = "iam:AWSServiceName" - values = ["wafv2.amazonaws.com"] - } - } -} - -data "aws_iam_policy_document" "public_bucket" { - statement { - sid = "ManageErrorPageBucket" - effect = "Allow" - actions = [ - "s3:*Configuration", - "s3:*Bucket*", - "s3:*Object*", - ] - resources = [ - "arn:aws:s3:::govuk-forms-${var.environment_name}-error-page*" - ] - } -} - -data "aws_iam_policy_document" "secure_bucket" { - statement { - sid = "ManageALBandWAFLogsBucket" - effect = "Allow" - actions = [ - "s3:*Configuration", - "s3:*Bucket*", - "s3:*Object*", - ] - resources = [ - "arn:aws:s3:::govuk-forms-alb-logs-${var.environment_name}*", - ] - } -} - -data "aws_iam_policy_document" "network" { - statement { - sid = "ManageNetwork" - effect = "Allow" - actions = [ - "ec2:*VpcEndpoint*", - "ec2:*SecurityGroup*", - "ec2:*NatGateway*", - "ec2:*Address", - "ec2:*Subnet*", - "ec2:*RouteTable", - "ec2:*RouteTableAssociation", - "ec2:*Vpc", - "ec2:*InternetGateway*", - ] - resources = [ - "arn:aws:ec2:eu-west-2:${var.account_id}:*" - ] - } - - statement { - sid = "DenyTransitGateway" - # because we don't want it doing transit gateway things - effect = "Deny" - actions = [ - "ec2:*TransitGatewayRouteTable", - ] - resources = [ - "arn:aws:ec2:eu-west-2:${var.account_id}:*" - ] - } -} diff --git a/infra/modules/deployer-access/policy.tf b/infra/modules/deployer-access/policy.tf index 01d5efc84..cd021e868 100644 --- a/infra/modules/deployer-access/policy.tf +++ b/infra/modules/deployer-access/policy.tf @@ -5,42 +5,58 @@ ## data "aws_iam_policy_document" "forms_infra" { source_policy_documents = [ - data.aws_iam_policy_document.alerts.json, - data.aws_iam_policy_document.dns.json, - data.aws_iam_policy_document.monitoring.json, + data.aws_iam_policy_document.acm.json, + data.aws_iam_policy_document.application-autoscaling.json, + data.aws_iam_policy_document.application-signals.json, + data.aws_iam_policy_document.cloudformation.json, + data.aws_iam_policy_document.cloudfront.json, + data.aws_iam_policy_document.cloudwatch.json, + data.aws_iam_policy_document.code.json, # codebuild, codecommit, codepipeline, codestar-connections ] } data "aws_iam_policy_document" "forms_infra_1" { source_policy_documents = [ - data.aws_iam_policy_document.rds.json, - data.aws_iam_policy_document.redis.json, - data.aws_iam_policy_document.code_build_modules.json, - data.aws_iam_policy_document.ssm.json, - data.aws_iam_policy_document.secrets_manager.json, + data.aws_iam_policy_document.ec2.json, + data.aws_iam_policy_document.ecr.json, + data.aws_iam_policy_document.ecs.json, + data.aws_iam_policy_document.elasticache.json, + data.aws_iam_policy_document.events.json, + data.aws_iam_policy_document.guardduty.json, ] } data "aws_iam_policy_document" "forms_infra_2" { source_policy_documents = [ - data.aws_iam_policy_document.ses.json, - data.aws_iam_policy_document.ecr.json, - data.aws_iam_policy_document.eventbridge.json, - data.aws_iam_policy_document.cloudwatch_logging.json, - data.aws_iam_policy_document.shield.json, + data.aws_iam_policy_document.kms.json, + data.aws_iam_policy_document.lambda.json, + data.aws_iam_policy_document.logs.json, + data.aws_iam_policy_document.rds.json, data.aws_iam_policy_document.route53.json, - data.aws_iam_policy_document.forms_runner.json + data.aws_iam_policy_document.s3.json, ] } data "aws_iam_policy_document" "forms_infra_3" { source_policy_documents = [ - data.aws_iam_policy_document.pipelines.json, - data.aws_iam_policy_document.application_signals.json, - data.aws_iam_policy_document.cloud_control_api.json + data.aws_iam_policy_document.secretsmanager.json, + data.aws_iam_policy_document.ses.json, + data.aws_iam_policy_document.shield.json, + data.aws_iam_policy_document.sns.json, + data.aws_iam_policy_document.sqs.json, + data.aws_iam_policy_document.ssm.json, + data.aws_iam_policy_document.wafv2.json, ] } +resource "aws_iam_role_policy_attachment" "iam" { + policy_arn = aws_iam_policy.iam.arn + role = aws_iam_role.deployer.id +} + +resource "aws_iam_policy" "iam" { + policy = data.aws_iam_policy_document.iam.json +} resource "aws_iam_policy" "forms_infra" { policy = data.aws_iam_policy_document.forms_infra.json } @@ -82,315 +98,406 @@ resource "aws_iam_role_policy_attachment" "full_read_only" { role = aws_iam_role.deployer.id } -data "aws_iam_policy_document" "alerts" { +data "aws_iam_policy_document" "acm" { statement { - sid = "ManageKMSKeyAlerts" actions = [ - "kms:EnableKeyRotation", - "kms:PutKeyPolicy", - "kms:TagResource", - "kms:UpdateKeyDescription", - "kms:UntagResource", - "kms:ScheduleKeyDeletion" + "acm:*Certificate*" ] + effect = "Allow" resources = [ - "arn:aws:kms:eu-west-2:${var.account_id}:key/*", - "arn:aws:kms:us-east-1:${var.account_id}:key/*", + "arn:aws:acm:eu-west-2:${var.account_id}:certificate/*", + "arn:aws:acm:us-east-1:${var.account_id}:certificate/*" ] - effect = "Allow" + sid = "ManageCertificates" } +} +data "aws_iam_policy_document" "application-autoscaling" { + #checkov:skip=CKV_AWS_111: allow write access without constraint when needed + #checkov:skip=CKV_AWS_356: allow resource * when needed statement { - sid = "CreateKMSKeys" - actions = ["kms:CreateKey"] - resources = ["*"] #CreateKey uses the * resource - effect = "Allow" + actions = [ + "application-autoscaling:*" + ] + effect = "Allow" + resources = [ + "*" + ] + sid = "ManageApplicationAutoScaling" } +} +data "aws_iam_policy_document" "application-signals" { statement { - sid = "CreateKMSKeyAliases" actions = [ - "kms:CreateAlias", - "kms:DeleteAlias" + "application-signals:BatchUpdateExclusionWindows", + "application-signals:CreateServiceLevelObjective", + "application-signals:UpdateServiceLevelObjective", + "application-signals:DeleteServiceLevelObjective", + "application-signals:ListServiceLevelObjectiveExclusionWindows", + "application-signals:TagResource", + "application-signals:UntagResource" ] + effect = "Allow" resources = [ - "arn:aws:kms:eu-west-2:${var.account_id}:key/*", - "arn:aws:kms:eu-west-2:${var.account_id}:alias/*", - "arn:aws:kms:us-east-1:${var.account_id}:key/*", - "arn:aws:kms:us-east-1:${var.account_id}:alias/*", + "arn:aws:application-signals:eu-west-2:${var.account_id}:slo/*" ] - effect = "Allow" + sid = "ManageApplicationSignalsSLOs" } +} + +data "aws_iam_policy_document" "cloudformation" { + # These permissions are required for the `awscc` provider to create, update, delete, and list + # Cloud Control API resources, which includes the Application Signals SLO resources. + # See: https://docs.aws.amazon.com/cloudcontrolapi/latest/userguide/security.html + + # It seems super scary to give `cloudformation:*` permissions, but the Cloud Control API + # is implemented as a layer on top of CloudFormation, and the `awscc` provider + # needs these permissions to manage resources. These permissions are essentially saying + # 'allow the deployer to use the Cloud Control API to attempt to CRUDL any resource' + # The deployer role will still be limited by the other permissions it has, so it won't be able + # to create resources we haven't explicitly given it permission for. + # eg. if we removed `s3:CreateBucket` from the deployer role, it wouldn't be able to create S3 buckets, + # even though it has `cloudformation:CreateResource` permission. statement { - sid = "ManageSNS" actions = [ - "sns:*Topic*", - "sns:*Tag*", - "sns:*Subscrib*", - "sns:Unsubscribe", - "sns:UntagResource", + "cloudformation:CreateResource", + "cloudformation:GetResource", + "cloudformation:UpdateResource", + "cloudformation:DeleteResource", + "cloudformation:ListResources" ] + effect = "Allow" resources = [ - "arn:aws:sns:eu-west-2:${var.account_id}:pagerduty_integration_${var.environment_name}", - "arn:aws:sns:eu-west-2:${var.account_id}:alert_zendesk_${var.environment_name}", - "arn:aws:sns:eu-west-2:${var.account_id}:slo-alerts", - "arn:aws:sns:us-east-1:${var.account_id}:cloudwatch-alarms", + "*" ] - effect = "Allow" + sid = "CloudControlAPIActions" } +} +data "aws_iam_policy_document" "cloudfront" { statement { - sid = "ManageCloudwatchMetricAlarms" actions = [ - "cloudwatch:*Alarm*", - "cloudwatch:*Metric*", - "cloudwatch:TagResource", - "cloudwatch:UntagResource", + "cloudfront:AssociateAlias", + "cloudfront:TagResource", + "cloudfront:UntagResource", + "cloudfront:*Distribution*" ] + effect = "Allow" resources = [ - "arn:aws:cloudwatch:eu-west-2:${var.account_id}:alarm:alb_healthy_host_count_*", - + "arn:aws:cloudfront::${var.account_id}:distribution/*" ] - effect = "Allow" + sid = "ManageCloudfrontDistribution" } -} -# This relates to the `dns` root and is different from what is covered in by the permissions in the `environment` module -data "aws_iam_policy_document" "dns" { statement { - sid = "ManageRoute53RecordSets" actions = [ - "route53:ChangeResourceRecordSets", + "cloudfront:GetResponseHeadersPolicy", + "cloudfront:GetCachePolicy", + "cloudfront:GetOriginRequestPolicy", + "cloudfront:ListResponseHeadersPolicies", + "cloudfront:ListCachePolicies", + "cloudfront:ListOriginRequestPolicies" ] + effect = "Allow" resources = [ - "arn:aws:route53:::hostedzone/${var.hosted_zone_id}" + "arn:aws:cloudfront::${var.account_id}:*" ] + sid = "GetPoliciesCloudfront" } +} +data "aws_iam_policy_document" "cloudwatch" { statement { - sid = "ManageInternalZoneAssociation" - effect = "Allow" actions = [ - "route53:AssociateVPCWithHostedZone", - "route53:DisassociateVPCFromHostedZone", + "cloudwatch:*Alarm*", + "cloudwatch:*Metric*", + "cloudwatch:*Tag*", + "cloudwatch:PutMetricAlarm", + "cloudwatch:UntagResource" ] + effect = "Allow" resources = [ - "arn:aws:route53:::hostedzone/${var.private_internal_zone_id}" + "arn:aws:cloudwatch:eu-west-2:${var.account_id}:*", + "arn:aws:cloudwatch:us-east-1:${var.account_id}:*" ] + sid = "ManageCloudWatchAlarms" } -} -data "aws_iam_policy_document" "monitoring" { statement { - sid = "ManageCloudwatchDashboards" actions = [ "cloudwatch:DeleteDashboards", "cloudwatch:PutDashboard", "cloudwatch:TagResource", - "cloudwatch:UntagResource", + "cloudwatch:UntagResource" ] + effect = "Allow" resources = [ "arn:aws:cloudwatch:*:${var.account_id}:dashboard/*" ] - effect = "Allow" + sid = "ManageCloudwatchDashboards" } + } -data "aws_iam_policy_document" "rds" { +data "aws_iam_policy_document" "code" { statement { - sid = "ManageRDS" actions = [ - "rds:*DBCluster*", - "rds:*DBInstance*", - "rds:*SecurityGroup*", - "rds:*SubnetGroup*", - "rds:*Tag*", + "codebuild:*Project*", + "codebuild:*Build*" ] + effect = "Allow" resources = [ - "arn:aws:rds:eu-west-2:${var.account_id}:*" + "arn:aws:codebuild:eu-west-2:${var.account_id}:project/*" ] - effect = "Allow" + sid = "ManageCodebuild" } -} -data "aws_iam_policy_document" "redis" { statement { - sid = "ManageElasticache" actions = [ - "elasticache:*CacheCluster*", - "elasticache:*CacheParameter*", - "elasticache:*CacheSubnetGroup*", - "elasticache:*CacheSecurityGroup*", - "elasticache:*ReplicationGroup*", - "elasticache:*Tags*", + "codecommit:GitPull" ] + effect = "Allow" resources = [ - "arn:aws:elasticache:eu-west-2:${var.account_id}:*", + "${var.codestar_connection_arn}" ] } -} -data "aws_iam_policy_document" "ses" { - #checkov:skip=CKV_AWS_111:We use SES v1 which doesn't let us be more specific than * - #checkov:skip=CKV_AWS_356:We use SES v1 which doesn't let us be more specific than * - #checkov:skip=CKV_AWS_109:We have a plan to add a permissions boundary to the deployer statement { - sid = "GetUser" - effect = "Allow" actions = [ - "iam:AttachUserPolicy", - "iam:DeleteUserPolicy", - "iam:DetachUserPolicy", - "iam:UntagUser", + "codepipeline:CreatePipeline", + "codepipeline:DeletePipeline", + "codepipeline:UpdatePipeline", + "codepipeline:TagResource", + "codepipeline:UntagResource" ] + effect = "Allow" resources = [ - "arn:aws:iam::${var.account_id}:user/auth0" + "arn:aws:codepipeline:eu-west-2:${var.account_id}:*" ] + sid = "ManagePipelines" } statement { - sid = "AllowManageSESTagging" - effect = "Allow" actions = [ - "ses:*Tag*", - "ses:UntagResource" + "codestar-connections:UseConnection", + "codestar-connections:PassConnection" + ] + effect = "Allow" + resources = [ + "${var.codestar_connection_arn}" ] - resources = ["*"] } +} +data "aws_iam_policy_document" "ec2" { statement { - sid = "ManageSESPolicies" + actions = [ + "ec2:*SecurityGroup*" + ] effect = "Allow" + resources = [ + "arn:aws:ec2:eu-west-2:${var.account_id}:*/*" + ] + sid = "ManageSecurityGroups" + } + + statement { actions = [ - "iam:CreatePolicy", - "iam:CreatePolicyVersion", - "iam:DeletePolicy", - "iam:DeletePolicyVersion", - "iam:TagPolicy", - "iam:UntagPolicy", + "ec2:*TransitGatewayRouteTable" ] + effect = "Deny" resources = [ - "arn:aws:iam::${var.account_id}:policy/ses_sender" + "arn:aws:ec2:eu-west-2:${var.account_id}:*" ] + sid = "DenyTransitGateway" } statement { - sid = "ManageSESVerification" - effect = "Allow" actions = [ - "ses:*Dkim*", - "ses:*EmailAddress*", - "ses:*Domain*", - "ses:VerifyEmailIdentity", - "ses:*Identity*" + "ec2:CreateTags", + "ec2:*VpcEndpoint*", + "ec2:*SecurityGroup*", + "ec2:*NatGateway*", + "ec2:*Address", + "ec2:*Subnet*", + "ec2:*RouteTable", + "ec2:*RouteTableAssociation", + "ec2:*Vpc", + "ec2:*InternetGateway*" ] + effect = "Allow" resources = [ - "*" + "arn:aws:ec2:eu-west-2:${var.account_id}:*" ] + sid = "ManageNetwork" } +} +data "aws_iam_policy_document" "ecr" { statement { - sid = "ManageSESConfigurationSet" + actions = [ + "ecr:*" + ] effect = "Allow" + resources = [ + "arn:aws:ecr:eu-west-2:${var.deploy_account_id}:*" + ] + } + + statement { actions = [ - "ses:*ConfigurationSet*", + "ecr:GetAuthorizationToken" ] + effect = "Allow" resources = [ "*" ] } +} +data "aws_iam_policy_document" "ecs" { + #checkov:skip=CKV_AWS_111: allow write access without constraint when needed + #checkov:skip=CKV_AWS_356: allow resource * when needed statement { - sid = "ManageKMSKeySES" - effect = "Allow" actions = [ - "kms:CreateKey", - "kms:EnableKeyRotation", - "kms:PutKeyPolicy", - "kms:TagResource", - "kms:UntagResource", + "ecs:*Cluster", + "ecs:*Service", + "ecs:TagResource", + "ecs:UntagResource", + "ecs:ListTagsForResource" ] + effect = "Allow" resources = [ - "arn:aws:kms:eu-west-2:${var.account_id}:key/*", + "arn:aws:ecs:eu-west-2:${var.account_id}:*" ] + sid = "ManageECSClustersAndServices" } statement { - sid = "ManageAccessKeys" - effect = "Allow" actions = [ - "iam:CreateAccessKey" + "ecs:*TaskDefinition", + "ecs:*TaskSet", + "ecs:RunTask" ] + effect = "Allow" resources = [ - "arn:aws:iam::${var.account_id}:user/auth0" + "*" ] + sid = "ManageEcsTaskDefinitions" } +} +data "aws_iam_policy_document" "elasticache" { statement { - sid = "ManageSQS" - effect = "Allow" actions = [ - "sqs:*queue*" + "elasticache:*CacheCluster*", + "elasticache:*CacheParameter*", + "elasticache:*CacheSubnetGroup*", + "elasticache:*CacheSecurityGroup*", + "elasticache:*ReplicationGroup*", + "elasticache:*Tags*" ] resources = [ - "arn:aws:sqs:eu-west-2:${var.account_id}:*" + "arn:aws:elasticache:eu-west-2:${var.account_id}:*" ] + sid = "ManageElasticache" } statement { - sid = "ManageSNS" actions = [ - "sns:*Topic*", - "sns:*Tag*", - "sns:*Subscrib*", - "sns:Unsubscribe", - "sns:UntagResource", + "elasticloadbalancing:*Tags", + "elasticloadbalancing:*TargetGroup*", + "elasticloadbalancing:RegisterTargets", + "elasticloadbalancing:*Listener", + "elasticloadbalancing:*Rule*", + "elasticloadbalancing:*LoadBalancer*", + "elasticloadbalancing:SetWebACL" ] + effect = "Allow" resources = [ - "arn:aws:sns:eu-west-2:${var.account_id}:ses_bounces_and_complaints", # TODO: remove me once all envs use the new queues https://trello.com/c/BCDU9U7N/3456-remove-sesbouncesandcomplaints-sns-resource-if-all-environments-are-using-the-new-queues - "arn:aws:sns:eu-west-2:${var.account_id}:auth0_ses_bounces_and_complaints", - "arn:aws:sns:eu-west-2:${var.account_id}:submission_email_ses_bounces_and_complaints", - "arn:aws:sns:eu-west-2:${var.account_id}:submission_email_ses_successful_deliveries", + "arn:aws:elasticloadbalancing:eu-west-2:${var.account_id}:*" ] - effect = "Allow" + sid = "ManageAlb" } } -data "aws_iam_policy_document" "code_build_modules" { - # These are needed for: - # code-build-build - # code-build-run-docker-build - # code-build-run-smoke-tests +data "aws_iam_policy_document" "events" { + #checkov:skip=CKV_AWS_356: resource "*" is restricted to events actions + #checkov:skip=CKV_AWS_111: there are many event resources the deployer + # role will write to, and adding conditions for + # each will add a lot to an already constrained + # character count statement { - sid = "ManageLogs" + actions = [ + "events:*" + ] effect = "Allow" + resources = [ + "*" + ] + sid = "AllowEventActions" + } +} + +data "aws_iam_policy_document" "guardduty" { + statement { actions = [ - "logs:*LogEvents", - "logs:*LogStream", - "logs:*SubscriptionFilters", - "logs:*SubscriptionFilter", - "logs:*LogGroup", + "guardduty:CreateMalwareProtectionPlan", + "guardduty:DeleteMalwareProtectionPlan", + "guardduty:GetMalwareProtectionPlan", + "guardduty:TagResource", + "guardduty:UntagResource", + "guardduty:UpdateMalwareProtectionPlan" ] + effect = "Allow" resources = [ - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/codebuild/*", - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:codebuild/*" + "arn:aws:guardduty:eu-west-2:${var.account_id}:malware-protection-plan/*" ] + sid = "ManageMalwareProtectionPlan" } +} +data "aws_iam_policy_document" "iam" { + statement { - sid = "ManageCodebuild" + actions = [ + "iam:*Policy", + "iam:*PolicyVersion", + "iam:*PolicyVersions", + "iam:*RolePolicy", + "iam:*AssumeRolePolicy" + ] effect = "Allow" + resources = [ + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-admin-ecs-task-execution-additional", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-runner-ecs-task-execution-additional", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-product-page-ecs-task-execution-additional", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-runner-queue-worker-ecs-task-execution-additional", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-admin-ecs-task-policy", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-admin-adot-collector", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-runner-ecs-task-policy", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-runner-adot-collector", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-product-page-ecs-task-policy", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-forms-product-page-adot-collector" + ] + sid = "ManageEcsPolicies" + } + + statement { actions = [ - "codebuild:*Project*", - "codebuild:*Build*", + "iam:*Role", + "iam:*RolePolicy" ] + effect = "Allow" resources = [ - "arn:aws:codebuild:eu-west-2:${var.account_id}:project/*" + "arn:aws:iam::${var.account_id}:role/${var.environment_name}-lambda-pipeline-invoker", + "arn:aws:iam::${var.account_id}:role/${var.environment_name}-lambda-paused-pipeline-invoker" ] + sid = "ManageRelatedIAMRoles" } + statement { - sid = "ManageRoles" - effect = "Allow" actions = [ "iam:AttachRolePolicy", "iam:CreateRole", @@ -399,161 +506,257 @@ data "aws_iam_policy_document" "code_build_modules" { "iam:DetachRolePolicy", "iam:DeleteRole", "iam:PassRole", - "iam:PutRolePermissionsBoundary", "iam:PutRolePolicy", "iam:TagRole" ] + effect = "Allow" resources = [ "arn:aws:iam::${var.account_id}:policy/codebuild-*", "arn:aws:iam::${var.account_id}:role/codebuild-*", "arn:aws:iam::${var.account_id}:role/${var.environment_name}-event-bridge-*", "arn:aws:iam::${var.account_id}:role/event-bridge-actor", - "arn:aws:iam::${var.account_id}:role/deployer-${var.environment_name}" + "arn:aws:iam::${var.account_id}:role/deployer-${var.environment_name}", + "arn:aws:iam::${var.account_id}:role/malware-protection-for-s3" ] + sid = "ManageRoles" } + statement { - sid = "ManagePolicies" + actions = [ + "iam:AttachRolePolicy", + "iam:CreateRole", + "iam:DeleteRolePolicy", + "iam:DetachRolePolicy", + "iam:PassRole", + "iam:PutRolePermissionsBoundary", + "iam:PutRolePolicy", + "iam:UpdateAssumeRolePolicy", + "iam:TagRole" + ] effect = "Allow" + resources = [ + "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-admin-ecs-task", + "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-runner-ecs-task", + "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-product-page-ecs-task", + "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-admin-ecs-task-execution", + "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-runner-ecs-task-execution", + "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-product-page-ecs-task-execution", + "arn:aws:iam::${var.account_id}:role/${var.environment_name}-forms-runner-queue-worker-ecs-task-execution" + ] + sid = "ManageTaskAndTaskExecutionRoles" + } + + statement { actions = [ - "iam:CreatePolicyVersion", - "iam:CreatePolicy", - "iam:DeletePolicy", - "iam:TagPolicy" + "iam:AttachRolePolicy", + "iam:CreateServiceLinkedRole", + "iam:CreateRole", + "iam:DeleteRole", + "iam:DeleteRolePolicy", + "iam:DetachRolePolicy", + "iam:PassRole", + "iam:PutRolePolicy", + "iam:TagRole", + "iam:UpdateRole" ] + effect = "Allow" resources = [ - "arn:aws:iam::${var.account_id}:policy/codebuild-*", - "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-event-bridge-*", + "arn:aws:iam::${var.account_id}:role/shield-response-team", + "arn:aws:iam::${var.account_id}:role/aws-service-role/shield.amazonaws.com/AWSServiceRoleForAWSShield" ] + sid = "ShieldPermissionsIAM" } -} -data "aws_iam_policy_document" "pipelines" { statement { actions = [ - "codestar-connections:UseConnection", - "codestar-connections:PassConnection" + "iam:AttachRolePolicy", + "iam:CreateServiceLinkedRole", + "iam:CreateRole", + "iam:DeleteRole", + "iam:DeleteRolePolicy", + "iam:DetachRolePolicy", + "iam:PutRolePolicy", + "iam:TagRole", + "iam:UpdateAssumeRolePolicy", + "iam:UpdateRole" ] - resources = [var.codestar_connection_arn] - effect = "Allow" + resources = [ + "arn:aws:iam::${var.account_id}:role/govuk-forms-submissions-to-s3-${var.environment_name}", + "arn:aws:iam::${var.account_id}:role/govuk-s3-end-to-end-test-${var.environment_name}" + ] + sid = "ManageRunnerSpecificRoles" } statement { - actions = ["codecommit:GitPull"] - resources = [var.codestar_connection_arn] - effect = "Allow" + actions = [ + "iam:AttachUserPolicy", + "iam:DeleteUserPolicy", + "iam:DetachUserPolicy", + "iam:UntagUser" + ] + effect = "Allow" + resources = [ + "arn:aws:iam::${var.account_id}:user/auth0" + ] + sid = "GetUser" } statement { - sid = "ManageArtifactBuckets" - effect = "Allow" - actions = ["s3:*"] - resources = ["arn:aws:s3:::pipeline-*", "arn:aws:s3:::pipeline-*/*"] + actions = [ + "iam:CreateAccessKey" + ] + effect = "Allow" + resources = [ + "arn:aws:iam::${var.account_id}:user/auth0" + ] + sid = "ManageAccessKeys" } statement { - sid = "ManageLambdaBuckets" - effect = "Allow" - actions = ["s3:*"] + actions = [ + "iam:CreatePolicy", + "iam:CreatePolicyVersion", + "iam:DeletePolicy", + "iam:DeletePolicyVersion", + "iam:TagPolicy", + "iam:UntagPolicy" + ] + effect = "Allow" resources = [ - "arn:aws:s3:::govuk-forms-*-pipeline-invoker", - "arn:aws:s3:::govuk-forms-*-pipeline-invoker/*", - - "arn:aws:s3:::govuk-forms-*-paused-pipeline-detection", - "arn:aws:s3:::govuk-forms-*-paused-pipeline-detection/*", - - "arn:aws:s3:::govuk-forms-*-paused-pipeline-detection-access-logs", - "arn:aws:s3:::govuk-forms-*-paused-pipeline-detection-access-logs/*", - - "arn:aws:s3:::govuk-forms-*-pipeline-invoker-access-logs", - "arn:aws:s3:::govuk-forms-*-pipeline-invoker-access-logs/*", + "arn:aws:iam::${var.account_id}:policy/allow-malware-scanning-for-s3", + "arn:aws:iam::${var.account_id}:policy/ses_sender", + "arn:aws:iam::${var.account_id}:policy/codebuild-*", + "arn:aws:iam::${var.account_id}:policy/${var.environment_name}-event-bridge-*" ] + sid = "ManageMalwareProtectionPoliciesforS3" } statement { - sid = "ManageFormsRunnerBuckets" - effect = "Allow" - actions = ["s3:*"] + actions = [ + "iam:CreateServiceLinkedRole" + ] + condition { + test = "StringLike" + values = ["application-signals.cloudwatch.amazonaws.com"] + variable = "iam:AWSServiceName" + } + effect = "Allow" resources = [ - "arn:aws:s3:::govuk-forms-${var.environment_name}-file-upload*", + "arn:aws:iam::${var.account_id}:role/aws-service-role/application-signals.cloudwatch.amazonaws.com/AWSServiceRoleForCloudWatchApplicationSignals" ] + sid = "CloudWatchApplicationSignalsCreateServiceLinkedRolePermissions" } statement { - sid = "ManageStateBucketAccessLogs" - effect = "Allow" - actions = ["s3:*"] + actions = [ + "iam:CreateServiceLinkedRole" + ] + condition { + test = "StringLike" + values = ["wafv2.amazonaws.com"] + variable = "iam:AWSServiceName" + } + effect = "Allow" resources = [ - "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate-access-logs", - "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate-access-logs/*", + "arn:aws:iam::${var.account_id}:role/*" ] + sid = "CreateServiceLinkedRoleForWAF" } statement { - sid = "ManageALBAccessLogsAccessLogs" - effect = "Allow" - actions = ["s3:*"] + actions = [ + "iam:CreateServiceLinkedRole" + ] + condition { + test = "StringLike" + values = ["ecs.application-autoscaling.amazonaws.com"] + variable = "iam:AWSServiceName" + } + effect = "Allow" resources = [ - "arn:aws:s3:::*-alb-access-logs-access-logs", - "arn:aws:s3:::*-alb-access-logs-access-logs/*", + "arn:aws:iam::*:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService" ] + sid = "ManageServiceLinkedRoleForAutoscaling" } statement { - sid = "ManageMalwareProtectionRoleforS3" - effect = "Allow" actions = [ - "iam:AttachRolePolicy", - "iam:CreateRole", - "iam:DeleteRole", - "iam:DeleteRolePolicy", - "iam:DetachRolePolicy", - "iam:GetRole", - "iam:ListAttachedRolePolicies", - "iam:PassRole", - "iam:PutRolePolicy", - "iam:TagRole", - "iam:UpdateRole", + "iam:PassRole" ] + condition { + test = "StringLike" + values = ["events.amazonaws.com"] + variable = "iam:PassedToService" + } + effect = "Allow" resources = [ - "arn:aws:iam::${var.account_id}:role/malware-protection-for-s3" + "arn:aws:iam::*:role/*" ] + sid = "AllowPassRoleForEventBridge" } statement { - sid = "ManageMalwareProtectionPoliciesforS3" - effect = "Allow" actions = [ - "iam:CreatePolicy", - "iam:CreatePolicyVersion", - "iam:DeletePolicy", - "iam:DeletePolicyVersion", - "iam:TagPolicy", - "iam:UntagPolicy", + "iam:PassRole" ] + effect = "Allow" resources = [ - "arn:aws:iam::${var.account_id}:policy/allow-malware-scanning-for-s3" + "arn:aws:iam::*:role/aws-service-role/ecs.application-autoscaling.amazonaws.com/AWSServiceRoleForApplicationAutoScaling_ECSService" ] + sid = "AllowPassingServiceLinkedRole" } +} + +data "aws_iam_policy_document" "kms" { + statement { - sid = "ManageMalwareProtectionPlan" + actions = [ + "kms:CreateAlias", + "kms:DeleteAlias" + ] effect = "Allow" + resources = [ + "arn:aws:kms:eu-west-2:${var.account_id}:key/*", + "arn:aws:kms:eu-west-2:${var.account_id}:alias/*", + "arn:aws:kms:us-east-1:${var.account_id}:key/*", + "arn:aws:kms:us-east-1:${var.account_id}:alias/*" + ] + sid = "CreateKMSKeyAliases" + } + + + statement { actions = [ - "guardduty:CreateMalwareProtectionPlan", - "guardduty:DeleteMalwareProtectionPlan", - "guardduty:GetMalwareProtectionPlan", - "guardduty:TagResource", - "guardduty:UntagResource", - "guardduty:UpdateMalwareProtectionPlan", + "kms:CreateKey" ] + effect = "Allow" resources = [ - "arn:aws:guardduty:eu-west-2:${var.account_id}:malware-protection-plan/*" + "*" ] + sid = "CreateKMSKeys" } statement { - sid = "ManageLambdaFunctions" + actions = [ + "kms:EnableKeyRotation", + "kms:PutKeyPolicy", + "kms:TagResource", + "kms:UpdateKeyDescription", + "kms:UntagResource", + "kms:ScheduleKeyDeletion" + ] effect = "Allow" + resources = [ + "arn:aws:kms:eu-west-2:${var.account_id}:key/*", + "arn:aws:kms:us-east-1:${var.account_id}:key/*" + ] + sid = "ManageKMSKeys" + } +} + +data "aws_iam_policy_document" "lambda" { + statement { actions = [ "lambda:*Function", "lambda:*Permission", @@ -561,172 +764,271 @@ data "aws_iam_policy_document" "pipelines" { "lambda:TagResource", "lambda:UntagResource", "lambda:UpdateFunctionCode", - "lambda:UpdateFunctionConfiguration", + "lambda:UpdateFunctionConfiguration" ] - + effect = "Allow" resources = [ - "arn:aws:lambda:*:${var.account_id}:function:*", + "arn:aws:lambda:*:${var.account_id}:function:*" ] + sid = "ManageLambdaFunctions" } +} +data "aws_iam_policy_document" "logs" { + #checkov:skip=CKV_AWS_356: allow resource * when needed statement { - sid = "ManagePipelines" - effect = "Allow" actions = [ - "codepipeline:CreatePipeline", - "codepipeline:DeletePipeline", - "codepipeline:UpdatePipeline", - "codepipeline:TagResource", - "codepipeline:UntagResource", + "logs:*LogEvents", + "logs:*LogStream", + "logs:*SubscriptionFilters", + "logs:*SubscriptionFilter", + "logs:*LogGroup" ] + effect = "Allow" + resources = [ + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/codebuild/*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:codebuild/*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/lambda/*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-admin-${var.environment_name}:*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-admin-${var.environment_name}/adot-collector:*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-runner-${var.environment_name}:*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-runner-${var.environment_name}/adot-collector:*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-runner-queue-worker-${var.environment_name}:*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-runner-queue-worker-${var.environment_name}/adot-collector:*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-product-page-${var.environment_name}:*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/ecs/forms-product-page-${var.environment_name}/adot-collector:*", + "arn:aws:logs:us-east-1:${var.account_id}:log-group:aws-waf-logs-${var.environment_name}*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:aws-waf-logs-alb-${var.environment_name}*" + ] + sid = "ManageLogs" + } + statement { + actions = [ + "logs:*SubscriptionFilter" + ] resources = [ - "arn:aws:codepipeline:eu-west-2:${var.account_id}:*" + "arn:aws:logs:*:${var.deploy_account_id}:destination:kinesis-log-destination", + "arn:aws:logs:*:${var.deploy_account_id}:destination:kinesis-log-destination-us-east-1", + "arn:aws:logs:*:${var.account_id}:log-group:*:log-stream:*" ] + sid = "ManageSubscriptionFilterForCRIBL" } statement { - sid = "ManageRelatedIAMRoles" - effect = "Allow" actions = [ - "iam:*Role", - "iam:*RolePolicy", + "logs:*LogDelivery", + "logs:PutResourcePolicy", + "logs:TagResource" ] - + effect = "Allow" resources = [ - "arn:aws:iam::${var.account_id}:role/${var.environment_name}-lambda-pipeline-invoker", - "arn:aws:iam::${var.account_id}:role/${var.environment_name}-lambda-paused-pipeline-invoker" + "*" ] + sid = "ManageCloudwatchLogs" } statement { - sid = "ManageLogs" - effect = "Allow" actions = [ - "logs:*LogEvents", - "logs:*LogStream", - "logs:*SubscriptionFilters", - "logs:*SubscriptionFilter", - "logs:*LogGroup", + "logs:PutRetentionPolicy", + "logs:DeleteLogGroup", + "logs:DeleteRetentionPolicy", + "logs:DeleteSubscriptionFilter" ] + effect = "Allow" resources = [ - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:/aws/lambda/*", + "arn:aws:logs:eu-west-2:${var.account_id}:log-group:*", + "arn:aws:logs:us-east-1:${var.account_id}:log-group:*" ] } } -data "aws_iam_policy_document" "ecr" { +data "aws_iam_policy_document" "rds" { + statement { actions = [ - "ecr:*" + "rds:*DBCluster*", + "rds:*DBInstance*", + "rds:*SecurityGroup*", + "rds:*SubnetGroup*", + "rds:*Tag*" ] + effect = "Allow" resources = [ - "arn:aws:ecr:eu-west-2:${var.deploy_account_id}:*", + "arn:aws:rds:eu-west-2:${var.account_id}:*" ] - effect = "Allow" + sid = "ManageRDS" } +} +data "aws_iam_policy_document" "route53" { statement { - # CodePipeline appears to perform GetAuthorizationToken - # with resource "*", and a statement with an ARN - # like "arn:aws:ecr::ACCT_ID:*" is insufficient to grant - # it permission - actions = ["ecr:GetAuthorizationToken"] - resources = ["*"] - effect = "Allow" + actions = [ + "route53:AssociateVPCWithHostedZone", + "route53:DisassociateVPCFromHostedZone" + ] + effect = "Allow" + resources = [ + "arn:aws:route53:::hostedzone/${var.private_internal_zone_id}" + ] + sid = "ManageInternalZoneAssociation" } -} -data "aws_iam_policy_document" "eventbridge" { - #checkov:skip=CKV_AWS_356: resource "*" is restricted to events actions - #checkov:skip=CKV_AWS_111: there are many event resources the deployer - # role will write to, and adding conditions for - # each will add a lot to an already constrained - # character count statement { - sid = "AllowEventActions" - effect = "Allow" actions = [ - "events:*" + "route53:ChangeResourceRecordSets" + ] + effect = "Allow" + resources = [ + "arn:aws:route53:::hostedzone/${var.hosted_zone_id}", + "arn:aws:route53:::hostedzone/${var.private_internal_zone_id}" ] - resources = ["*"] + sid = "ManageRoute53RecordSets" } statement { - sid = "AllowPassRoleForEventBridge" - effect = "Allow" - actions = ["iam:PassRole"] - resources = ["arn:aws:iam::*:role/*"] + actions = [ + "route53:ChangeTagsForResource", + "route53:DeleteHealthCheck", + "route53:UpdateHealthCheck" + ] + effect = "Allow" + resources = [ + "arn:aws:cloudwatch:eu-west-2:${var.account_id}:${var.environment_name}_cloudfront_total_error_rate", + "arn:aws:cloudwatch:us-east-1:${var.account_id}:ddos_detected_in_${var.environment_name}", + "arn:aws:route53:::healthcheck/*" + ] + sid = "ConfigureRoute53HealthChecks" + } - condition { - variable = "iam:PassedToService" - test = "StringLike" - values = ["events.amazonaws.com"] - } + statement { + actions = [ + "route53:CreateHealthCheck" + ] + effect = "Allow" + resources = [ + "*" + ] + sid = "CreateRoute53HealthChecks" } + } -data "aws_iam_policy_document" "cloudwatch_logging" { +data "aws_iam_policy_document" "s3" { statement { actions = [ - "logs:PutRetentionPolicy", - "logs:DeleteLogGroup", - "logs:DeleteRetentionPolicy", - "logs:DeleteSubscriptionFilter", + "s3:*" ] + effect = "Allow" resources = [ - "arn:aws:logs:eu-west-2:${var.account_id}:log-group:*", - "arn:aws:logs:us-east-1:${var.account_id}:log-group:*", + "arn:aws:s3:::pipeline-*", + "arn:aws:s3:::pipeline-*/*", + + "arn:aws:s3:::govuk-forms-*-pipeline-invoker", + "arn:aws:s3:::govuk-forms-*-pipeline-invoker/*", + "arn:aws:s3:::govuk-forms-*-paused-pipeline-detection", + "arn:aws:s3:::govuk-forms-*-paused-pipeline-detection/*", + "arn:aws:s3:::govuk-forms-*-paused-pipeline-detection-access-logs", + "arn:aws:s3:::govuk-forms-*-paused-pipeline-detection-access-logs/*", + "arn:aws:s3:::govuk-forms-*-pipeline-invoker-access-logs", + "arn:aws:s3:::govuk-forms-*-pipeline-invoker-access-logs/*", + + "arn:aws:s3:::govuk-forms-${var.environment_name}-file-upload*", + + "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate-access-logs", + "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate-access-logs/*", + + "arn:aws:s3:::*-alb-access-logs-access-logs", + "arn:aws:s3:::*-alb-access-logs-access-logs/*", + "arn:aws:s3:::govuk-forms-alb-logs-${var.environment_name}*", + + "arn:aws:s3:::govuk-forms-${var.environment_name}-error-page*" + ] + sid = "ManageS3" + } + + statement { + actions = [ + "s3:DeleteObject" ] effect = "Allow" + resources = [ + "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate/*.tflock" + ] + sid = "ReleaseTerraformStateLock" } statement { - sid = "ManageSubscriptionFilterForCRIBL" actions = [ - "logs:*SubscriptionFilter" + "s3:PutObject", + "s3:GetObject", + "s3:ListBucket" ] + effect = "Allow" resources = [ - "arn:aws:logs:*:${var.deploy_account_id}:destination:kinesis-log-destination", - "arn:aws:logs:*:${var.deploy_account_id}:destination:kinesis-log-destination-us-east-1", - "arn:aws:logs:*:${var.account_id}:log-group:*:log-stream:*", + "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate/*", + "arn:aws:s3:::gds-forms-${var.environment_type}-tfstate" ] + sid = "ManageTerraformStateBuckets" } } -data "aws_iam_policy_document" "shield" { +data "aws_iam_policy_document" "secretsmanager" { statement { - sid = "ShieldPermissionsProtectionResources" actions = [ - "shield:*HealthCheck", - "shield:*Protection", - "shield:TagResource", - "shield:UntagResource", + "secretsmanager:CreateSecret", + "secretsmanager:DeleteSecret", + "secretsmanager:UpdateSecret", + "secretsmanager:TagResource", + "secretsmanager:UntagResource", + "secretsmanager:PutSecretValue", + "secretsmanager:UpdateSecretVersionStage", + "secretsmanager:GetSecretValue" ] + effect = "Allow" resources = [ - "arn:aws:shield::${var.account_id}:protection/*", + "arn:aws:secretsmanager:eu-west-2:${var.account_id}:secret:data-api/${var.environment_name}/*", + "arn:aws:secretsmanager:eu-west-2:${var.account_id}:secret:rds-db-credentials/cluster-*" ] - effect = "Allow" + sid = "ManageRdsDbCredentialSecrets" } +} +data "aws_iam_policy_document" "ses" { + #checkov:skip=CKV_AWS_111:We use SES v1 which doesn't let us be more specific than * + #checkov:skip=CKV_AWS_356:We use SES v1 which doesn't let us be more specific than * + #checkov:skip=CKV_AWS_109:We have a plan to add a permissions boundary to the deployer statement { - sid = "ShieldPermissionsProtectionGroupResources" actions = [ - "shield:*ProtectionGroup", - "shield:ListProtectionGroups", - "shield:ListResourcesInProtectionGroup", - "shield:TagResource", - "shield:UntagResource", - + "ses:*ConfigurationSet*" ] + effect = "Allow" resources = [ - "arn:aws:shield::${var.account_id}:protection-group/*", + "*" + ] + sid = "ManageSESConfigurationSet" + } + + statement { + actions = [ + "ses:*Dkim*", + "ses:*EmailAddress*", + "ses:*Domain*", + "ses:VerifyEmailIdentity", + "ses:*Identity*", + "ses:*Tag*", + "ses:UntagResource" ] effect = "Allow" + resources = [ + "*" + ] + sid = "ManageSESVerification" } +} +data "aws_iam_policy_document" "shield" { statement { - sid = "ShieldPermissionsAllResources" actions = [ "shield:*DRTLogBucket", "shield:*DRTRole", @@ -736,225 +1038,183 @@ data "aws_iam_policy_document" "shield" { "shield:EnableProactiveEngagement", "shield:DisableApplicationLayerAutomaticResponse", "shield:DisableProactiveEngagement", - "shield:UpdateEmergencyContactSettings", + "shield:UpdateEmergencyContactSettings" ] + effect = "Allow" resources = [ - "*", + "*" ] - effect = "Allow" + sid = "ShieldPermissionsAllResources" } statement { - sid = "ShieldPermissionsIAM" actions = [ - "iam:AttachRolePolicy", - "iam:CreateServiceLinkedRole", - "iam:CreateRole", - "iam:DeleteRole", - "iam:DeleteRolePolicy", - "iam:DetachRolePolicy", - "iam:GetRole", - "iam:ListAttachedRolePolicies", - "iam:PassRole", - "iam:PutRolePolicy", - "iam:TagRole", - "iam:UpdateRole", + "shield:*HealthCheck", + "shield:*Protection", + "shield:TagResource", + "shield:UntagResource" ] + effect = "Allow" resources = [ - "arn:aws:iam::${var.account_id}:role/shield-response-team", - "arn:aws:iam::${var.account_id}:role/aws-service-role/shield.amazonaws.com/AWSServiceRoleForAWSShield" + "arn:aws:shield::${var.account_id}:protection/*" ] - effect = "Allow" + sid = "ShieldPermissionsProtectionResources" } -} -data "aws_iam_policy_document" "route53" { statement { - sid = "CreateRoute53HealthChecks" actions = [ - "route53:CreateHealthCheck" + "shield:*ProtectionGroup", + "shield:TagResource", + "shield:UntagResource" + ] + effect = "Allow" + resources = [ + "arn:aws:shield::${var.account_id}:protection-group/*" ] - resources = ["*"] # CreateHealthCheck uses * - effect = "Allow" + sid = "ShieldPermissionsProtectionGroupResources" } +} +data "aws_iam_policy_document" "sns" { statement { - sid = "ConfigureRoute53HealthChecks" actions = [ - "route53:ChangeTagsForResource", - "route53:DeleteHealthCheck", - "route53:UpdateHealthCheck" + "sns:*Topic*", + "sns:*Tag*", + "sns:*Subscrib*", + "sns:Unsubscribe", + "sns:UntagResource" ] + effect = "Allow" resources = [ - "arn:aws:cloudwatch:eu-west-2:${var.account_id}:${var.environment_name}_cloudfront_total_error_rate", - "arn:aws:cloudwatch:us-east-1:${var.account_id}:ddos_detected_in_${var.environment_name}", - "arn:aws:route53:::healthcheck/*" + "arn:aws:sns:eu-west-2:${var.account_id}:pagerduty_integration_${var.environment_name}", + "arn:aws:sns:eu-west-2:${var.account_id}:alert_zendesk_${var.environment_name}", + "arn:aws:sns:eu-west-2:${var.account_id}:slo-alerts", + "arn:aws:sns:us-east-1:${var.account_id}:cloudwatch-alarms", + "arn:aws:sns:eu-west-2:${var.account_id}:ses_bounces_and_complaints", # TODO: remove me once all envs use the new queues https://trello.com/c/BCDU9U7N/3456-remove-sesbouncesandcomplaints-sns-resource-if-all-environments-are-using-the-new-queues + "arn:aws:sns:eu-west-2:${var.account_id}:auth0_ses_bounces_and_complaints", + "arn:aws:sns:eu-west-2:${var.account_id}:submission_email_ses_bounces_and_complaints", + "arn:aws:sns:eu-west-2:${var.account_id}:submission_email_ses_successful_deliveries" ] - effect = "Allow" + sid = "ManageSNS" } } -data "aws_iam_policy_document" "ssm" { +data "aws_iam_policy_document" "sqs" { statement { - sid = "DescribeSSMParameters" actions = [ - "ssm:DescribeParameters", + "sqs:*queue*" ] + effect = "Allow" resources = [ - "arn:aws:ssm:eu-west-2:${var.account_id}:*" + "arn:aws:sqs:eu-west-2:${var.account_id}:*" ] - effect = "Allow" + sid = "ManageSQS" } +} +data "aws_iam_policy_document" "ssm" { statement { - sid = "ManageSSMParameters" actions = [ "ssm:*Tag*", - "ssm:*Parameter*", + "ssm:*Parameter*" ] + effect = "Allow" resources = [ - "arn:aws:ssm:eu-west-2:${var.account_id}:parameter/*", + "arn:aws:ssm:eu-west-2:${var.account_id}:parameter/*" ] - effect = "Allow" + sid = "ManageSSMParameters" } - # We allow all operations except deleting a parameter. If you need the deployer role to delete a parameter then you can temporarily comment out this block. + + statement { - sid = "DeleteSSMParameters" actions = [ - "ssm:DeleteParameter", + "ssm:DeleteParameter" ] + effect = "Deny" resources = [ - "arn:aws:ssm:eu-west-2:${var.account_id}:parameter/*", + "arn:aws:ssm:eu-west-2:${var.account_id}:parameter/*" ] - effect = "Deny" + sid = "DeleteSSMParameters" } -} -data "aws_iam_policy_document" "forms_runner" { statement { - sid = "ManageRunnerSpecificRoles" actions = [ - "iam:AttachRolePolicy", - "iam:CreateServiceLinkedRole", - "iam:CreateRole", - "iam:DeleteRole", - "iam:DeleteRolePolicy", - "iam:DetachRolePolicy", - "iam:GetRole", - "iam:ListAttachedRolePolicies", - "iam:PutRolePolicy", - "iam:TagRole", - "iam:UpdateAssumeRolePolicy", - "iam:UpdateRole", + "ssm:DescribeParameters" ] - + effect = "Allow" resources = [ - "arn:aws:iam::${var.account_id}:role/govuk-forms-submissions-to-s3-${var.environment_name}", - "arn:aws:iam::${var.account_id}:role/govuk-s3-end-to-end-test-${var.environment_name}", + "arn:aws:ssm:eu-west-2:${var.account_id}:*" ] + sid = "DescribeSSMParameters" } + } -data "aws_iam_policy_document" "application_signals" { +data "aws_iam_policy_document" "wafv2" { statement { - sid = "ManageApplicationSignalsSLOs" - effect = "Allow" actions = [ - "application-signals:BatchUpdateExclusionWindows", - "application-signals:CreateServiceLevelObjective", - "application-signals:UpdateServiceLevelObjective", - "application-signals:DeleteServiceLevelObjective", - "application-signals:ListServiceLevelObjectiveExclusionWindows", - "application-signals:TagResource", - "application-signals:UntagResource" + "wafv2:*LoggingConfiguration", + "wafv2:CreateWebACL", + "wafv2:DeleteWebACL", + "wafv2:UpdateWebACL" ] - resources = ["arn:aws:application-signals:eu-west-2:${var.account_id}:slo/*"] - } - - statement { - sid = "CloudWatchApplicationSignalsCreateServiceLinkedRolePermissions" effect = "Allow" - actions = [ - "iam:CreateServiceLinkedRole" + resources = [ + "arn:aws:wafv2:us-east-1:${var.account_id}:regional/webacl/*", + "arn:aws:wafv2:eu-west-2:${var.account_id}:regional/webacl/*" ] - resources = ["arn:aws:iam::${var.account_id}:role/aws-service-role/application-signals.cloudwatch.amazonaws.com/AWSServiceRoleForCloudWatchApplicationSignals"] - condition { - test = "StringLike" - variable = "iam:AWSServiceName" - values = ["application-signals.cloudwatch.amazonaws.com"] - } + sid = "ManageWebACL" } statement { - sid = "CloudWatchApplicationSignalsPutMetricAlarmPermissions" - effect = "Allow" actions = [ - "cloudwatch:PutMetricAlarm" - ] - resources = [ - "arn:aws:cloudwatch:eu-west-2:${var.account_id}:alarm:SLO-AttainmentGoalAlarm-*", - "arn:aws:cloudwatch:eu-west-2:${var.account_id}:alarm:SLO-WarningAlarm-*", - "arn:aws:cloudwatch:eu-west-2:${var.account_id}:alarm:SLI-HealthAlarm-*" + "wafv2:*WebACL", + "wafv2:*LoggingConfiguration", + "wafv2:TagResource", + "wafv2:UntagResource", + "wafv2:*RuleGroup", + "wafv2:*RegexPatternSet" ] - } -} - -data "aws_iam_policy_document" "cloud_control_api" { - # These permissions are required for the `awscc` provider to create, update, delete, and list - # Cloud Control API resources, which includes the Application Signals SLO resources. - # See: https://docs.aws.amazon.com/cloudcontrolapi/latest/userguide/security.html - - # It seems super scary to give `cloudformation:*` permissions, but the Cloud Control API - # is implemented as a layer on top of CloudFormation, and the `awscc` provider - # needs these permissions to manage resources. These permissions are essentially saying - # 'allow the deployer to use the Cloud Control API to attempt to CRUDL any resource' - # The deployer role will still be limited by the other permissions it has, so it won't be able - # to create resources we haven't explicitly given it permission for. - # eg. if we removed `s3:CreateBucket` from the deployer role, it wouldn't be able to create S3 buckets, - # even though it has `cloudformation:CreateResource` permission. - statement { - sid = "CloudControlAPIActions" effect = "Allow" - actions = [ - "cloudformation:CreateResource", - "cloudformation:GetResource", - "cloudformation:UpdateResource", - "cloudformation:DeleteResource", - "cloudformation:ListResources", + resources = [ + "arn:aws:wafv2:us-east-1:${var.account_id}:global/webacl/cloudfront_waf_${var.environment_name}/*", + "arn:aws:wafv2:eu-west-2:${var.account_id}:regional/webacl/alb_${var.environment_name}/*", + "arn:aws:wafv2:us-east-1:${var.account_id}:global/rulegroup/${var.environment_name}-*/*", + "arn:aws:wafv2:us-east-1:${var.account_id}:global/regexpatternset/${var.environment_name}-*", + "arn:aws:wafv2:us-east-1:153427709519:global/rulegroup/ShieldMitigationRuleGroup_*" ] - resources = ["*"] + sid = "ManageWAFv2WebACL" } -} -data "aws_iam_policy_document" "secrets_manager" { statement { - sid = "ManageRdsDbCredentialSecrets" actions = [ - "secretsmanager:CreateSecret", - "secretsmanager:DeleteSecret", - "secretsmanager:UpdateSecret", - "secretsmanager:TagResource", - "secretsmanager:UntagResource", - "secretsmanager:PutSecretValue", - "secretsmanager:UpdateSecretVersionStage", - "secretsmanager:GetSecretValue", - "secretsmanager:DescribeSecret", - "secretsmanager:ListSecretVersionIds", + "wafv2:CreateWebACL", + "wafv2:PutManagedRuleSetVersions", + "wafv2:UpdateWebACL" ] + effect = "Allow" resources = [ - "arn:aws:secretsmanager:eu-west-2:${var.account_id}:secret:data-api/${var.environment_name}/*", - "arn:aws:secretsmanager:eu-west-2:${var.account_id}:secret:rds-db-credentials/cluster-*", + "arn:aws:wafv2:us-east-1:${var.account_id}:global/managedruleset/*" ] - effect = "Allow" + sid = "ManageWAFRuleSet" } statement { - sid = "ListRdsDbCredentialSecrets" actions = [ - "secretsmanager:ListSecrets", + "wafv2:DeleteIPSet", + "wafv2:CreateIPSet", + "wafv2:UpdateIPSet", + "wafv2:TagResource", + "wafv2:UntagResource" + ] + effect = "Allow" + resources = [ + "arn:aws:wafv2:us-east-1:${var.account_id}:global/ipset/*", + "arn:aws:wafv2:us-east-1:${var.account_id}:regional/ipset/*", + "arn:aws:wafv2:eu-west-2:${var.account_id}:global/ipset/*", + "arn:aws:wafv2:eu-west-2:${var.account_id}:regional/ipset/*" ] - resources = ["*"] - effect = "Allow" + sid = "ManageIPSets" } }