Infrastructure

Deployed AWS components

Network ServicesOptionalDescription
A dedicated multi AZ VPCnoEverything Qovery will deploy, will be deployed inside this VPC
Subnets, routing tables, subnet groups and security groups for RDS (multi AZ)noDedicated network fand security rules for RDS
Subnets, routing tables, subnet groups and security groups for DocumentDB (multi AZ)noDedicated network fand security rules for DocumentDB
Subnets, routing tables, subnet groups and security groups for Elasticache (multi AZ)noDedicated network fand security rules for Elasticache
An internet gateway for the VPCnoRequired to let containers having access to Internet
Dedicated NLB to redirect 443 traffic to Nginx IngressnoHigh Availability network load balancer, pointing to Nginx Ingress inside EKS
NAT gateways (multi AZ) + EIP addresses (multi AZ) + subnet groups + routing tableyesUseful to get outgoing static IP
Dedicated VPC routes for VPC peeringyesUseful to perform VPC peering with others VPC on the same or different account
Kubernetes ServicesOptionalDescription
A dedicated EKS cluster (multi AZ) for this VPCnoDedicated Kubernetes cluster managed by AWS with nodes (instances type) defined by the customer
IAM dedicated user for AWS EBS CSI to access EC2 volumes + a dedicated policynoRequired to allow EKS cluster having access to volume and mount them to containers
IAM dedicated user for AWS IAM User Sync + a dedicated policynoRequired to sync desired IAM account to EKS to let them connect directly ot Kubernetes
IAM dedicated user for a Cluster Autoscaler+ a dedicated policynoRequired to let autoscaler having access to EC2 autoscaling groups
IAM dedicated policies for AWS EKS CNI, EC2 container registry + EKS worker nodesnoRequired to let EKS having access to container registry and configure the Kubernetes network
Security group for EKS remote access (dual authentication: TLS + IAM authenticator)noRequired to have a secure remote access on the Kubernetes cluster
Security group for 443 port pointing to Nginx ingress inside EKSnoExternal access to web services inside the Kubernetes cluster
Other ServicesOptionalDescription
Cloudwatch log groups for the EKS clusternoKubernetes logs, useful for the AWS and EKS support to diagnose an issue
Dedicated S3 bucket for application's logs + a dedicated IAM accountnoApplication's logs are stored in an KMS encrypted S3 private bucket
Dedicated S3 bucket to store the kubeconfignoKubernetes Kubeconfig is stored in an KMS encrypted, private and versioned bucket, used by Qovery for application's deployment

Remove Qovery from your AWS account

To delete Qovery from your AWS account you must be the owner of the Qovery Organization and you have to delete everything in this order:

  • Environments
  • Clusters

IAM permissions

Qovery required IAM permissions to create, update and managed the infrastructure.

  • IAM is used to create IAM roles
  • S3 is used to store our generated configuration files
  • Cloudwatch, for creating a group stream for each Kubernetes clusters
  • Autoscaling for RDS and autoscaling rules for the Kubernetes cluster
  • Elastic load-balancing for ELB / ALB / NLB.
  • DynamoDB to have a distributed lock on infrastructure deployment.
  • ECR for managing the container registry, create/update/delete repository.
  • KMS to load and store keys (RDS, SSH, …)
  • EKS to create and update the Kubernetes cluster.
Minimum IAM permission set
Last update: 2023-06-08

Below you can find the minimum permission set required by Qovery to run and deploy your applications.

Policies lengths are limited regarding which object they’re attached to but the one Qovery needs represent more than the maximum (~6000 characters).

In order to setup it up, you need to create two IAM groups, each one with one of the following policies.

Then we must create a user added to each of the previously created groups.

Once it’s done, the user’s access key and secret key can be used in Qovery.

{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"autoscaling:SuspendProcesses",
"ec2:AllocateAddress",
"ec2:AssociateAddress",
"ec2:AssociateRouteTable",
"ec2:AttachVolume",
"ec2:AttachInternetGateway",
"ec2:AuthorizeSecurityGroupEgress",
"ec2:AuthorizeSecurityGroupIngress",
"ec2:CreateInternetGateway",
"ec2:CreateKeyPair",
"ec2:CreateLaunchTemplate",
"ec2:CreateLaunchTemplateVersion",
"ec2:CreateNatGateway",
"ec2:CreateRoute",
"ec2:CreateRouteTable",
"ec2:CreateSecurityGroup",
"ec2:CreateSubnet",
"ec2:CreateTags",
"ec2:CreateVolume",
"ec2:CreateVpc",
"ec2:DeleteInternetGateway",
"ec2:DeleteKeyPair",
"ec2:DeleteLaunchTemplate",
"ec2:DeleteNatGateway",
"ec2:DeleteRouteTable",
"ec2:DeleteSecurityGroup",
"ec2:DeleteSubnet",
"ec2:DeleteVolume",
"ec2:DeleteVpc",
"ec2:DescribeAddresses",
"ec2:DescribeAvailabilityZones",
"ec2:DescribeImages",
"ec2:DescribeInstanceAttribute",
"ec2:DescribeInstanceCreditSpecifications",
"ec2:DescribeInstances",
"ec2:DescribeInstanceTypes",
"ec2:DescribeInternetGateways",
"ec2:DescribeKeyPairs",
"ec2:DescribeLaunchTemplateVersions",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeNatGateways",
"ec2:DescribeNetworkAcls",
"ec2:DescribeNetworkInterfaces",
"ec2:DescribeRouteTables",
"ec2:DescribeSecurityGroupRules",
"ec2:DescribeSecurityGroups",
"ec2:DescribeSubnets",
"ec2:DescribeTags",
"ec2:DescribeVolumes",
"ec2:DescribeVpcAttribute",
"ec2:DescribeVpcClassicLink",
"ec2:DescribeVpcClassicLinkDnsSupport",
"ec2:DescribeVpcs",
"ec2:DetachInternetGateway",
"ec2:DetachVolume",
"ec2:DisassociateAddress",
"ec2:DisassociateRouteTable",
"ec2:ImportKeyPair",
"ec2:ModifySubnetAttribute",
"ec2:ModifyVpcAttribute",
"ec2:ReleaseAddress",
"ec2:RevokeSecurityGroupEgress",
"ec2:RevokeSecurityGroupIngress",
"ec2:RunInstances",
"ec2:StopInstances",
"ec2:TerminateInstances",
"ecr:BatchCheckLayerAvailability",
"ecr:BatchGetImage",
"ecr:CompleteLayerUpload",
"ecr:CreateRepository",
"ecr:DeleteRepository",
"ecr:DescribeImages",
"ecr:DescribeRepositories",
"ecr:GetAuthorizationToken",
"ecr:GetDownloadUrlForLayer",
"ecr:InitiateLayerUpload",
"ecr:PutImage",
"ecr:PutLifecyclePolicy",
"ecr:TagResource",
"ecr:UploadLayerPart",
"eks:CreateAddon",
"eks:CreateCluster",
"eks:CreateNodegroup",
"eks:DeleteAddon",
"eks:DeleteCluster",
"eks:DeleteNodegroup",
"eks:DescribeAddon",
"eks:DescribeCluster",
"eks:DescribeNodegroup",
"eks:DescribeUpdate",
"eks:ListClusters",
"eks:ListNodegroups",
"eks:TagResource",
"eks:UpdateAddon",
"eks:UpdateClusterConfig",
"eks:UpdateClusterVersion",
"eks:UpdateNodegroupConfig",
"eks:UpdateNodegroupVersion",
"elasticache:AddTagsToResource",
"elasticache:CreateCacheSubnetGroup",
"elasticache:CreateReplicationGroup",
"elasticache:DeleteCacheSubnetGroup",
"elasticache:DeleteReplicationGroup",
"elasticache:DescribeCacheClusters",
"elasticache:DescribeCacheSubnetGroups",
"elasticache:DescribeReplicationGroups",
"elasticache:ListTagsForResource",
"elasticloadbalancing:DescribeLoadBalancers",
"elasticloadbalancing:DescribeTags"
],
"Resource": "*"
}
]
}
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"iam:AddRoleToInstanceProfile",
"iam:AttachRolePolicy",
"iam:AttachUserPolicy",
"iam:CreateAccessKey",
"iam:CreateInstanceProfile",
"iam:CreateOpenIDConnectProvider",
"iam:CreatePolicy",
"iam:CreateRole",
"iam:CreateServiceLinkedRole",
"iam:CreateUser",
"iam:DeleteAccessKey",
"iam:DeleteInstanceProfile",
"iam:DeleteOpenIDConnectProvider",
"iam:DeletePolicy",
"iam:DeleteRole",
"iam:DeleteRolePolicy",
"iam:DeleteUser",
"iam:DeleteUserPolicy",
"iam:DetachRolePolicy",
"iam:DetachUserPolicy",
"iam:GetInstanceProfile",
"iam:GetOpenIDConnectProvider",
"iam:GetPolicy",
"iam:GetPolicyVersion",
"iam:GetRole",
"iam:GetRolePolicy",
"iam:GetUser",
"iam:GetUserPolicy",
"iam:ListAccessKeys",
"iam:ListAttachedRolePolicies",
"iam:ListAttachedUserPolicies",
"iam:ListGroupsForUser",
"iam:ListInstanceProfilesForRole",
"iam:ListPolicyVersions",
"iam:ListRolePolicies",
"iam:PassRole",
"iam:PutRolePolicy",
"iam:PutUserPolicy",
"iam:RemoveRoleFromInstanceProfile",
"iam:TagInstanceProfile",
"iam:TagOpenIDConnectProvider",
"iam:TagRole",
"iam:TagUser",
"kms:CreateGrant",
"kms:CreateKey",
"kms:Decrypt",
"kms:DescribeKey",
"kms:GenerateDataKey",
"kms:GetKeyPolicy",
"kms:GetKeyRotationStatus",
"kms:ListResourceTags",
"kms:PutKeyPolicy",
"kms:ScheduleKeyDeletion",
"kms:TagResource",
"logs:CreateLogGroup",
"logs:DeleteLogGroup",
"logs:DescribeLogGroups",
"logs:ListTagsLogGroup",
"logs:PutRetentionPolicy",
"logs:TagLogGroup",
"rds:AddTagsToResource",
"rds:CreateDBCluster",
"rds:CreateDBInstance",
"rds:CreateDBParameterGroup",
"rds:CreateDBSubnetGroup",
"rds:DeleteDBCluster",
"rds:DeleteDBInstance",
"rds:DeleteDBParameterGroup",
"rds:DeleteDBSubnetGroup",
"rds:DescribeDBClusters",
"rds:DescribeDBInstances",
"rds:DescribeDBParameterGroups",
"rds:DescribeDBParameters",
"rds:DescribeDBSubnetGroups",
"rds:DescribeGlobalClusters",
"rds:ListTagsForResource",
"rds:ModifyDBInstance",
"rds:ModifyDBParameterGroup",
"rds:StartDBCluster",
"rds:StartDBInstance",
"rds:StopDBCluster",
"rds:StopDBInstance",
"s3:CreateBucket",
"s3:DeleteBucket",
"s3:DeleteObject",
"s3:DeleteObjectVersion",
"s3:DeleteBucketPolicy",
"s3:GetAccelerateConfiguration",
"s3:GetBucketAcl",
"s3:GetBucketCORS",
"s3:GetBucketLogging",
"s3:GetBucketObjectLockConfiguration",
"s3:GetBucketOwnershipControls",
"s3:GetBucketPolicy",
"s3:GetBucketPublicAccessBlock",
"s3:GetBucketRequestPayment",
"s3:GetBucketTagging",
"s3:GetBucketVersioning",
"s3:GetBucketWebsite",
"s3:GetEncryptionConfiguration",
"s3:GetLifecycleConfiguration",
"s3:GetObject",
"s3:GetReplicationConfiguration",
"s3:ListAccessPoints",
"s3:ListAllMyBuckets",
"s3:ListBucket",
"s3:ListBucketMultipartUploads",
"s3:ListBucketVersions",
"s3:ListMultiRegionAccessPoints",
"s3:ListMultipartUploadParts",
"s3:ListStorageLensConfigurations",
"s3:PutBucketAcl",
"s3:PutBucketOwnershipControls",
"s3:PutBucketPolicy",
"s3:PutBucketPublicAccessBlock",
"s3:PutBucketTagging",
"s3:PutBucketVersioning",
"s3:PutEncryptionConfiguration",
"s3:PutLifecycleConfiguration",
"s3:PutObject",
"s3:PutObjectRetention",
"secretsmanager:CreateSecret",
"secretsmanager:TagResource",
"sts:GetCallerIdentity"
],
"Resource": "*"
}
]
}