From 31705b6e935042f30182abc5c1db802aed7f3410 Mon Sep 17 00:00:00 2001 From: sobrab <170367248+sobrab@users.noreply.github.com> Date: Sat, 2 Nov 2024 16:55:44 +0200 Subject: [PATCH 1/4] added a java example for an ApiGateway backed by a lambda behind a Cognito user pool (#1079) Co-authored-by: Michael Kaiser --- java/cognito-api-lambda/.gitignore | 13 + java/cognito-api-lambda/README.md | 55 ++++ java/cognito-api-lambda/cdk.json | 68 +++++ java/cognito-api-lambda/pom.xml | 60 +++++ .../java/com/myorg/CognitoApiLambdaApp.java | 14 ++ .../java/com/myorg/CognitoApiLambdaStack.java | 76 ++++++ .../src/main/resources/lambda/hello-world.py | 8 + .../java/com/myorg/CognitoApiLambdaTest.java | 237 ++++++++++++++++++ .../src/test/java/com/myorg/TestUtils.java | 61 +++++ 9 files changed, 592 insertions(+) create mode 100644 java/cognito-api-lambda/.gitignore create mode 100644 java/cognito-api-lambda/README.md create mode 100644 java/cognito-api-lambda/cdk.json create mode 100644 java/cognito-api-lambda/pom.xml create mode 100644 java/cognito-api-lambda/src/main/java/com/myorg/CognitoApiLambdaApp.java create mode 100644 java/cognito-api-lambda/src/main/java/com/myorg/CognitoApiLambdaStack.java create mode 100644 java/cognito-api-lambda/src/main/resources/lambda/hello-world.py create mode 100644 java/cognito-api-lambda/src/test/java/com/myorg/CognitoApiLambdaTest.java create mode 100644 java/cognito-api-lambda/src/test/java/com/myorg/TestUtils.java diff --git a/java/cognito-api-lambda/.gitignore b/java/cognito-api-lambda/.gitignore new file mode 100644 index 000000000..1db21f162 --- /dev/null +++ b/java/cognito-api-lambda/.gitignore @@ -0,0 +1,13 @@ +.classpath.txt +target +.classpath +.project +.idea +.settings +.vscode +*.iml + +# CDK asset staging directory +.cdk.staging +cdk.out + diff --git a/java/cognito-api-lambda/README.md b/java/cognito-api-lambda/README.md new file mode 100644 index 000000000..82b127eec --- /dev/null +++ b/java/cognito-api-lambda/README.md @@ -0,0 +1,55 @@ +# APIGateway backed by Lambda and protected by a Cognito User Pool. + + + + +--- + +![Stability: Stable](https://img.shields.io/badge/stability-Stable-success.svg?style=for-the-badge) + +> **This is a stable example. It should successfully build out of the box** +> +> This example is built on Construct Libraries marked "Stable" and does not have any infrastructure prerequisites to build. + +--- + + +This an example of an APIGateway that is protected with a Cognito User Pool, pointing to a Hello World Lambda. + +## Build + +To build this example, you need to be in this example's root directory. Then run the following: + +```bash +npm install -g aws-cdk +npm install +cdk synth +``` + +This will install the necessary CDK, then this example's dependencies, and then build the CloudFormation template. The resulting CloudFormation template will be in the `cdk.out` directory. + +## Deploy + +Run `cdk deploy`. +This will deploy / redeploy the Stack to AWS. +After the deployment, the URL of the Rest API created will be available in the outputs of the CloudFormation stack and can be used to invoke the lambda function. +At this point, if an HTTP GET request is attempted on the Rest API without including and `Authorization` header, a `401 - Unauthorized` response will be returned. +In order for the authorization to succeed when the lambda function is invoked through the API Gateway, each request must include an `Authorization` HTTP header containing an access token obtained for the specific user from the user pool. + +## The Component Structure + +The main resources of the component are: + +- A Lambda Function that returns the string "Hello world!" +- A Rest API with a GET method that points to the Lambda Function +- A Cognito User Pool +- An Authorizer for the Rest API with the User Pool attached. + +## Useful commands + +* `mvn package` compile and run tests +* `cdk ls` list all stacks in the app +* `cdk synth` emits the synthesized CloudFormation template +* `cdk deploy` deploy this stack to your default AWS account/region +* `cdk diff` compare deployed stack with current state +* `cdk docs` open CDK documentation diff --git a/java/cognito-api-lambda/cdk.json b/java/cognito-api-lambda/cdk.json new file mode 100644 index 000000000..e94ff8512 --- /dev/null +++ b/java/cognito-api-lambda/cdk.json @@ -0,0 +1,68 @@ +{ + "app": "mvn -e -q compile exec:java", + "watch": { + "include": [ + "**" + ], + "exclude": [ + "README.md", + "cdk*.json", + "target", + "pom.xml", + "src/test" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, + "@aws-cdk/aws-eks:nodegroupNameAttribute": true, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false + } +} diff --git a/java/cognito-api-lambda/pom.xml b/java/cognito-api-lambda/pom.xml new file mode 100644 index 000000000..35197d226 --- /dev/null +++ b/java/cognito-api-lambda/pom.xml @@ -0,0 +1,60 @@ + + + 4.0.0 + + com.myorg + cognito-api-lambda + 0.1 + + + UTF-8 + 2.158.0 + [10.0.0,11.0.0) + 5.7.1 + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.11.0 + + 17 + + + + + org.codehaus.mojo + exec-maven-plugin + 3.1.0 + + com.myorg.CognitoApiLambdaApp + + + + + + + + + software.amazon.awscdk + aws-cdk-lib + ${cdk.version} + + + + software.constructs + constructs + ${constructs.version} + + + + org.junit.jupiter + junit-jupiter + ${junit.version} + test + + + diff --git a/java/cognito-api-lambda/src/main/java/com/myorg/CognitoApiLambdaApp.java b/java/cognito-api-lambda/src/main/java/com/myorg/CognitoApiLambdaApp.java new file mode 100644 index 000000000..0db8c2b64 --- /dev/null +++ b/java/cognito-api-lambda/src/main/java/com/myorg/CognitoApiLambdaApp.java @@ -0,0 +1,14 @@ +package com.myorg; + +import software.amazon.awscdk.App; +import software.amazon.awscdk.StackProps; + +public class CognitoApiLambdaApp { + public static void main(final String... args) { + App app = new App(); + StackProps stackProps = StackProps.builder().build(); + new CognitoApiLambdaStack(app, "CognitoApiLambdaStack", stackProps); + app.synth(); + } +} + diff --git a/java/cognito-api-lambda/src/main/java/com/myorg/CognitoApiLambdaStack.java b/java/cognito-api-lambda/src/main/java/com/myorg/CognitoApiLambdaStack.java new file mode 100644 index 000000000..5a040a82c --- /dev/null +++ b/java/cognito-api-lambda/src/main/java/com/myorg/CognitoApiLambdaStack.java @@ -0,0 +1,76 @@ +package com.myorg; + +import org.jetbrains.annotations.NotNull; +import software.amazon.awscdk.RemovalPolicy; +import software.amazon.awscdk.Stack; +import software.amazon.awscdk.StackProps; +import software.amazon.awscdk.services.apigateway.*; +import software.amazon.awscdk.services.cognito.SignInAliases; +import software.amazon.awscdk.services.cognito.UserPool; +import software.amazon.awscdk.services.lambda.InlineCode; +import software.amazon.awscdk.services.lambda.Runtime; +import software.amazon.awscdk.services.lambda.SingletonFunction; +import software.constructs.Construct; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; + +public class CognitoApiLambdaStack extends Stack { + + private record Authorizer(CfnAuthorizer authorizer) implements IAuthorizer { + @Override + public @NotNull String getAuthorizerId() { + return authorizer.getRef(); + } + } + + public CognitoApiLambdaStack(final Construct scope, final String id, final StackProps props) { + super(scope, id, props); + var helloWorldFunction = SingletonFunction.Builder.create(this, "helloWorldFunction") + .functionName("helloWorldFunction") + .code(InlineCode.fromInline(getInlineCode())) + .handler("index.handler") + .runtime(Runtime.PYTHON_3_12) + .uuid("") + .build(); + var helloWorldLambdaRestApi = LambdaRestApi.Builder.create(this, "helloWorldLambdaRestApi") + .restApiName("Hello World API") + .cloudWatchRole(true) + .cloudWatchRoleRemovalPolicy(RemovalPolicy.DESTROY) + .handler(helloWorldFunction) + .proxy(false) + .build(); + var signInAliases = SignInAliases.builder() + .email(true) + .build(); + var userPool = UserPool.Builder.create(this, "userPool") + .signInAliases(signInAliases) + .removalPolicy(RemovalPolicy.DESTROY) + .build(); + var authorizer = new Authorizer( + CfnAuthorizer.Builder.create(this, "cfnAuth") + .restApiId(helloWorldLambdaRestApi.getRestApiId()) + .name("HelloWorldAPIAuthorizer") + .type("COGNITO_USER_POOLS") + .identitySource("method.request.header.Authorization") + .providerArns(List.of(userPool.getUserPoolArn())) + .build() + ); + var helloResource = helloWorldLambdaRestApi.getRoot().addResource("HELLO"); + var methodOptions = MethodOptions.builder() + .authorizationType(AuthorizationType.COGNITO) + .authorizer(authorizer) + .build(); + helloResource.addMethod("GET", new LambdaIntegration(helloWorldFunction), methodOptions); + } + + private String getInlineCode() { + try { + return new String(Files.readAllBytes(Path.of("src/main/resources/lambda/hello-world.py"))); + } catch (IOException e) { + throw new RuntimeException(e); + } + } +} diff --git a/java/cognito-api-lambda/src/main/resources/lambda/hello-world.py b/java/cognito-api-lambda/src/main/resources/lambda/hello-world.py new file mode 100644 index 000000000..cd353c836 --- /dev/null +++ b/java/cognito-api-lambda/src/main/resources/lambda/hello-world.py @@ -0,0 +1,8 @@ +import json + +def handler(event, context): + print(event) + return { + 'statusCode': 200, + 'body': 'Hello world!' + } diff --git a/java/cognito-api-lambda/src/test/java/com/myorg/CognitoApiLambdaTest.java b/java/cognito-api-lambda/src/test/java/com/myorg/CognitoApiLambdaTest.java new file mode 100644 index 000000000..e7ec14426 --- /dev/null +++ b/java/cognito-api-lambda/src/test/java/com/myorg/CognitoApiLambdaTest.java @@ -0,0 +1,237 @@ +package com.myorg; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import software.amazon.awscdk.App; +import software.amazon.awscdk.StackProps; +import software.amazon.awscdk.cxapi.CloudFormationStackArtifact; + +import java.util.HashMap; +import java.util.Map; +import java.util.Optional; +import java.util.Set; +import java.util.stream.Stream; + +import static com.myorg.TestUtils.*; +import static org.junit.platform.commons.util.StringUtils.isNotBlank; + +public class CognitoApiLambdaTest { + + private static final Map stackResourcesMap = new HashMap<>(); + + @BeforeAll + public static void setUp() { + var app = App.Builder.create().build(); + var stackProps = StackProps.builder().build(); + var cognitoApiLambdaStack = new CognitoApiLambdaStack(app, "test", stackProps); + Optional.of(app) + .map(App::synth) + .flatMap( + cloudAssembly -> Optional.of(cognitoApiLambdaStack) + .map(CognitoApiLambdaStack::getArtifactId) + .map(cloudAssembly::getStackArtifact) + .map(CloudFormationStackArtifact::getTemplate) + ).flatMap( + template -> Optional.of(new ObjectMapper()) + .map(objectMapper -> objectMapper.valueToTree(template)) + .map(jsonNode -> jsonNode.at("/Resources")) + .map(JsonNode::fields) + ).ifPresent(stackResourceIterator -> stackResourceIterator.forEachRemaining( + stackResourceEntry -> { + if (stackResourceEntry != null && + isNotBlank(stackResourceEntry.getKey()) && + stackResourceEntry.getValue() != null && + !stackResourceEntry.getValue().isEmpty() + ) { + stackResourcesMap.put(stackResourceEntry.getKey(), stackResourceEntry.getValue()); + } + }) + ); + } + + @Test + @DisplayName("Test if the expected IAM role required for the lambda function is present in the resources of the stack.") + public void testLambdaFunctionRole() { + var lambdaIAMRoleMatchMap = Map.of( + "/Type", "AWS::IAM::Role", + "/Properties/AssumeRolePolicyDocument/Statement/0/Action", "sts:AssumeRole", + "/Properties/AssumeRolePolicyDocument/Statement/0/Effect", "Allow", + "/Properties/AssumeRolePolicyDocument/Statement/0/Principal/Service", "lambda.amazonaws.com", + "/Properties/ManagedPolicyArns/0/Fn::Join/1/2", ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ); + Assertions.assertNotNull(findResource(stackResourcesMap, lambdaIAMRoleMatchMap)); + } + + @Test + @DisplayName("Test if the expected lambda function is present in the resources of the stack.") + public void testLambdaFunction() { + var lambdaIAMRoleMatchMap = Map.of( + "/Type", "AWS::IAM::Role", + "/Properties/ManagedPolicyArns/0/Fn::Join/1/2", ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ); + var lambdaIAMRoleId = findResourceId(stackResourcesMap, lambdaIAMRoleMatchMap); + var lambdaMatchMap = Map.of( + "/Type", "AWS::Lambda::Function", + "/Properties/FunctionName", "helloWorldFunction", + "/Properties/Role/Fn::GetAtt/0", lambdaIAMRoleId, + "/Properties/Handler", "index.handler", + "/Properties/Runtime", "python3.12" + ); + Assertions.assertNotNull(findResource(stackResourcesMap, lambdaMatchMap)); + } + + @Test + @DisplayName("Test if the expected Rest API is present in the resources of the stack.") + public void testRestAPI() { + var restAPIMatchMap = Map.of( + "/Type", "AWS::ApiGateway::RestApi", + "/Properties/Name", "Hello World API" + ); + Assertions.assertNotNull(findResource(stackResourcesMap, restAPIMatchMap)); + } + + @Test + @DisplayName("Test if the expected IAM Role required for the Rest API is present in the resources of the stack.") + public void testRestApiRole() { + var restAPIRoleMatchMap = Map.of( + "/Type", "AWS::IAM::Role", + "/Properties/AssumeRolePolicyDocument/Statement/0/Action", "sts:AssumeRole", + "/Properties/AssumeRolePolicyDocument/Statement/0/Effect", "Allow", + "/Properties/AssumeRolePolicyDocument/Statement/0/Principal/Service", "apigateway.amazonaws.com", + "/Properties/ManagedPolicyArns/0/Fn::Join/1/2", ":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + ); + Assertions.assertNotNull(findResource(stackResourcesMap, restAPIRoleMatchMap)); + } + + @Test + @DisplayName("Test if the expected API Gateway account is present in the resources of the stack.") + public void testAPIGatewayAccount() { + var restAPIMatchMap = Map.of( + "/Type", "AWS::ApiGateway::RestApi" + ); + var restAPIId = findResourceId(stackResourcesMap, restAPIMatchMap); + var restAPIRoleMatchMap = Map.of( + "/Type", "AWS::IAM::Role", + "/Properties/ManagedPolicyArns/0/Fn::Join/1/2", ":iam::aws:policy/service-role/AmazonAPIGatewayPushToCloudWatchLogs" + ); + var restAPIRoleId = findResourceId(stackResourcesMap, restAPIRoleMatchMap); + var apiGatewayAccountMatchMap = Map.of( + "/Type", "AWS::ApiGateway::Account", + "/Properties/CloudWatchRoleArn/Fn::GetAtt/0", restAPIRoleId, + "/DependsOn/0", restAPIId + ); + Assertions.assertNotNull(findResource(stackResourcesMap, apiGatewayAccountMatchMap)); + } + + @Test + @DisplayName("Test if the expected API Gateway deployment is present in the resources of the stack.") + public void testAPIGatewayDeployment() { + var apiGatewayResourceId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::Resource")); + var apiGatewayMethodId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::Method")); + var restAPIId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::RestApi")); + var apiGatewayDeploymentMatchMap = Map.of( + "/Type", "AWS::ApiGateway::Deployment", + "/Properties/RestApiId/Ref", restAPIId, + "/DependsOn/0", apiGatewayMethodId, + "/DependsOn/1", apiGatewayResourceId + ); + Assertions.assertNotNull(findResource(stackResourcesMap, apiGatewayDeploymentMatchMap)); + } + + @Test + @DisplayName("Test if the expected API Gateway stage is present in the resources of the stack.") + public void testAPIGatewayStage() { + var apiGatewayAccountId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::Account")); + var apiGatewayDeploymentId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::Deployment")); + var restAPIId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::RestApi")); + var apiGatewayStageMatchMap = Map.of( + "/Type", "AWS::ApiGateway::Stage", + "/Properties/DeploymentId/Ref", apiGatewayDeploymentId, + "/Properties/RestApiId/Ref", restAPIId, + "/Properties/StageName", "prod", + "/DependsOn/0", apiGatewayAccountId + ); + Assertions.assertNotNull(findResource(stackResourcesMap, apiGatewayStageMatchMap)); + } + + @Test + @DisplayName("Test if the expected API Gateway resource is present in the resources of the stack.") + public void testAPIGatewayResource() { + var restAPIId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::RestApi")); + var apiGatewayResourceMatchMap = Map.of( + "/Type", "AWS::ApiGateway::Resource", + "/Properties/ParentId/Fn::GetAtt/0", restAPIId, + "/Properties/PathPart", "HELLO", + "/Properties/RestApiId/Ref", restAPIId + ); + Assertions.assertNotNull(findResource(stackResourcesMap, apiGatewayResourceMatchMap)); + } + + @Test + @DisplayName("Test if the expected Lambda permissions are present in the resources of the stack.") + public void testLambdaPermissions() { + var lambdaFunctionId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::Lambda::Function")); + var lambdaPermissionsMatchMap = Map.of( + "/Type", "AWS::Lambda::Permission", + "/Properties/Action", "lambda:InvokeFunction", + "/Properties/FunctionName/Fn::GetAtt/0", lambdaFunctionId + ); + Long expectedPermissionsCount = 2L; + Assertions.assertTrue( + Optional.ofNullable(findResources(stackResourcesMap, lambdaPermissionsMatchMap)) + .map(Map::entrySet) + .map(Set::stream) + .map(Stream::count) + .filter(permissionsCont -> permissionsCont.equals(expectedPermissionsCount)) + .isPresent() + ); + } + + @Test + @DisplayName("Test if the expected API Gateway method is present in the resources of the stack.") + public void testAPIGatewayMethod() { + var apiGatewayResourceId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::Resource")); + var restAPIId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::RestApi")); + var authorizerId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::Authorizer")); + var apiGatewayMethodMatchMap = Map.of( + "/Type", "AWS::ApiGateway::Method", + "/Properties/AuthorizationType", "COGNITO_USER_POOLS", + "/Properties/AuthorizerId/Ref", authorizerId, + "/Properties/HttpMethod", "GET", + "/Properties/ResourceId/Ref", apiGatewayResourceId, + "/Properties/RestApiId/Ref", restAPIId + ); + Assertions.assertNotNull(findResource(stackResourcesMap, apiGatewayMethodMatchMap)); + } + + @Test + @DisplayName("Test if the expected Cognito user pool is present in the resources of the stack.") + public void testCognitoUserPool() { + var cognitoUserPoolMatchMap = Map.of( + "/Type", "AWS::Cognito::UserPool", + "/Properties/AutoVerifiedAttributes/0", "email", + "/Properties/UsernameAttributes/0", "email" + ); + Assertions.assertNotNull(findResource(stackResourcesMap, cognitoUserPoolMatchMap)); + } + + @Test + @DisplayName("Test if the expected API Gateway authorizer is present in the resources of the stack.") + public void testAPIGatewayAuthorizer() { + var restAPIId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::ApiGateway::RestApi")); + var cognitoUserPoolId = findResourceId(stackResourcesMap, Map.of("/Type", "AWS::Cognito::UserPool")); + var apiGatewayAuthorizerMatchMap = Map.of( + "/Type", "AWS::ApiGateway::Authorizer", + "/Properties/IdentitySource", "method.request.header.Authorization", + "/Properties/Name", "HelloWorldAPIAuthorizer", + "/Properties/ProviderARNs/0/Fn::GetAtt/0", cognitoUserPoolId, + "/Properties/RestApiId/Ref", restAPIId, + "/Properties/Type", "COGNITO_USER_POOLS" + ); + Assertions.assertNotNull(findResource(stackResourcesMap, apiGatewayAuthorizerMatchMap)); + } +} diff --git a/java/cognito-api-lambda/src/test/java/com/myorg/TestUtils.java b/java/cognito-api-lambda/src/test/java/com/myorg/TestUtils.java new file mode 100644 index 000000000..e1f157bd7 --- /dev/null +++ b/java/cognito-api-lambda/src/test/java/com/myorg/TestUtils.java @@ -0,0 +1,61 @@ +package com.myorg; + +import com.fasterxml.jackson.databind.JsonNode; + +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; +import java.util.Optional; +import java.util.function.Predicate; +import java.util.stream.Collectors; + +import static org.junit.platform.commons.util.StringUtils.isNotBlank; + +public class TestUtils { + + public static String findResourceId(Map stackResources, Map matchMap) { + return Optional.ofNullable(findResource(stackResources, matchMap)) + .map(Entry::getKey) + .orElse(null); + } + + public static Entry findResource(Map stackResources, Map matchMap) { + return stackResources.entrySet().stream() + .filter(createResourcePredicate(matchMap)) + .findAny() + .orElse(null); + } + + public static Map findResources(Map stackResources, Map matchMap) { + return stackResources.entrySet().stream() + .filter(createResourcePredicate(matchMap)) + .collect(Collectors.toMap( + Entry::getKey, + Entry::getValue + )); + } + + public static Predicate> createResourcePredicate(String expectedJsonPath, String expectedJsonValue) { + return stackResourceEntry -> Optional.ofNullable(stackResourceEntry) + .map(Entry::getValue) + .flatMap( + resource -> Optional.ofNullable(expectedJsonPath) + .map(resource::at) + .map(JsonNode::asText) + ).filter(propertyValue -> propertyValue.equals(expectedJsonValue)) + .isPresent(); + } + + public static Predicate> createResourcePredicate(Map matchMap) { + return Optional.ofNullable(matchMap) + .map(Map::entrySet) + .flatMap( + matchEntrySet -> matchEntrySet.stream() + .filter(Objects::nonNull) + .filter(matchEntry -> isNotBlank(matchEntry.getKey())) + .filter(matchEntry -> isNotBlank(matchEntry.getValue())) + .map(matchEntry -> createResourcePredicate(matchEntry.getKey(), matchEntry.getValue())) + .reduce(Predicate::and) + ).orElseGet(() -> stackResourceEntry -> false); + } +} From ec0aab16099ad638545acad0a71eb709eee6a4c7 Mon Sep 17 00:00:00 2001 From: Souvik Bose Date: Sat, 2 Nov 2024 08:27:27 -0700 Subject: [PATCH 2/4] Add an example for ingesting CloudWatch logs into OpenSearch using OpenSearch Ingestion pipeline. (#1056) * Example CDK project for CloudWatch logs ingestion using OSI and CW subscription filter. * Rename the resources and add README Signed-off-by: Souvik Bose * Update package.json Update cdk and specify version for alpha module. * does not work and should match cdk version. * Update package.json Need to add alpha suffix. * Update cwlogs_subscription_stack.ts Update Python version * Update cwlogs_subscription_stack.ts * Update os_setup_stack.ts Update to account SP * Update os_setup_stack.ts --------- Signed-off-by: Souvik Bose Co-authored-by: Souvik Bose Co-authored-by: Michael Kaiser Co-authored-by: Michael Kaiser --- .../opensearch/cwlogs_ingestion/.gitignore | 8 + .../opensearch/cwlogs_ingestion/.npmignore | 6 + .../opensearch/cwlogs_ingestion/README.md | 70 +++++ .../bin/cwlogs_ingestion_stack.ts | 16 ++ .../opensearch/cwlogs_ingestion/cdk.json | 55 ++++ .../cwlogs_ingestion/docs/architecture.png | Bin 0 -> 35957 bytes .../cwlogs_ingestion/docs/architecture.xml | 1 + .../lib/cwlogs_subscription_stack.ts | 99 +++++++ .../cwlogs_ingestion/lib/os_setup_stack.ts | 244 ++++++++++++++++++ .../opensearch/cwlogs_ingestion/package.json | 32 +++ .../lambda/cw_subscription_filter/handler.py | 57 ++++ .../layers/requirements.txt | 3 + .../resources/lambda/log_emitter/handler.py | 15 ++ .../resources/pipeline/configuration.yaml | 15 ++ .../opensearch/cwlogs_ingestion/tsconfig.json | 23 ++ 15 files changed, 644 insertions(+) create mode 100644 typescript/opensearch/cwlogs_ingestion/.gitignore create mode 100644 typescript/opensearch/cwlogs_ingestion/.npmignore create mode 100644 typescript/opensearch/cwlogs_ingestion/README.md create mode 100644 typescript/opensearch/cwlogs_ingestion/bin/cwlogs_ingestion_stack.ts create mode 100644 typescript/opensearch/cwlogs_ingestion/cdk.json create mode 100644 typescript/opensearch/cwlogs_ingestion/docs/architecture.png create mode 100644 typescript/opensearch/cwlogs_ingestion/docs/architecture.xml create mode 100644 typescript/opensearch/cwlogs_ingestion/lib/cwlogs_subscription_stack.ts create mode 100644 typescript/opensearch/cwlogs_ingestion/lib/os_setup_stack.ts create mode 100644 typescript/opensearch/cwlogs_ingestion/package.json create mode 100644 typescript/opensearch/cwlogs_ingestion/resources/lambda/cw_subscription_filter/handler.py create mode 100644 typescript/opensearch/cwlogs_ingestion/resources/lambda/cw_subscription_filter/layers/requirements.txt create mode 100644 typescript/opensearch/cwlogs_ingestion/resources/lambda/log_emitter/handler.py create mode 100644 typescript/opensearch/cwlogs_ingestion/resources/pipeline/configuration.yaml create mode 100644 typescript/opensearch/cwlogs_ingestion/tsconfig.json diff --git a/typescript/opensearch/cwlogs_ingestion/.gitignore b/typescript/opensearch/cwlogs_ingestion/.gitignore new file mode 100644 index 000000000..f60797b6a --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/.gitignore @@ -0,0 +1,8 @@ +*.js +!jest.config.js +*.d.ts +node_modules + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/typescript/opensearch/cwlogs_ingestion/.npmignore b/typescript/opensearch/cwlogs_ingestion/.npmignore new file mode 100644 index 000000000..c1d6d45dc --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/.npmignore @@ -0,0 +1,6 @@ +*.ts +!*.d.ts + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/typescript/opensearch/cwlogs_ingestion/README.md b/typescript/opensearch/cwlogs_ingestion/README.md new file mode 100644 index 000000000..0c660dafe --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/README.md @@ -0,0 +1,70 @@ +## Amazon OpenSearch Ingestion + +## + +![Stability: Stable](https://img.shields.io/badge/stability-Stable-success.svg?style=for-the-badge) + +> **This is a stable example. It should successfully build out of the box** +> +> This example is built on Construct Libraries marked "Stable" and does not have any infrastructure prerequisites to build. + +--- + + + +## Overview + +[Amazon OpenSearch Ingestion](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/ingestion.html) is a fully managed, serverless data collector that delivers real-time log, metric, and trace data to [Amazon OpenSearch Service domains](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/what-is.html) and [Amazon OpenSearch Serverless collections](https://docs.aws.amazon.com/opensearch-service/latest/developerguide/serverless.html). + +In this example, we show how to use the [AWS Cloud Development Kit (CDK)](https://docs.aws.amazon.com/cdk/v2/guide/home.html) to set up an Amazon OpenSearch Ingestion Pipeline to ingest CloudWatch logs using a [CloudWatch subscription filter]() and write to Amazon OpenSearch Serverless collection in an [Amazon Virtual Private Cloud (VPC)](https://aws.amazon.com/vpc/). The pipeline is setup to receive log events on `/logs/ingest` path using the OpenSearch Ingestion pipeline API endpoint. + +![](docs/architecture.png) +_figure1.Architecture Diagram of loading CloudWatch logs into an OpenSearch Serverless collection using an OpenSearch Ingestion pipeline_ + +The CDK stack sets up roles and permissions to enable all of the services to communicate with one-another. It further provides access for the deploying user's IAM identity. Finally, the stack sets up a VPC, and creates a VPC endpoint for communication to OpenSearch Serverless (see below for configuration). + +### Configuration of the code + +To configure the solution for your account, visit [cwlogs_ingestion_stack](./cwlogs_ingestion/bin/cwlogs_ingestion_stack.ts). There are 2 stacks that are created here: +- `OpenSearchSetupStack` +- `CWLogsSubscriptionStack` + +You can modify the names of the resources in `OpenSearchSetupStack` stack. Below are default values: + +``` +STACK_NAMING_PREFIX = 'cw-to-os' + +STACK_RESOURCE_NAMING_PREFIX = 'OpenSearchSetup' + +COLLECTION_NAME = '${this.STACK_NAMING_PREFIX}-col' +PIPELINE_NAME = '${this.STACK_NAMING_PREFIX}-pipe' +NETWORK_POLICY_NAME = '${this.STACK_NAMING_PREFIX}-net-pol' +ENCRYPTION_POLICY_NAME = '${this.STACK_NAMING_PREFIX}-enc-pol' +DATA_ACCESS_POLICY_NAME = '${this.STACK_NAMING_PREFIX}-data-pol' +``` + +For, `CWLogsSubscriptionStack` stack, visit [cwlogs_subscription_stack](./cwlogs_ingestion/lib/cwlogs_subscription_stack.ts). This stack deploys the following resources: + +- `CWLogsSubscriptionLogEmitter` lambda to publish logs to CloudWatch which is invoked every 5 minutes triggered using an EventBridge timer. +- Lambda Subscription Filter for CloudWatch logs published by the `CWLogsSubscriptionLogEmitter` lambda resource + +To view data in your OpenSearch Serverless Collection navigate to the Amazon OpenSearch Service console. In the left navigation pane click the reveal triangle if it's not already open. Click **Collections**. Click **cw-to-os-col** (or find your **COLLECTION_NAME** if you changed it). Scroll down until you see the **Endpoint** section, and click the URL under **OpenSearch Dashboards URL**. This will launch OpenSearch Dashboards. + +In OpenSearch Dashboards, dismiss the initial splash screen. In the upper right, find the **Manage** link, and click it. Click **Index Patterns** in the left navigation pane. Click **Create index pattern**. and type `ddb-to-aoss-*` into the **Index pattern name** text box. Click **Next step**. Drop down the **Time field** menu, and select `@timestamp`. Click **Create index pattern**. + +## Build and Deploy + +The `cdk.json` file tells the CDK Toolkit how to execute your app. + +## Synthesize Cloudformation Template + +To see the Cloudformation template generated by the CDK, run `cdk synth`, then check the output file in the "cdk.out" directory. + +## Deploy + +- Run `cdk deploy OpenSearchSetupStack` to deploy OpenSearch Serverless collection, OpenSearch Ingestion Pipeline resources to your personal account. +- Run `cdk deploy CWLogsSubscriptionStack` to deploy CloudWatch logs subscription filter lambda resources to your personal account. + +## CDK Destroy + +If no longer want the stack to be running, you can destroy the stack by running `cdk destroy` diff --git a/typescript/opensearch/cwlogs_ingestion/bin/cwlogs_ingestion_stack.ts b/typescript/opensearch/cwlogs_ingestion/bin/cwlogs_ingestion_stack.ts new file mode 100644 index 000000000..5c02d2b2c --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/bin/cwlogs_ingestion_stack.ts @@ -0,0 +1,16 @@ +#!/usr/bin/env node +import "source-map-support/register"; +import { OpenSearchSetupStack } from "../lib/os_setup_stack"; +import { CWLogsSubscriptionStack } from "../lib/cwlogs_subscription_stack"; +import { App } from "aws-cdk-lib"; + +const app = new App(); +const opensearch_stack = new OpenSearchSetupStack( + app, + "OpenSearchSetupStack", + {}, +); + +new CWLogsSubscriptionStack(app, "CWLogsSubscriptionFilterStack", { + ingestionEndpointURL: opensearch_stack.ingestionEndPointURL, +}); \ No newline at end of file diff --git a/typescript/opensearch/cwlogs_ingestion/cdk.json b/typescript/opensearch/cwlogs_ingestion/cdk.json new file mode 100644 index 000000000..ee1a49130 --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/cdk.json @@ -0,0 +1,55 @@ +{ + "app": "npx ts-node --prefer-ts-exts bin/cwlogs_ingestion_stack.ts", + "watch": { + "include": ["**"], + "exclude": [ + "README.md", + "cdk*.json", + "**/*.d.ts", + "**/*.js", + "tsconfig.json", + "package*.json", + "yarn.lock", + "node_modules", + "test" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": ["aws", "aws-cn"], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-iam:standardizedServicePrincipals": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true + } +} diff --git a/typescript/opensearch/cwlogs_ingestion/docs/architecture.png b/typescript/opensearch/cwlogs_ingestion/docs/architecture.png new file mode 100644 index 0000000000000000000000000000000000000000..090fe68442ecac51a8a5a38866d879409b01f2ce GIT binary patch literal 35957 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 IA^QIR4-|K~>;M1& literal 0 HcmV?d00001 diff --git a/typescript/opensearch/cwlogs_ingestion/docs/architecture.xml b/typescript/opensearch/cwlogs_ingestion/docs/architecture.xml new file mode 100644 index 000000000..6bf0520a0 --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/docs/architecture.xml @@ -0,0 +1 @@ +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 \ No newline at end of file diff --git a/typescript/opensearch/cwlogs_ingestion/lib/cwlogs_subscription_stack.ts b/typescript/opensearch/cwlogs_ingestion/lib/cwlogs_subscription_stack.ts new file mode 100644 index 000000000..77e89eddf --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/lib/cwlogs_subscription_stack.ts @@ -0,0 +1,99 @@ +import { PythonLayerVersion } from '@aws-cdk/aws-lambda-python-alpha'; +import { Duration, Stack, StackProps } from 'aws-cdk-lib'; +import { Rule, Schedule } from 'aws-cdk-lib/aws-events'; +import { LambdaFunction } from 'aws-cdk-lib/aws-events-targets'; +import { Effect, PolicyStatement } from 'aws-cdk-lib/aws-iam'; +import { Code, Runtime, Function, Alias } from 'aws-cdk-lib/aws-lambda'; +import { FilterPattern, LogGroup, RetentionDays, SubscriptionFilter } from 'aws-cdk-lib/aws-logs'; +import { LambdaDestination } from 'aws-cdk-lib/aws-logs-destinations'; +import { Construct } from 'constructs'; +import path = require('path'); + +export interface CWLogsSubscriptionStackProps extends StackProps { + ingestionEndpointURL: string +} + +export class CWLogsSubscriptionStack extends Stack { + + private readonly STACK_NAMING_PREFIX: string = 'cwlogs-subscription'; + + constructor(scope: Construct, id: string, props: CWLogsSubscriptionStackProps) { + super(scope, id, props); + + ///////////////////////////////////////////////////////////////////////////////// + // + // Create the Log Emitter Lambda resources + // + ///////////////////////////////////////////////////////////////////////////////// + const logGroup = new LogGroup(this, `EventBridgeTriggeredLambdaLogGroup`, { + retention: RetentionDays.ONE_WEEK, + }); + + // Lambda Function to publish message + const lambdaFn = new Function(this, 'EventBridgeTriggeredLambdaFunction', { + code: Code.fromAsset(path.join(__dirname, '../resources/lambda/log_emitter')), + handler: 'handler.log_emitter', + timeout: Duration.seconds(300), + runtime: Runtime.PYTHON_3_12, + logGroup: logGroup + }); + + // Run the eventbridge every 5 minute interval to generate logs + const rule = new Rule(this, 'Rule', { + schedule: Schedule.rate(Duration.minutes(5)) + }); + + // Add the lambda function as a target to the eventbridge + rule.addTarget(new LambdaFunction(lambdaFn)); + + + ///////////////////////////////////////////////////////////////////////////////// + // + // Create the CloudWatch Log group subscription filter resources + // + ///////////////////////////////////////////////////////////////////////////////// + + const lambdaLayer = new PythonLayerVersion(this, `${this.STACK_NAMING_PREFIX}LambdaLayer`, { + entry: path.join(__dirname, "../resources/lambda/cw_subscription_filter/layers"), + compatibleRuntimes: [ + Runtime.PYTHON_3_12, + Runtime.PYTHON_3_11, + ], + description: "A layer that contains the required modules", + license: "MIT License", + }); + + const lambdaFunction = new Function(this, `${this.STACK_NAMING_PREFIX}LambdaFunction`, { + runtime: Runtime.PYTHON_3_12, + code: Code.fromAsset(path.join(__dirname, '../resources/lambda/cw_subscription_filter')), + handler: 'handler.cw_subscription_handler', + layers: [lambdaLayer], + environment: { + OSI_INGESTION_ENDPOINT: props.ingestionEndpointURL, + }, + } + ); + + new Alias(this, `${this.STACK_NAMING_PREFIX}LambdaFunctionAlias`, { + aliasName: 'live', + version: lambdaFunction.currentVersion, + }); + + lambdaFunction.addToRolePolicy( + new PolicyStatement({ + effect: Effect.ALLOW, + resources: ['*'], + actions: ['osis:ingest'], + }), + ); + + // Create a Lambda Subscription Filter on the specific log group created above + const subscriptionFilter = new SubscriptionFilter(this, `${this.STACK_NAMING_PREFIX}LogSubscription`, { + logGroup: logGroup, + destination: new LambdaDestination(lambdaFunction), + filterPattern: FilterPattern.allEvents(), + }); + subscriptionFilter.node.addDependency(lambdaFunction); + } + +} diff --git a/typescript/opensearch/cwlogs_ingestion/lib/os_setup_stack.ts b/typescript/opensearch/cwlogs_ingestion/lib/os_setup_stack.ts new file mode 100644 index 000000000..bae2882c4 --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/lib/os_setup_stack.ts @@ -0,0 +1,244 @@ +import { Fn, Stack, StackProps } from 'aws-cdk-lib'; +import { Peer, Port, SecurityGroup, Vpc } from 'aws-cdk-lib/aws-ec2'; +import { Effect, Policy, PolicyDocument, PolicyStatement, Role, AccountPrincipal, ServicePrincipal } from 'aws-cdk-lib/aws-iam'; +import { CfnAccessPolicy, CfnCollection, CfnSecurityPolicy, CfnVpcEndpoint } from 'aws-cdk-lib/aws-opensearchserverless'; +import { CfnPipeline } from 'aws-cdk-lib/aws-osis'; +import { Construct } from 'constructs'; +import { readFileSync } from "fs"; + +export class OpenSearchSetupStack extends Stack { + + private readonly STACK_NAMING_PREFIX: string = 'cw-to-os'; + private readonly STACK_RESOURCE_NAMING_PREFIX: string = 'OpenSearchSetup'; + private readonly COLLECTION_NAME: string = `${this.STACK_NAMING_PREFIX}-col`; + private readonly DATA_ACCESS_POLICY_NAME: string = `${this.STACK_NAMING_PREFIX}-data-pol`; + private readonly NETWORK_POLICY_NAME: string = `${this.STACK_NAMING_PREFIX}-net-pol`; + private readonly ENCRYPTION_POLICY_NAME: string = `${this.STACK_NAMING_PREFIX}-enc-pol`; + private readonly VPC_ENDPOINT_NAME: string = `${this.STACK_NAMING_PREFIX}-vpc`; + private readonly PIPELINE_NAME: string = `${this.STACK_NAMING_PREFIX}-pipe`; + + public readonly ingestionEndPointURL: string; + + constructor(scope: Construct, id: string, props?: StackProps) { + super(scope, id, props); + + // Create VPC + const vpc = new Vpc(this, `${this.STACK_RESOURCE_NAMING_PREFIX}-vpc`); + + // Create Security Group + const securityGroup = new SecurityGroup(this, `${this.STACK_RESOURCE_NAMING_PREFIX}-security-group`, { + description: 'Security group for OpenSearch', + vpc: vpc, + allowAllOutbound: true, + }); + + securityGroup.addIngressRule(Peer.anyIpv4(), Port.tcp(443)); + securityGroup.connections.allowFrom( + securityGroup, + Port.allTraffic(), + 'Allow ingress from the same SecurityGroup', + ); + + // Create VPC Endpoint + const vpcEndpoint = new CfnVpcEndpoint(this, `${this.STACK_RESOURCE_NAMING_PREFIX}VpcEndpoint`, { + name: this.VPC_ENDPOINT_NAME, + vpcId: vpc.vpcId, + subnetIds: vpc.privateSubnets.map((subnet) => subnet.subnetId), + securityGroupIds: [securityGroup.securityGroupId], + }); + + // Create OpenSearch Serverless network security policy + const cfnNetworkAccessPolicy = new CfnSecurityPolicy(this, `${this.STACK_RESOURCE_NAMING_PREFIX}NetworkPolicy`, { + name: this.NETWORK_POLICY_NAME, + type: 'network', + policy: JSON.stringify([ + { + AllowFromPublic: false, + Rules: [ + { + ResourceType: 'collection', + Resource: [`collection/${this.COLLECTION_NAME}`], + }, + ], + SourceVPCEs: [vpcEndpoint.attrId], + }, + { + AllowFromPublic: true, + Rules: [ + { + ResourceType: 'dashboard', + Resource: [`collection/${this.COLLECTION_NAME}`], + }, + ], + }, + ]), + }); + + // Create OpenSearch Serverless encryption policy + const cfnEncryptionPolicy = new CfnSecurityPolicy(this, `${this.STACK_RESOURCE_NAMING_PREFIX}EncryptionPolicy`, { + name: this.ENCRYPTION_POLICY_NAME, + type: 'encryption', + policy: JSON.stringify({ + Rules: [ + { + ResourceType: 'collection', + Resource: [`collection/${this.COLLECTION_NAME}`], + } + ], + AWSOwnedKey: true + }) + }); + + // Create OpenSearch Serverless collection + const cfnCollection = new CfnCollection( + this, + `${this.COLLECTION_NAME}Collection`, + { + name: this.COLLECTION_NAME, + description: 'OpenSearch serverless collection to be used for search from CDK', + type: 'SEARCH', + }, + ); + + cfnCollection.addDependency(cfnEncryptionPolicy); + cfnCollection.addDependency(cfnNetworkAccessPolicy); + + // Create IAM role for OpenSearch Ingestion pipeline + const pipelineRole = new Role(this, `${this.STACK_RESOURCE_NAMING_PREFIX}PipelineRole`, { + roleName: `${this.STACK_RESOURCE_NAMING_PREFIX}PipelineRole`, + assumedBy: new ServicePrincipal('osis-pipelines.amazonaws.com'), + inlinePolicies: { + 'OSISPipelineRolePolicy': this.pipelinePolicies(cfnCollection.attrArn) + } + }); + + // Create OpenSearch Ingestion pipeline + const cfnPipeline = new CfnPipeline(this, `${this.STACK_RESOURCE_NAMING_PREFIX}Pipeline`, { + maxUnits: 4, + minUnits: 2, + bufferOptions: { + persistentBufferEnabled: true + }, + pipelineConfigurationBody: this.getPipelineConfiguration(pipelineRole.roleArn, cfnCollection.attrCollectionEndpoint), + pipelineName: this.PIPELINE_NAME, + }); + + this.ingestionEndPointURL = Fn.select(0, cfnPipeline.attrIngestEndpointUrls); + + cfnPipeline.addDependency(cfnCollection); + + // Create a dashboard access role + const dashboardAccessRole = new Role(this, `${this.STACK_RESOURCE_NAMING_PREFIX}DashboardAccessRole`, { + assumedBy: new AccountPrincipal(this.account) , + }); + + dashboardAccessRole.attachInlinePolicy( + new Policy(this, `${this.STACK_RESOURCE_NAMING_PREFIX}DashboardAccessPolicy`, { + statements: [ + new PolicyStatement({ + effect: Effect.ALLOW, + resources: ['*'], + actions: ['aoss:*'], + }), + ], + }), + ); + + // Create OpenSearch Serverless data access policy + const data_access_policy_arns: string[] = [pipelineRole.roleArn, dashboardAccessRole.roleArn]; + + const cfnDataAccessPolicy = new CfnAccessPolicy(this, `${this.STACK_NAMING_PREFIX}AccessPolicy`, { + name: this.DATA_ACCESS_POLICY_NAME, + type: 'data', + policy: JSON.stringify([ + { + Rules: [ + { + ResourceType: 'index', + Resource: [`index/${this.COLLECTION_NAME}/*`], + Permission: [ + 'aoss:CreateIndex', + 'aoss:DescribeIndex', + 'aoss:ReadDocument', + 'aoss:WriteDocument', + 'aoss:UpdateIndex', + 'aoss:DeleteIndex', + ], + }, + { + ResourceType: 'collection', + Resource: [`collection/${this.COLLECTION_NAME}`], + Permission: [ + 'aoss:CreateCollectionItems', + 'aoss:DeleteCollectionItems', + 'aoss:UpdateCollectionItems', + 'aoss:DescribeCollectionItems', + ], + }, + ], + Principal: data_access_policy_arns, + }, + ]), + }); + + cfnDataAccessPolicy.addDependency(cfnCollection); + cfnDataAccessPolicy.addDependency(cfnPipeline); + } + + pipelinePolicies(collectionArn: string) { + const policyDocument = new PolicyDocument(); + policyDocument.addStatements( + new PolicyStatement({ + 'effect': Effect.ALLOW, + "resources": ["*"], + "actions": [ + "aoss:BatchGetCollection" + ] + })); + policyDocument.addStatements( + new PolicyStatement({ + 'effect': Effect.ALLOW, + "resources": [collectionArn], + "actions": [ + "aoss:APIAccessAll" + ] + })); + policyDocument.addStatements( + new PolicyStatement({ + 'effect': Effect.ALLOW, + "resources": [`arn:aws:aoss:*:${this.account}:dashboards/default`], + "actions": [ + "aoss:DashboardsAccessAll" + ] + })); + policyDocument.addStatements( + new PolicyStatement({ + 'effect': Effect.ALLOW, + "resources": ["*"], + "actions": [ + "aoss:CreateSecurityPolicy", + "aoss:GetSecurityPolicy", + "aoss:UpdateSecurityPolicy" + ], + "conditions": { + "StringEquals": { + "aoss:collection": this.COLLECTION_NAME + } + } + })); + return policyDocument; + } + + getPipelineConfiguration(roleArn: string, collectionEndPoint: string) { + let pipelineConfigurationTemplate = readFileSync('resources/pipeline/configuration.yaml').toString() + + const formattedPipelineConfiguration = + pipelineConfigurationTemplate + .replace('', collectionEndPoint) + .replace('', roleArn) + .replace('', this.region) + .replace('', this.NETWORK_POLICY_NAME); + + return formattedPipelineConfiguration; + } +} diff --git a/typescript/opensearch/cwlogs_ingestion/package.json b/typescript/opensearch/cwlogs_ingestion/package.json new file mode 100644 index 000000000..cba042315 --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/package.json @@ -0,0 +1,32 @@ +{ + "name": "cwlogs_ingestion", + "version": "0.1.0", + "bin": { + "cwlogs_ingestion": "bin/cwlogs_ingestion.js" + }, + "scripts": { + "clean": "rm -rf build dist cdk.out node_modules && find . -name \"*.js\" -type f -delete && find . -name \"*.d.ts\" -type f -delete", + "build": "tsc", + "watch": "tsc -w", + "cdk": "cdk" + }, + "devDependencies": { + "@types/jest": "^29.5.4", + "@types/node": "20.5.9", + "aws-cdk": "^2.165.0", + "aws-cdk-lib": "^2.165.0", + "constructs": "^10.2.43", + "globals": "^15.6.0", + "jest": "^29.6.4", + "ts-jest": "^29.1.1", + "ts-node": "^10.9.1", + "typescript": "~5.2.2" + }, + "dependencies": { + "@aws-cdk/aws-lambda-python-alpha": "2.165.0-alpha.0", + "aws-cdk": "^2.165.0", + "aws-cdk-lib": "^2.165.0", + "constructs": "^10.0.0", + "source-map-support": "^0.5.21" + } +} diff --git a/typescript/opensearch/cwlogs_ingestion/resources/lambda/cw_subscription_filter/handler.py b/typescript/opensearch/cwlogs_ingestion/resources/lambda/cw_subscription_filter/handler.py new file mode 100644 index 000000000..b0a4090e3 --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/resources/lambda/cw_subscription_filter/handler.py @@ -0,0 +1,57 @@ +import base64 +import gzip +import logging +import json +import jmespath +import requests +import os +from datetime import datetime +from requests_auth_aws_sigv4 import AWSSigV4 + +def cw_subscription_handler(event, context): + + """Extract the data from the event""" + data = jmespath.search("awslogs.data", event) + + """Decompress the logs""" + cwLogs = decompress_json_data(data) + + """Construct the payload to send to OpenSearch Ingestion""" + payload = prepare_payload(cwLogs) + + """Ingest the set of events to the pipeline""" + response = ingestData(payload) + + return { + 'statusCode': 200, + 'execute-api': { + 'status_code': response.status_code, + 'response': response.text + } + } +def decompress_json_data(data): + compressed_data = base64.b64decode(data) + uncompressed_data = gzip.decompress(compressed_data) + return json.loads(uncompressed_data) + +def prepare_payload(cwLogs): + payload = [] + logEvents = cwLogs['logEvents'] + for logEvent in logEvents: + request = {} + request['@id'] = logEvent['id'] + request['@timestamp'] = str(datetime.now().year) + '0' + str(datetime.now().month) + '0' + str(datetime.now().day) + request['@message'] = logEvent['message'] + request['@owner'] = cwLogs['owner'] + request['@log_group'] = cwLogs['logGroup'] + request['@log_stream'] = cwLogs['logStream'] + + payload.append(request) + return payload + +def ingestData(payload): + ingestionEndpoint = os.environ["OSI_INGESTION_ENDPOINT"] + endpoint = 'https://' + ingestionEndpoint + response = requests.request('POST', f'{endpoint}/logs/ingest', data=json.dumps(payload), auth=AWSSigV4('osis')) + print('Response received: ' + response.text) + return response \ No newline at end of file diff --git a/typescript/opensearch/cwlogs_ingestion/resources/lambda/cw_subscription_filter/layers/requirements.txt b/typescript/opensearch/cwlogs_ingestion/resources/lambda/cw_subscription_filter/layers/requirements.txt new file mode 100644 index 000000000..7bfeb86a6 --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/resources/lambda/cw_subscription_filter/layers/requirements.txt @@ -0,0 +1,3 @@ +boto3 +requests +requests_auth_aws_sigv4 \ No newline at end of file diff --git a/typescript/opensearch/cwlogs_ingestion/resources/lambda/log_emitter/handler.py b/typescript/opensearch/cwlogs_ingestion/resources/lambda/log_emitter/handler.py new file mode 100644 index 000000000..d66d37bbb --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/resources/lambda/log_emitter/handler.py @@ -0,0 +1,15 @@ +from datetime import datetime +import json +from random import randrange + +def log_emitter(event, context): + source = {} + id = str(randrange(10000)) + source['id'] = id + source['timestamp'] = str(datetime.now()) + source['message'] = 'Hello world' + source['owner'] = 'aws-osi' + + print(json.dumps(source)) + + diff --git a/typescript/opensearch/cwlogs_ingestion/resources/pipeline/configuration.yaml b/typescript/opensearch/cwlogs_ingestion/resources/pipeline/configuration.yaml new file mode 100644 index 000000000..286eaf010 --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/resources/pipeline/configuration.yaml @@ -0,0 +1,15 @@ +version: "2" +cwlogs-ingestion-http-pipeline: + source: + http: + path: /logs/ingest + sink: + - opensearch: + hosts: [""] + aws: + sts_role_arn: "" + region: "" + serverless: true + serverless_options: + network_policy_name: "" + index: "cwl-%{yyyy-MM-dd}" diff --git a/typescript/opensearch/cwlogs_ingestion/tsconfig.json b/typescript/opensearch/cwlogs_ingestion/tsconfig.json new file mode 100644 index 000000000..464ed774b --- /dev/null +++ b/typescript/opensearch/cwlogs_ingestion/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": ["es2020", "dom"], + "declaration": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "typeRoots": ["./node_modules/@types"] + }, + "exclude": ["node_modules", "cdk.out"] +} From 63d0cf7fa59b2c99ea43eb08bcb3d863838ca16a Mon Sep 17 00:00:00 2001 From: SGhotra1 <73190872+SGhotra1@users.noreply.github.com> Date: Mon, 4 Nov 2024 15:09:18 +0100 Subject: [PATCH 3/4] feat(typescript/quicksight): Add an example that creates a useable dataset in Quicksight (#1085) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Initial quicksight example commit * Used world population data, created logical columns, refactored naming of variables * refactor: improving naming and sorting the code * fix: re-add deployment to dependencies of the quicksight data source * refactor: cleanup imports * refactor: quicksight datasource name moved to a static property * refactor: policy generation and cleanup * refactor: naming of definitions for the quicksight table * refactor: move dataset name to a static * docs: add instructions * refactor: Fixed some links for Cloudformation resources docs, quicksightAccountArn needs to be passed as context * docs: a tad more info in the readme * chore: readme updated * chore: add resources information * docs: Added explanation of the quicksight arn, removed test scripts * chore: Add DO_NOT_AUTOTEST file --------- Co-authored-by: Sebastian Schürmann Co-authored-by: KathiHae Co-authored-by: Carlos Revuelto Quero <99762845+carreque@users.noreply.github.com> Co-authored-by: Sebastian Schürmann --- typescript/quicksight/DO_NOT_AUTOTEST | 0 typescript/quicksight/README.md | 66 +++ .../quicksight/bin/quicksight-example.ts | 14 + typescript/quicksight/cdk.json | 72 ++++ .../quicksight/data/world-population-data.csv | 271 ++++++++++++ typescript/quicksight/lib/data-transforms.ts | 391 ++++++++++++++++++ typescript/quicksight/lib/input-columns.ts | 72 ++++ .../lib/quicksight-example-stack.ts | 205 +++++++++ typescript/quicksight/package.json | 26 ++ typescript/quicksight/tsconfig.json | 31 ++ 10 files changed, 1148 insertions(+) create mode 100644 typescript/quicksight/DO_NOT_AUTOTEST create mode 100644 typescript/quicksight/README.md create mode 100644 typescript/quicksight/bin/quicksight-example.ts create mode 100644 typescript/quicksight/cdk.json create mode 100644 typescript/quicksight/data/world-population-data.csv create mode 100644 typescript/quicksight/lib/data-transforms.ts create mode 100644 typescript/quicksight/lib/input-columns.ts create mode 100644 typescript/quicksight/lib/quicksight-example-stack.ts create mode 100644 typescript/quicksight/package.json create mode 100644 typescript/quicksight/tsconfig.json diff --git a/typescript/quicksight/DO_NOT_AUTOTEST b/typescript/quicksight/DO_NOT_AUTOTEST new file mode 100644 index 000000000..e69de29bb diff --git a/typescript/quicksight/README.md b/typescript/quicksight/README.md new file mode 100644 index 000000000..198e2c7c8 --- /dev/null +++ b/typescript/quicksight/README.md @@ -0,0 +1,66 @@ + +--- + +![Stability: Cfn-Only](https://img.shields.io/badge/stability-Cfn--Only-important.svg?style=for-the-badge) + +> **This is an experimental example. It may not build out of the box** +> +> This example is built on Cfn resources. +> +> It requires additional infrastructure prerequisites that must be created before successful build, see below. +> +> If build is unsuccessful, please create an [issue](https://github.com/aws-samples/aws-cdk-examples/issues/new) so that we may debug the problem +--- + + +## Overview + +This project demonstrates how to set up Amazon Quicksight. It will set up a S3 Bucket, import some test data and makes it available as a datasource to quicksight. + +With this setup you can create analysis in the console to view e.g. the world-population data: +world-population.csv file in data directory taken from https://data.worldbank.org/indicator/SP.POP.TOTL +License: CC BY-4.0 + +## Build + +To build this app, you need to be in this example's root folder. Then run the following: + +```bash +npm install -g aws-cdk +npm install +npm run build +``` + +## Resources + +1. * `Bucket` (aws-s3): Creates an Amazon S3 bucket with encryption and full access control, used to store data files and the manifest for QuickSight. +2. * `BucketDeployment` (aws-s3-deployment): Deploys world population data and manifest JSON files to the S3 bucket, making them accessible for analysis in QuickSight. +3. * `CfnDataSource` (aws-quicksight): Defines an Amazon QuickSight data source that connects to the S3 bucket to access the uploaded CSV files. +4. * `CfnDataSet` (aws-quicksight): Configures a QuickSight dataset that organizes and structures the CSV data from the S3 bucket for reporting and analysis. +5. * `CfnManagedPolicy` (aws-iam): Creates an IAM policy granting permissions to the QuickSight service role, allowing access to the S3 bucket and other necessary actions. + +## Deploy + +1. Create a quicksight account [by following these instructions](https://docs.aws.amazon.com/quicksight/latest/user/signing-up.html). +2. Use the arn of the quicksight account and pass it to cdk using a context `cdk deploy --context quicksightAccountArn=` + +The Quicksight account arn should look like this 'arn:aws:quicksight:\:\:user/\/\' + +#### \ +The aws region that contains the quicksight resources. +#### \ +This is your AWS account id. +#### \ +You can create a separate namespace, but if you haven't created one it should be 'default'. +#### \ +You can find the username in Quicksight. It should be the same as your IAM Account name +and if you are using a role it will be added to the name as well like: \/\ + +## Useful commands + +* `npm run build` compile typescript to js +* `npm run watch` watch for changes and compile +* `npm run test` perform the jest unit tests +* `npx cdk deploy` deploy this stack to your default AWS account/region +* `npx cdk diff` compare deployed stack with current state +* `npx cdk synth` emits the synthesized CloudFormation template diff --git a/typescript/quicksight/bin/quicksight-example.ts b/typescript/quicksight/bin/quicksight-example.ts new file mode 100644 index 000000000..872c2c003 --- /dev/null +++ b/typescript/quicksight/bin/quicksight-example.ts @@ -0,0 +1,14 @@ +#!/usr/bin/env node +import 'source-map-support/register'; +import * as cdk from 'aws-cdk-lib'; +import { QuicksightExampleStack } from '../lib/quicksight-example-stack'; + +const app = new cdk.App(); + +// Quicksight account arn should look like this 'arn:aws:quicksight:::user//' +const quicksightExampleProps = {quicksightAccountArn: app.node.tryGetContext('quicksightAccountArn')}; +if (quicksightExampleProps.quicksightAccountArn == null) { + console.log('quicksightAccountArn is empty! Please provide it via the cdk context'); + process.exit(1); +} +new QuicksightExampleStack(app, 'QuicksightExampleStack', quicksightExampleProps); diff --git a/typescript/quicksight/cdk.json b/typescript/quicksight/cdk.json new file mode 100644 index 000000000..5df2fb745 --- /dev/null +++ b/typescript/quicksight/cdk.json @@ -0,0 +1,72 @@ +{ + "app": "npx ts-node --prefer-ts-exts bin/quicksight-example.ts", + "watch": { + "include": [ + "**" + ], + "exclude": [ + "README.md", + "cdk*.json", + "**/*.d.ts", + "**/*.js", + "tsconfig.json", + "package*.json", + "yarn.lock", + "node_modules", + "test" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, + "@aws-cdk/aws-eks:nodegroupNameAttribute": true, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false + } +} diff --git a/typescript/quicksight/data/world-population-data.csv b/typescript/quicksight/data/world-population-data.csv new file mode 100644 index 000000000..5e1eb34df --- /dev/null +++ b/typescript/quicksight/data/world-population-data.csv @@ -0,0 +1,271 @@ +"Data Source","World Development Indicators", + +"Last Updated Date","2024-09-19", + +"Country Name","Country Code","Indicator Name","Indicator Code","1960","1961","1962","1963","1964","1965","1966","1967","1968","1969","1970","1971","1972","1973","1974","1975","1976","1977","1978","1979","1980","1981","1982","1983","1984","1985","1986","1987","1988","1989","1990","1991","1992","1993","1994","1995","1996","1997","1998","1999","2000","2001","2002","2003","2004","2005","2006","2007","2008","2009","2010","2011","2012","2013","2014","2015","2016","2017","2018","2019","2020","2021","2022","2023", +"Aruba","ABW","Population, total","SP.POP.TOTL","54608","55811","56682","57475","58178","58782","59291","59522","59471","59330","59106","58816","58855","59365","60028","60715","61193","61465","61738","62006","62267","62614","63116","63683","64174","64478","64553","64450","64332","64596","65712","67864","70192","72360","74710","77050","79417","81858","84355","86867","89101","90691","91781","92701","93540","94483","95606","96787","97996","99212","100341","101288","102112","102880","103594","104257","104874","105439","105962","106442","106585","106537","106445","106277", +"Africa Eastern and Southern","AFE","Population, total","SP.POP.TOTL","130692579","134169237","137835590","141630546","145605995","149742351","153955516","158313235","162875171","167596160","172475766","177503186","182599092","187901657","193512956","199284304","205202669","211120911","217481420","224315978","230967858","237937461","245386717","252779730","260209149","267938123","276035920","284490394","292795186","301124880","309890664","318544083","326933522","335625136","344418362","353466601","362985802","372352230","381715600","391486231","401600588","412001885","422741118","433807484","445281555","457153837","469508516","482406426","495748900","509410477","523459657","537792950","552530654","567892149","583651101","600008424","616377605","632746570","649757148","667242986","685112979","702977106","720859132","739108306", +"Afghanistan","AFG","Population, total","SP.POP.TOTL","8622466","8790140","8969047","9157465","9355514","9565147","9783147","10010030","10247780","10494489","10752971","11015857","11286753","11575305","11869879","12157386","12425267","12687301","12938862","12986369","12486631","11155195","10088289","9951449","10243686","10512221","10448442","10322758","10383460","10673168","10694796","10745167","12057433","14003760","15455555","16418912","17106595","17788819","18493132","19262847","19542982","19688632","21000256","22645130","23553551","24411191","25442944","25903301","26427199","27385307","28189672","29249157","30466479","31541209","32716210","33753499","34636207","35643418","36686784","37769499","38972230","40099462","41128771","42239854", +"Africa Western and Central","AFW","Population, total","SP.POP.TOTL","97256290","99314028","101445032","103667517","105959979","108336203","110798486","113319950","115921723","118615741","121424797","124336039","127364044","130563107","133953892","137548613","141258400","145122851","149206663","153459665","157825609","162323313","167023385","171566640","176054495","180817312","185720244","190759952","195969722","201392200","206739024","212172888","217966101","223788766","229675775","235861484","242200260","248713095","255482918","262397030","269611898","277160097","284952322","292977949","301265247","309824829","318601484","327612838","336893835","346475221","356337762","366489204","376797999","387204553","397855507","408690375","419778384","431138704","442646825","454306063","466189102","478185907","490330870","502789511", +"Angola","AGO","Population, total","SP.POP.TOTL","5357195","5441333","5521400","5599827","5673199","5736582","5787044","5827503","5868203","5928386","6029700","6177049","6364731","6578230","6802494","7032713","7266780","7511895","7771590","8043218","8330047","8631457","8947152","9276707","9617702","9970621","10332574","10694057","11060261","11439498","11828638","12228691","12632507","13038270","13462031","13912253","14383350","14871146","15366864","15870753","16394062","16941587","17516139","18124342","18771125","19450959","20162340","20909684","21691522","22507674","23364185","24259111","25188292","26147002","27128337","28127721","29154746","30208628","31273533","32353588","33428486","34503774","35588987","36684202", +"Albania","ALB","Population, total","SP.POP.TOTL","1608800","1659800","1711319","1762621","1814135","1864791","1914573","1965598","2022272","2081695","2135479","2187853","2243126","2296752","2350124","2404831","2458526","2513546","2566266","2617832","2671997","2726056","2784278","2843960","2904429","2964762","3022635","3083605","3142336","3227943","3286542","3266790","3247039","3227287","3207536","3187784","3168033","3148281","3128530","3108778","3089027","3060173","3051010","3039616","3026939","3011487","2992547","2970017","2947314","2927519","2913021","2905195","2900401","2895092","2889104","2880703","2876101","2873457","2866376","2854191","2837849","2811666","2777689","2745972", +"Andorra","AND","Population, total","SP.POP.TOTL","9443","10216","11014","11839","12690","13563","14546","15745","17079","18449","19860","21322","22832","24393","26003","27640","29294","30949","32574","34142","35611","36987","38598","40432","42181","43809","45605","47635","49654","51639","53569","55434","57283","59156","61037","62928","64147","64682","65186","65655","66097","67820","70849","73907","76933","79826","80221","78168","76055","73852","71519","70567","71013","71367","71621","71746","72540","73837","75013","76343","77700","79034","79824","80088", +"Arab World","ARB","Population, total","SP.POP.TOTL","93359407","95760348","98268683","100892507","103618568","106444103","109394536","112499764","115729597","119061868","122475578","125979765","129605560","133384981","137372356","141756318","146815543","151960544","156741680","162014425","167707208","173118753","178587926","184342569","190162096","195956917","201916517","207894127","213455083","219021375","225923327","230837072","236598334","242994250","249596194","255803349","261953764","268158920","274376380","280650496","287065982","293512340","300018650","306573087","313249616","320558754","328703057","337498222","346630443","355754908","364427661","372351065","380383408","389131555","397922915","406501999","415077960","423664839","432545676","441467739","449228296","456520777","464684914","473272080", +"United Arab Emirates","ARE","Population, total","SP.POP.TOTL","133426","140984","148877","157006","165305","173797","182509","191404","213582","253261","298084","344513","392368","441546","491955","543394","614177","706861","805231","908452","1014048","1100180","1167856","1237572","1308331","1379536","1468697","1575909","1683681","1791840","1900151","2008383","2116231","2223284","2329024","2433988","2572735","2746119","2921130","3097563","3275333","3454198","3633655","3813443","3993339","4280993","4898954","5872624","6988685","7992644","8481771","8575205","8664969","8751847","8835951","8916899","8994263","9068296","9140169","9211657","9287289","9365145","9441129","9516871", +"Argentina","ARG","Population, total","SP.POP.TOTL","20349744","20680653","21020359","21364017","21708487","22053661","22403116","22757014","23112971","23472028","23842803","24223379","24612794","25020588","25449754","25875558","26290257","26713780","27146121","27584134","28024803","28471285","28922762","29377137","29832197","30287112","30748326","31216453","31690792","32165766","32637657","33105763","33568285","34027240","34488696","34946110","35389362","35815971","36233195","36653031","37070774","37480493","37885028","38278164","38668796","39070501","39476851","39876111","40273769","40684338","40788453","41261490","41733271","42202935","42669500","43131966","43590368","44044811","44494502","44938712","45376763","45808747","46234830","46654581", +"Armenia","ARM","Population, total","SP.POP.TOTL","1904148","1971530","2039346","2106142","2171029","2234051","2295496","2355997","2416461","2476359","2534377","2590923","2648048","2706852","2767646","2830798","2896311","2965523","3038224","3097058","3135123","3167876","3202011","3238291","3272102","3300896","3327182","3351364","3366838","3448186","3556539","3617631","3574555","3457349","3373713","3322782","3298898","3271418","3240550","3206030","3168523","3133133","3105037","3084102","3065745","3047246","3026486","3004393","2983421","2964296","2946293","2928976","2914421","2901385","2889930","2878595","2865835","2851923","2836557","2820602","2805608","2790974","2780469","2777970", +"American Samoa","ASM","Population, total","SP.POP.TOTL","20085","20626","21272","21949","22656","23391","24122","24848","25608","26396","27075","27593","28063","28529","29012","29573","30198","30816","31428","32045","32886","34059","35367","36735","38168","39663","41221","42842","44532","46288","47818","48992","50078","51174","52288","53401","54500","55578","56603","57594","58230","58324","58177","57941","57626","57254","56837","56383","55891","55366","54849","54310","53691","52995","52217","51368","50448","49463","48424","47321","46189","45035","44273","43914", +"Antigua and Barbuda","ATG","Population, total","SP.POP.TOTL","55342","56245","57008","57778","58664","59644","60615","61617","62658","63742","64517","64769","64695","64463","64218","64035","63990","64117","64329","64609","64889","65076","65231","65408","65362","65048","64712","64353","63982","63636","63328","63634","64659","65834","67072","68398","69798","71218","72572","73821","75055","76215","77195","78075","78941","79869","80895","82016","83251","84534","85695","86729","87674","88497","89236","89941","90564","91119","91626","92117","92664","93219","93763","94298", +"Australia","AUS","Population, total","SP.POP.TOTL","10276477","10483000","10742000","10950000","11167000","11388000","11651000","11799000","12009000","12263000","12507000","12937000","13177000","13380000","13723000","13893000","14033000","14192000","14358000","14514000","14692000","14923260","15184247","15393472","15579391","15788312","16018350","16263874","16532164","16814416","17065128","17284036","17478635","17634808","17805468","18004882","18224767","18423037","18607584","18812264","19028802","19274701","19495210","19720737","19932722","20176844","20450966","20827622","21249199","21691653","22031750","22340024","22733465","23128129","23475686","23815995","24190907","24592588","24963258","25334826","25649248","25685412","26014399","26638544", +"Austria","AUT","Population, total","SP.POP.TOTL","7047539","7086299","7129864","7175811","7223801","7270889","7322066","7376998","7415403","7441055","7467086","7500482","7544201","7586115","7599038","7578903","7565525","7568430","7562305","7549425","7549433","7568710","7574140","7561910","7561434","7564985","7569794","7574586","7585317","7619567","7677850","7754891","7840709","7905633","7936118","7948278","7959017","7968041","7976789","7992324","8011566","8042293","8081957","8121423","8171966","8227829","8268641","8295487","8321496","8343323","8363404","8391643","8429991","8479823","8546356","8642699","8736668","8797566","8840521","8879920","8916864","8955797","9041851","9132383", +"Azerbaijan","AZE","Population, total","SP.POP.TOTL","3894500","4045750","4168150","4293550","4439250","4574650","4708150","4832000","4948500","5063300","5172050","5282950","5391450","5493900","5594100","5689050","5781000","5876150","5976150","6071300","6160500","6257750","6357550","6459800","6567850","6670150","6770300","6875350","6974600","7076550","7175200","7271300","7382050","7494800","7596550","7684850","7763000","7838250","7913000","7982750","8048600","8111200","8171950","8234100","8306500","8391850","8484550","8581300","8763400","8947243","9054332","9173082","9295784","9416801","9535079","9649341","9757812","9854033","9939771","10024283","10093121","10137750","10141756","10112555", +"Burundi","BDI","Population, total","SP.POP.TOTL","2746628","2815972","2887398","2948133","3033221","3118134","3193378","3274493","3352397","3424429","3497834","3582070","3579195","3571450","3660032","3749232","3830889","3927428","4039410","4137437","4312834","4490743","4602271","4726506","4842268","4948024","5041706","5157769","5271840","5373697","5483793","5594828","5743085","5555220","5586408","5932783","5930507","5923862","6035340","6180180","6307659","6465729","6648938","6860846","7120496","7388874","7658190","7944609","8278109","8709366","9126605","9455733","9795479","10149577","10494913","10727148","10903327","11155593","11493472","11874838","12220227","12551213","12889576","13238559", +"Belgium","BEL","Population, total","SP.POP.TOTL","9153489","9183948","9220578","9289770","9378113","9463667","9527807","9580991","9618756","9646032","9655549","9673162","9711115","9741720","9772419","9800700","9818227","9830358","9839534","9848382","9859242","9858982","9856303","9855520","9855372","9858308","9861823","9870234","9901664","9937697","9967379","10004486","10045158","10084475","10115603","10136811","10156637","10181245","10203008","10226419","10251250","10286570","10332785","10376133","10421137","10478617","10547958","10625700","10709973","10796493","10895586","11038264","11106932","11159407","11209057","11274196","11331422","11375158","11427054","11488980","11538604","11586195","11685814","11822592", +"Benin","BEN","Population, total","SP.POP.TOTL","2512284","2551216","2593302","2638082","2685619","2735843","2788642","2843739","2901218","2961166","3023443","3088381","3156408","3227380","3301276","3378703","3460329","3546454","3636927","3732394","3833939","3941569","4054385","4171526","4293070","4419552","4551382","4688787","4831624","4979680","5133419","5293046","5457778","5706181","5923394","6046511","6203860","6387026","6584183","6788589","6998023","7212041","7431783","7659208","7894554","8149419","8402631","8647761","8906469","9172514","9445710","9726380","10014078","10308730","10614844","10932783","11260085","11596779","11940683","12290444","12643123","12996895","13352864","13712828", +"Burkina Faso","BFA","Population, total","SP.POP.TOTL","4783259","4852833","4924497","4998671","5076111","5157929","5242797","5330613","5422119","5515747","5611666","5707793","5805283","5907742","6018141","6138444","6269765","6416569","6577779","6749939","6932967","7123730","7321817","7531184","7751476","7979185","8207827","8434996","8663720","8895234","9131361","9365064","9598555","9840075","10091256","10353263","10621210","10897353","11201063","11533554","11882888","12249764","12632269","13030591","13445977","13876127","14316242","14757074","15197915","15650022","16116845","16602651","17113732","17636408","18169842","18718019","19275498","19835858","20392723","20951639","21522626","22100683","22673762","23251485", +"Bangladesh","BGD","Population, total","SP.POP.TOTL","50396429","51882769","53461661","55094115","56774465","58500159","60265259","62104488","63995652","65866908","67541860","68376204","69346705","71144818","72947807","74700345","76380080","78137788","80007550","81908151","83929765","86154836","88555336","91045478","93534239","95959099","98271746","100490256","102688833","104893674","107147651","109242834","111272102","113418757","115614891","117793338","119876868","122039226","124350471","126754824","129193327","131670484","134139826","136503206","138789725","140912590","142628831","144135934","145421318","146706810","148391139","150211005","152090649","154030139","155961299","157830000","159784568","161793964","163683958","165516222","167420951","169356251","171186372","172954319", +"Bulgaria","BGR","Population, total","SP.POP.TOTL","7867374","7943118","8012946","8078145","8144340","8204168","8258057","8310226","8369603","8434172","8489574","8536395","8576200","8620967","8678745","8720742","8758599","8804183","8814032","8825940","8861535","8891117","8917457","8939738","8960679","8960547","8958171","8971359","8981446","8876972","8718289","8632367","8540164","8472313","8443591","8406067","8362826","8312068","8256786","8210624","8170172","8009142","7837161","7775327","7716860","7658972","7601022","7545338","7492561","7444443","7395599","7348328","7305888","7265115","7223938","7177991","7127822","7075947","7025037","6975761","6934015","6877743","6465097","6430370", +"Bahrain","BHR","Population, total","SP.POP.TOTL","160691","166970","173359","179891","186587","193012","199019","204916","210801","216696","222555","230992","243143","256632","270627","285116","300044","315337","330912","346697","362595","377430","391017","404772","419217","434375","450196","466565","483337","500349","517418","535415","554470","573755","593254","612934","632756","652643","672484","692133","711442","730257","748324","778256","833451","901921","970981","1040532","1110343","1179453","1213645","1212077","1224939","1261673","1311134","1362142","1409661","1456834","1487340","1494188","1477469","1463265","1472233","1485509", +"Bahamas, The","BHS","Population, total","SP.POP.TOTL","114500","120216","126305","132639","138785","144849","151323","158197","165456","172745","179129","184435","189181","193563","197767","201881","206096","210534","215016","219426","223752","227956","232177","236586","241166","245935","250804","255618","260452","265493","270679","276058","281973","288164","293997","299554","304933","310171","315398","320272","325014","329626","334002","338490","343089","347804","352664","357666","362795","368057","373272","377950","382061","385650","389131","392697","395976","399020","401906","404557","406471","407906","409984","412623", +"Bosnia and Herzegovina","BIH","Population, total","SP.POP.TOTL","3262539","3325333","3387512","3448532","3507959","3565517","3620849","3673367","3723067","3770376","3815561","3859242","3901895","3943152","3983063","4022090","4060039","4096516","4131521","4165511","4199820","4235970","4274013","4312521","4349597","4383306","4413374","4440300","4463320","4481230","4494310","4502386","4275730","3942981","3762330","3750527","3907751","4047748","4115059","4153014","4179350","4194932","4198410","4183757","4142860","4094297","4058086","4007876","3943392","3877750","3811088","3743142","3674374","3617559","3571068","3524324","3480986","3440027","3400129","3360711","3318407","3270943","3233526","3210847", +"Belarus","BLR","Population, total","SP.POP.TOTL","8198000","8271216","8351928","8437232","8524224","8610000","8696496","8785648","8874552","8960304","9040000","9115576","9188968","9257272","9317584","9367000","9411000","9463000","9525000","9584000","9643000","9710000","9776000","9843000","9910000","9975000","10043000","10111000","10140000","10170000","10189348","10194050","10216470","10239050","10226955","10193831","10159569","10117433","10071963","10026738","9979610","9928549","9865548","9796749","9730146","9663915","9604924","9560953","9527985","9504583","9483836","9461643","9446836","9443211","9448515","9461076","9469379","9458989","9438785","9419758","9379952","9302585","9228071","9178298", +"Belize","BLZ","Population, total","SP.POP.TOTL","91403","93757","96188","98862","101772","104838","108062","111411","114825","118145","120905","123091","125054","126875","128620","130801","133471","136183","138933","141823","145133","148764","152409","156053","159721","163436","167191","170980","174817","178695","182589","186462","190299","194177","198416","203556","209840","217117","224907","232733","240406","248100","255987","263998","272128","280375","288729","297173","305671","314171","322106","329538","337059","344688","352335","359871","367313","374693","382066","389095","394921","400031","405272","410825", +"Bermuda","BMU","Population, total","SP.POP.TOTL","44400","45500","46600","47700","48900","50100","51000","52000","53000","54000","55000","54600","54200","53800","53400","53000","53200","53400","53600","53800","54670","55050","55449","55930","56423","56898","57382","57849","58347","58841","59326","59021","58595","58910","59320","59746","60129","60497","60943","61285","61833","62504","62912","63325","63740","64154","64523","64888","65273","65636","65124","64564","64798","65001","65138","65237","64554","63873","63918","63911","63893","63764","63595","63489", +"Bolivia","BOL","Population, total","SP.POP.TOTL","3707515","3784744","3864140","3945729","4029472","4115511","4204065","4295269","4389249","4486098","4585693","4688267","4793804","4902248","5013765","5127776","5244355","5363917","5486132","5610380","5736088","5862990","5991118","6120620","6251926","6385630","6521983","6661434","6804072","6949139","7096194","7244891","7394419","7544489","7693722","7841471","7989367","8137619","8286928","8439052","8592656","8746084","8900583","9057378","9216279","9377388","9542663","9711152","9880593","10051317","10223270","10396246","10569697","10743349","10916987","11090085","11263015","11435533","11606905","11777315","11936162","12079472","12224110","12388571", +"Brazil","BRA","Population, total","SP.POP.TOTL","73092515","75330008","77599218","79915555","82262794","84623747","86979283","89323288","91659246","94000381","96369875","98766288","101194394","103666904","106167372","108700515","111286504","113939886","116664382","119447303","122288383","125168060","128065095","130977370","133888775","136783180","139643355","142466264","145253973","148003411","150706446","153336445","155900790","158440875","160980472","163515328","166037122","168546707","171039804","173486281","175873720","178211881","180476685","182629278","184722043","186797334","188820682","190779453","192672317","194517549","196353492","198185302","199977707","201721767","203459650","205188205","206859578","208504960","210166592","211782878","213196304","214326223","215313498","216422446", +"Barbados","BRB","Population, total","SP.POP.TOTL","232550","233698","234829","235875","236834","237694","238494","239238","239905","240594","241397","242350","243458","244643","245851","247090","248359","249663","251009","252334","253575","254684","255642","256505","257279","257911","258370","258654","258762","258759","258868","259402","260212","260995","261712","262303","262793","263224","263642","264170","264657","265377","266455","267499","268505","269477","270425","271444","272635","273791","274711","275486","276197","276865","277493","278083","278649","279187","279688","280180","280693","281200","281635","281995", +"Brunei Darussalam","BRN","Population, total","SP.POP.TOTL","85346","89561","93837","98277","102904","107686","112597","117628","122764","128012","133343","138666","143886","149065","154314","159653","165064","170560","176176","181951","187921","194099","200630","207523","214682","222119","229815","237712","245729","253821","261928","269860","277416","284713","291935","299097","306196","313215","320152","327045","333926","340748","347463","354045","360461","366717","372808","378748","384568","390311","396053","401506","406634","411702","416656","421437","425994","430276","434274","438048","441725","445373","449002","452524", +"Bhutan","BTN","Population, total","SP.POP.TOTL","221266","227071","233417","240268","247444","255010","262976","271339","280102","289296","298894","308837","319128","329800","340842","352269","364119","376387","389072","402063","415257","428641","442201","456033","470165","484528","499151","514026","529051","544209","558442","567710","545944","520838","521260","527536","537494","546865","557143","570990","587207","603234","619048","634627","649991","663323","673260","681614","689737","697678","705516","713331","721145","728889","736357","743274","749761","756121","762096","767459","772506","777486","782455","787424", +"Botswana","BWA","Population, total","SP.POP.TOTL","512865","524403","536428","549041","562274","570975","574855","578723","582655","586737","592244","604139","626601","657246","691569","727930","766424","806968","849394","893500","938578","982747","1023009","1060717","1099170","1138704","1179263","1220361","1261272","1301671","1341474","1380584","1420695","1462262","1503544","1543634","1582169","1619354","1655699","1691558","1726985","1761930","1795130","1826863","1859085","1892807","1928704","1966977","2007320","2048997","2091664","2134037","2175425","2217278","2260376","2305171","2352416","2401840","2451409","2499702","2546402","2588423","2630296","2675352", +"Central African Republic","CAF","Population, total","SP.POP.TOTL","1679728","1710364","1742502","1776214","1811694","1849171","1888853","1930861","1975257","2021519","2067356","2111224","2153613","2195905","2239305","2283927","2318349","2342048","2365957","2390329","2415276","2441010","2467635","2495097","2523538","2553075","2583631","2615594","2657235","2724109","2809221","2898052","2991727","3089146","3187844","3276706","3363570","3458472","3555064","3655360","3759170","3844773","3930648","4026841","4115138","4208834","4294352","4375569","4467233","4564540","4660067","4732022","4773306","4802428","4798734","4819333","4904177","4996741","5094780","5209324","5343020","5457154","5579144","5742315", +"Canada","CAN","Population, total","SP.POP.TOTL","17909356","18271000","18614000","18964000","19325000","19678000","20048000","20412000","20744000","21028000","21324000","21962032","22218463","22491777","22807969","23143275","23449808","23725843","23963203","24201544","24515667","24819915","25116942","25366451","25607053","25842116","26100278","26446601","26791747","27276781","27691138","28037420","28371264","28684764","29000663","29302311","29610218","29905948","30155173","30401286","30685730","31020855","31359199","31642461","31938807","32242732","32571193","32888886","33247298","33630069","34005902","34339221","34713395","35080992","35434066","35704498","36110803","36545075","37072620","37618495","38028638","38239864","38939056","40097761", +"Central Europe and the Baltics","CEB","Population, total","SP.POP.TOTL","91401764","92232738","93009498","93840016","94715795","95440988","96146336","97043270","97884022","98606630","99134548","99635258","100357161","101112680","101939916","102860571","103776068","104616884","105329397","105948616","106541316","107129392","107730380","108297837","108838073","109338285","109824166","110296425","110686740","110801640","110743128","110469467","110111454","110041924","110021594","109864246","109626194","109422013","109238340","109060951","108447824","107660041","106959751","106624167","106331716","106041911","105772481","105378748","105001883","104800475","104421447","104174038","103935318","103713726","103496179","103257886","102994278","102740078","102538451","102398537","102180124","101413157","100108262","100156608", +"Switzerland","CHE","Population, total","SP.POP.TOTL","5327827","5434294","5573815","5694247","5789228","5856472","5918002","5991785","6067714","6136387","6180877","6213399","6260956","6307347","6341405","6338632","6302504","6281174","6281738","6294365","6319408","6354074","6391309","6418773","6441865","6470365","6504124","6545106","6593386","6646912","6715519","6799978","6875364","6938265","6993795","7040687","7071850","7088906","7110001","7143991","7184250","7229854","7284753","7339001","7389625","7437115","7483934","7551117","7647675","7743831","7824909","7912398","7996861","8089346","8188649","8282396","8373338","8451840","8514329","8575280","8638167","8704546","8775760","8849852", +"Channel Islands","CHI","Population, total","SP.POP.TOTL","109186","110225","111281","112410","113596","114832","116116","117430","118707","119884","121003","122162","123348","124465","125486","126393","127052","127425","127667","127850","127984","128510","129614","130881","132154","133450","134808","136264","137765","139228","140601","141557","142011","142291","142466","142559","142898","143549","144211","144811","145306","146044","147167","148341","149538","150763","151985","153225","154475","155721","156933","157819","158621","159794","160912","162190","163721","165215","167259","169410","171113","172683","174079","175346", +"Chile","CHL","Population, total","SP.POP.TOTL","8141820","8313535","8486120","8656006","8825046","8994936","9161649","9326268","9491502","9656299","9820481","9984378","10145765","10307842","10472743","10639531","10804869","10969861","11137748","11304331","11469828","11637613","11807408","11976513","12147758","12326396","12514502","12712784","12918389","13128619","13342868","13561945","13782297","13998386","14210674","14416796","14615483","14809289","14996742","15176410","15351799","15523978","15693790","15859112","16017966","16175311","16334575","16495538","16661462","16833447","17004162","17173573","17341771","17509925","17687108","17870124","18083879","18368577","18701450","19039485","19300315","19493184","19603733","19629590", +"China","CHN","Population, total","SP.POP.TOTL","667070000","660330000","665770000","682335000","698355000","715185000","735400000","754550000","774510000","796025000","818315000","841105000","862030000","881940000","900350000","916395000","930685000","943455000","956165000","969005000","981235000","993885000","1008630000","1023310000","1036825000","1051040000","1066790000","1084035000","1101630000","1118650000","1135185000","1150780000","1164970000","1178440000","1191835000","1204855000","1217550000","1230075000","1241935000","1252735000","1262645000","1271850000","1280400000","1288400000","1296075000","1303720000","1311020000","1317885000","1324655000","1331260000","1337705000","1345035000","1354190000","1363240000","1371860000","1379860000","1387790000","1396215000","1402760000","1407745000","1411100000","1412360000","1412175000","1410710000", +"Cote d'Ivoire","CIV","Population, total","SP.POP.TOTL","3708661","3848336","3998287","4156453","4321368","4492890","4671196","4856689","5050106","5255149","5477086","5718867","5979984","6257373","6548923","6853981","7142690","7415900","7700816","7996368","8303810","8621621","8948119","9282050","9621405","9964075","10309440","10663498","11043193","11462943","11910540","12369269","12838314","13316448","13802285","14299727","14810946","15335453","15858990","16345894","16799670","17245468","17683897","18116451","18544903","18970215","19394057","19817700","20244449","20677762","21120042","21562914","22010712","22469268","22995555","23596741","24213622","24848016","25493988","26147551","26811790","27478249","28160542","28873034", +"Cameroon","CMR","Population, total","SP.POP.TOTL","5117608","5200355","5303841","5427511","5556209","5690086","5829580","5975087","6127193","6286232","6452787","6627350","6809468","6998688","7194697","7397417","7598028","7796825","8013279","8243377","8519891","8829048","9046986","9240672","9508570","9804254","10112712","10433905","10759573","11089222","11430520","11777719","12128604","12486773","12848862","13211647","13575324","13941181","14314599","14698973","15091594","15493253","15914033","16354326","16809407","17275171","17751333","18251866","18777081","19319274","19878036","20448873","21032684","21632850","22299585","23012646","23711630","24393181","25076747","25782341","26491087","27198628","27914536","28647293", +"Congo, Dem. Rep.","COD","Population, total","SP.POP.TOTL","15276558","15673284","16086084","16517995","16965855","17438254","17941738","18472105","19022799","19583123","20151733","20712952","21273409","21853906","22448415","23052715","23655016","24256464","25015244","25902760","26708686","27457783","28219219","29005175","29879852","30800051","31725132","32712574","33750052","34825891","35987541","37194812","38332302","39580844","41511985","43285791","44118709","44822198","45895524","47227238","48616317","50106657","51662071","53205639","54815607","56550247","58381630","60289422","62249724","64270232","66391257","68654269","70997870","73460021","76035588","78656904","81430977","84283273","87087355","89906890","92853164","95894118","99010212","102262808", +"Congo, Rep.","COG","Population, total","SP.POP.TOTL","1055693","1083431","1112348","1142600","1174269","1207412","1242116","1278312","1316130","1355699","1396989","1440159","1485274","1532069","1580280","1624935","1665418","1706181","1747207","1788218","1829256","1870540","1911634","1951851","2001739","2062555","2124863","2188654","2253336","2319177","2385435","2452675","2520958","2594168","2669220","2742309","2816595","2875037","2937166","3016659","3134030","3254101","3331158","3424653","3543012","3672839","3813323","3956329","4089602","4257230","4437884","4584216","4713257","4828066","4944861","5064386","5186824","5312340","5441062","5570733","5702174","5835806","5970424","6106869", +"Colombia","COL","Population, total","SP.POP.TOTL","15687688","16182414","16691282","17210956","17739754","18275814","18811407","19343961","19872503","20392264","20905254","21405413","21898055","22396318","22897871","23403731","23913002","24443926","25003608","25579323","26176195","26785982","27405194","28042329","28689032","29326260","29960101","30603048","31256727","31923117","32601393","33272628","33939039","34614735","35295461","35970101","36632573","37291946","37944414","38585033","39215135","39837875","40454050","41057687","41648268","42220940","42772910","43306582","43815313","44313917","44816108","45308899","45782417","46237930","46677947","47119728","47625955","48351671","49276961","50187406","50930662","51516562","51874024","52085168", +"Comoros","COM","Population, total","SP.POP.TOTL","194852","198617","202527","206546","210665","214939","219369","224321","229971","236002","242351","249066","256187","263728","271719","280036","288810","298152","307938","318123","328328","337986","347053","356137","365664","375650","386068","396887","408070","419584","431119","442277","452990","463318","473478","483760","494288","505033","515959","526443","536758","547741","559047","570130","581154","592683","604658","616899","629470","642493","656024","670071","684553","699393","714612","730216","746232","761664","776313","790986","806166","821625","836774","852075", +"Cabo Verde","CPV","Population, total","SP.POP.TOTL","209849","214788","221484","228814","236362","244156","252238","260648","269408","278524","287262","293505","296818","299191","301682","304375","307015","309389","311685","313995","317234","321634","326319","330971","335473","339874","344271","348718","353233","358150","364563","372721","381947","391749","401655","411382","421007","430654","440214","449627","458251","465958","473231","480089","486583","492827","498884","504733","510336","515638","521212","527521","533864","539940","546076","552166","558394","564954","571202","577030","582640","587925","593149","598682", +"Costa Rica","CRI","Population, total","SP.POP.TOTL","1346302","1396138","1447037","1498647","1550661","1602736","1654619","1706062","1756333","1805968","1855697","1905486","1955547","2006247","2058235","2111850","2167544","2225630","2286210","2349258","2414303","2481334","2550780","2622532","2696200","2771463","2847849","2924595","3001461","3079001","3158253","3239414","3321939","3405372","3489152","3572856","3656234","3739421","3821421","3901430","3979193","4053222","4122623","4188610","4252800","4315887","4378172","4440019","4501921","4563127","4622252","4679926","4736593","4791535","4844288","4895242","4945205","4993842","5040734","5084532","5123105","5153957","5180829","5212173", +"Caribbean small states","CSS","Population, total","SP.POP.TOTL","1719747","1760647","1801140","1842018","1882012","1920806","1959063","1996792","2034050","2070611","2105333","2137603","2161722","2178240","2193773","2209263","2225099","2240643","2255168","2267669","2280663","2295232","2309508","2323503","2337040","2350145","2362152","2371752","2380933","2390808","2399288","2412122","2432356","2453739","2476169","2502323","2530137","2557844","2585353","2612065","2637733","2662831","2687634","2712172","2735176","2756536","2777604","2798623","2819748","2840648","2860236","2878168","2898802","2922026","2945840","2969980","2993247","3016651","3058106","3090374","3106185","3128519","3147057","3167738", +"Cuba","CUB","Population, total","SP.POP.TOTL","7267395","7418518","7574265","7736352","7902286","8067651","8230450","8390962","8550286","8709654","8869636","9025709","9169289","9297924","9413105","9514305","9600862","9672546","9729986","9774711","9809107","9848560","9908874","9984591","10065539","10149044","10235480","10326910","10425433","10527187","10626680","10713812","10783748","10840934","10887207","10926703","10963031","10998129","11033758","11070094","11105791","11139127","11170051","11199217","11225294","11246114","11260630","11269887","11276609","11283185","11290417","11298710","11309290","11321579","11332026","11339894","11342012","11336405","11328244","11316697","11300698","11256372","11212191","11194449", +"Curacao","CUW","Population, total","SP.POP.TOTL","124826","126125","128414","130860","133148","135266","136682","138140","140298","142581","144739","147389","147710","146912","148351","149129","149399","149459","148341","147851","148041","148629","150101","151159","151940","152711","152662","151456","149254","146937","145400","144403","143912","144299","144630","145139","146306","146956","144472","139428","133860","129047","129205","131897","134192","137658","141239","144056","145880","146833","148703","150831","152088","153822","155909","157980","159664","160175","159336","157441","154947","152369","149996","147862", +"Cayman Islands","CYM","Population, total","SP.POP.TOTL","8473","8626","8799","8985","9172","9366","9566","9771","9981","10181","10533","11117","11778","12443","13118","13791","14456","15116","15746","16378","17100","17904","18729","19572","20433","21313","22195","23075","23956","24888","26027","27340","28677","30038","31418","32802","34194","35579","36947","38295","39658","41054","42456","43862","45286","46727","48177","49647","51123","52602","54074","55492","56860","58212","59559","60911","62255","63581","64884","66134","67311","68136","68706","69310", +"Cyprus","CYP","Population, total","SP.POP.TOTL","585725","594771","601095","607072","612338","617345","622566","627695","632452","636821","640804","644413","647620","650705","648585","644982","648868","656414","663975","671611","679327","687170","696227","707477","719678","731664","743446","755021","766412","777592","788500","799061","810431","825986","844444","862418","880058","897471","914660","931600","948237","964830","982194","1000350","1018684","1037062","1055438","1073873","1092390","1110974","1129686","1145086","1156556","1166968","1176995","1187280","1197881","1208523","1218831","1228836","1237537","1244188","1251488","1260138", +"Czechia","CZE","Population, total","SP.POP.TOTL","9602006","9586651","9624660","9670685","9727804","9779358","9821040","9852899","9876346","9896580","9858071","9826815","9867632","9922266","9988459","10058620","10125939","10186755","10242098","10292341","10304193","10300591","10314826","10323856","10330213","10337118","10342227","10347318","10355276","10361068","10333355","10308578","10319123","10329855","10333587","10327253","10315241","10304131","10294373","10283860","10255063","10216605","10196916","10193998","10197101","10211216","10238905","10298828","10384603","10443936","10474410","10496088","10510785","10514272","10525347","10546059","10566332","10594438","10629928","10671870","10697858","10505772","10672118","10873689", +"Germany","DEU","Population, total","SP.POP.TOTL","72814900","73377632","74025784","74714353","75318337","75963695","76600311","76951336","77294314","77909682","78169289","78312842","78688452","78936666","78967433","78673554","78336950","78159814","78091820","78126350","78288576","78407907","78333366","78128282","77858685","77684873","77720436","77839920","78144619","78751283","79433029","80013896","80624598","81156363","81438348","81678051","81914831","82034771","82047195","82100243","82211508","82349925","82488495","82534176","82516260","82469422","82376451","82266372","82110097","81902307","81776930","80274983","80425823","80645605","80982500","81686611","82348669","82657002","82905782","83092962","83160871","83196078","83797985","84482267", +"Djibouti","DJI","Population, total","SP.POP.TOTL","85940","89270","93122","97670","102945","108772","114874","121168","127668","135390","144379","154225","165234","177327","191389","208582","229304","253083","278425","302856","324121","341316","355110","367726","382156","400709","424286","452272","482337","521104","577173","628521","623197","611231","623477","629619","644649","667786","694920","719371","742033","765490","789129","806411","818373","830861","846947","865196","882886","901103","919199","936811","954297","971753","989087","1006259","1023261","1040233","1057198","1073994","1090156","1105557","1120849","1136455", +"Dominica","DMA","Population, total","SP.POP.TOTL","59379","60395","61224","62031","62843","63744","64728","65760","66865","68007","68895","69430","69870","70334","70822","71300","71748","72142","72478","72768","72978","72932","72626","72269","71936","71596","71215","70808","70397","69975","69481","69141","69112","69169","69198","69201","69166","69081","68938","68698","68346","68153","68262","68442","68574","68674","68742","68775","68782","68787","68755","68742","68888","68819","69371","70007","70075","70403","70823","71428","71995","72412","72737","73040", +"Denmark","DNK","Population, total","SP.POP.TOTL","4579603","4611687","4647727","4684483","4722072","4759012","4797381","4835354","4864883","4891860","4928757","4963126","4991596","5021861","5045297","5059862","5072596","5088419","5104248","5116801","5123027","5121572","5117810","5114297","5111619","5113691","5120534","5127024","5129516","5132594","5140939","5154298","5171370","5188628","5206180","5233373","5263074","5284991","5304219","5321799","5339616","5358783","5375931","5390574","5404523","5419432","5437272","5461438","5493621","5523095","5547683","5570572","5591572","5614932","5643475","5683483","5728010","5764980","5793636","5814422","5831404","5856733","5903037","5946952", +"Dominican Republic","DOM","Population, total","SP.POP.TOTL","3298021","3408415","3521164","3635798","3752313","3868712","3987090","4108916","4230877","4352954","4475871","4599841","4724801","4851183","4978582","5106453","5235318","5365074","5495443","5625864","5755800","5885244","6014979","6147213","6282104","6417798","6554325","6692720","6834207","6980033","7129004","7278402","7427340","7576074","7723934","7869753","8012314","8150076","8282126","8411374","8540791","8669040","8795101","8919852","9043127","9164768","9284168","9402206","9522948","9648061","9775755","9903737","10030882","10157051","10282115","10405832","10527592","10647244","10765531","10881882","10999664","11117873","11228821","11332972", +"Algeria","DZA","Population, total","SP.POP.TOTL","11394307","11598608","11778260","11969451","12179099","12381256","12613389","12897115","13190975","13491016","13795915","14110271","14439748","14786469","15153602","15724692","16500516","17134192","17632645","18166981","18739378","19351357","20000096","20682111","21393530","22132905","22882553","23586101","24243018","24889507","25518074","26133905","26748303","27354327","27937006","28478022","28984634","29476031","29924668","30346083","30774621","31200985","31624696","32055883","32510186","32956690","33435080","33983827","34569592","35196037","35856344","36543541","37260563","38000626","38760168","39543154","40339329","41136546","41927007","42705368","43451666","44177969","44903225","45606480", +"East Asia & Pacific (excluding high income)","EAP","Population, total","SP.POP.TOTL","896452801","895982616","907849084","931103981","953977437","977483065","1004323080","1030442864","1057583766","1086447495","1116170774","1146513513","1175144020","1202800072","1228896581","1252472762","1274251072","1294846389","1315749587","1336881495","1357568923","1378929135","1402542074","1426243031","1448866962","1472135650","1496876017","1523084914","1549637871","1575635488","1601222039","1625888128","1649237070","1671930685","1694403785","1716310165","1737842789","1759202933","1779768710","1798994292","1816986829","1834082049","1850453077","1866220978","1881541652","1896768430","1911702057","1926287101","1940749039","1955023279","1969168373","1984249541","2001246209","2018050656","2034247084","2049740052","2065155186","2080901482","2094506990","2106374009","2116360715","2123610397","2129094071","2133652241", +"Early-demographic dividend","EAR","Population, total","SP.POP.TOTL","979461502","1004319366","1029962253","1056327420","1083430197","1110603410","1137875812","1166092667","1195278339","1225287413","1255661025","1285672098","1316555228","1349249410","1382608576","1416414404","1450710647","1485833546","1521983049","1559348459","1598348344","1639825731","1682434337","1724928292","1767765290","1811272313","1855624329","1900589995","1946149314","1992092223","2041043553","2088580891","2134566607","2179380224","2223076958","2267616622","2314334474","2361095210","2407186134","2452952807","2499206970","2545843129","2591204247","2635731526","2680567394","2725013738","2769421149","2813790790","2857587007","2901329923","2946285613","2991403487","3035159632","3078407213","3121656203","3165214886","3208369547","3250752755","3292896609","3334561751","3374383528","3411268373","3447398652","3486290439", +"East Asia & Pacific","EAS","Population, total","SP.POP.TOTL","1043333636","1045203037","1059600211","1085398906","1110819272","1136927045","1166227679","1194567141","1224255729","1255933616","1288490485","1322732627","1354211283","1384704173","1413718269","1439944265","1464087148","1486953865","1510060320","1533514709","1556403010","1580048609","1605925794","1631735726","1656258164","1681267266","1707611028","1735427884","1763555005","1791156275","1818247576","1844603995","1869453624","1893594516","1917553356","1940892820","1964042971","1986768093","2008680261","2028993034","2048148696","2066530023","2083969920","2100610344","2116651449","2132517760","2148405823","2164155292","2179914111","2195169711","2210203758","2225992094","2243776727","2261274500","2278232287","2294507020","2310721864","2327132966","2341383691","2353856866","2363934334","2370214403","2375208613","2380601170", +"Europe & Central Asia (excluding high income)","ECA","Population, total","SP.POP.TOTL","128004868","130820612","133624232","136412403","139183218","141850212","144532646","147243299","149917246","152495588","154904402","157302537","159769903","162210682","164636799","167025422","169417382","171856019","174295734","176711498","179134330","181605180","184101787","186767082","189482130","192169372","194943688","197778590","200590588","202941311","205274329","207469747","209295467","210691828","211613719","212235863","213252888","214167783","214788022","215247930","216002444","216892662","217808502","218779991","219860219","220987094","222181747","223150949","224757863","226581984","228742156","230906639","232735642","234709774","236718663","238848390","240976831","243006453","245052675","247195931","248913167","250663105","246915820","247474425", +"Europe & Central Asia","ECS","Population, total","SP.POP.TOTL","666316810","674006055","681853980","689723879","697597298","705266930","712106610","718908748","725472765","731807369","737417742","742980383","749108833","755028396","760712783","766207613","771636189","776969009","782276619","787563097","792958926","798163948","802960230","807615842","812473775","817419352","822539979","827779053","833073833","837911059","842133494","846468500","849923742","852844448","855003604","856623954","858323941","859830347","861000616","861975173","862909497","864048235","865618646","867833353","870382097","873001450","875680116","878472460","882068986","885603905","889077806","891273900","894705970","898764759","902938502","907094808","911173722","914748588","918181600","921212388","923384672","924168763","920988359","923929755", +"Ecuador","ECU","Population, total","SP.POP.TOTL","4618158","4751507","4890425","5034334","5183283","5337351","5495761","5658446","5825663","5997037","6172215","6350944","6533630","6720443","6911123","7105786","7304349","7506665","7712718","7922490","8135845","8352602","8572607","8795873","9022979","9254311","9490096","9729376","9969788","10210185","10449837","10686279","10914222","11132829","11347652","11561683","11775221","11987838","12199693","12412046","12626507","12845521","13070609","13301184","13534593","13770012","14009061","14251835","14496797","14742766","14989585","15237728","15483883","15722989","15957994","16195902","16439585","16696944","17015672","17343740","17588595","17797737","18001000","18190484", +"Egypt, Arab Rep.","EGY","Population, total","SP.POP.TOTL","27034499","27747867","28485022","29245936","30026648","30818469","31613132","32408414","33204629","33995955","34781986","35555969","36330768","37120776","37930374","38775584","39649050","40577356","41576636","42632458","43748556","44899573","46088647","47353665","48676443","50035843","51424313","52841319","54298446","55765843","57214630","58611032","59989142","61382200","62775847","64166908","65565195","66993728","68446011","69907887","71371371","72854261","74393759","75963322","77522427","79075310","80629670","82218755","83844783","85501064","87252413","89200054","91240376","93377890","95592324","97723799","99784030","101789386","103740765","105618671","107465134","109262178","110990103","112716598", +"Euro area","EMU","Population, total","SP.POP.TOTL","269385168","271727867","274105087","276517540","278953378","281432987","283803777","285908171","287907506","289911679","291544661","293192129","295189531","297059919","298719155","300215183","301525335","302746591","304018977","305309331","306668989","307893389","308788172","309428033","309939418","310521622","311282260","312125526","313147164","314457467","315870845","317411362","318746422","320056200","321026530","321810273","322570180","323308056","323978576","324784751","325792924","326862028","328443707","330208234","332006792","333709006","335250759","336971054","338599969","339682801","340467048","339722971","340450693","341584506","342725321","343718279","344683796","345370612","346153001","346517987","346961127","346942960","348331552","350357398", +"Eritrea","ERI","Population, total","SP.POP.TOTL","993568","1016932","1041552","1067295","1094042","1121739","1150264","1179554","1209602","1240562","1272748","1306234","1340838","1376516","1413220","1450867","1489656","1529802","1571193","1613829","1657982","1703789","1751045","1799814","1849594","1899243","1949611","2000355","2051546","2102131","2149960","2039220","1921153","1981419","2042500","2157220","2264073","2291561","2322753","2356477","2392880","2461927","2547424","2653390","2763140","2831732","2880093","2926168","3005779","3083888","3147727","3207570","3252596","3296367","3323425","3340006","3365287","3396933","3445374","3498818","3555868","3620312","3684032","3748901", +"Spain","ESP","Population, total","SP.POP.TOTL","30455000","30739250","31023366","31296651","31609195","31954292","32283194","32682947","33113134","33441054","33814531","34224490","34604469","34988947","35373335","35757900","36137812","36511638","36864898","37191330","37491165","37758631","37986012","38171525","38330364","38469512","38584624","38684815","38766939","38827764","38867322","38966376","39157685","39361262","39549108","39724050","39889852","40057389","40223509","40386875","40567864","40850412","41431558","42187645","42921895","43653155","44397319","45226803","45954106","46362946","46576897","46742697","46773055","46620045","46480882","46444832","46484062","46593236","46797754","47134837","47365655","47415794","47778340","48373336", +"Estonia","EST","Population, total","SP.POP.TOTL","1211537","1225077","1241623","1258857","1277086","1294566","1308597","1318946","1331214","1345249","1360076","1376955","1392518","1405951","1418169","1429352","1439576","1450211","1460188","1468333","1477219","1487666","1498414","1508745","1518617","1528781","1540190","1552221","1561900","1568131","1569174","1561314","1533091","1494128","1462514","1436634","1415594","1399535","1386156","1390244","1396985","1388115","1379350","1370720","1362550","1354775","1346810","1340680","1337090","1334515","1331475","1327439","1322696","1317997","1314545","1315407","1315790","1317384","1321977","1326898","1329522","1330932","1348840","1366188", +"Ethiopia","ETH","Population, total","SP.POP.TOTL","21739710","22281675","22852158","23448979","24073696","24727506","25377645","26051596","26778653","27530388","28308246","29099594","29891328","30694316","31488613","32252783","33062216","33695018","34259065","34758823","34945469","35818844","37213393","38235187","39202890","40285965","41455309","42851957","44511537","46195954","47878073","49937430","52011554","53791672","55620211","57476536","59347649","61233480","63136493","65077579","67031867","69018932","71073215","73168838","75301026","77469940","79691050","81996185","84357105","86755585","89237791","91817929","94451280","97084366","99746766","102471895","105293228","108197950","111129438","114120594","117190911","120283026","123379924","126527060", +"European Union","EUU","Population, total","SP.POP.TOTL","356947129","359937892","362998792","366152978","369387359","372533839","375563155","378512582","381280912","383958527","386116472","388229403","390859355","393386261","395778659","398096151","400211366","402170665","404056840","405879948","407760829","409490677","410875285","411956706","412891310","413866961","414996545","416199247","417528527","418925771","420308868","421744728","422972438","424347768","425406851","426212138","426906931","427549432","428122323","428828749","429342455","429910140","430898141","432434810","434059923","435600393","437014860","438484072","439892213","440934530","441552554","440769682","441419873","442496175","443601373","444570054","445515422","446215182","447001100","447367191","447692315","447178093","447370551","449476878", +"Fragile and conflict affected situations","FCS","Population, total","SP.POP.TOTL","245054534","250320873","255792159","261419447","267217843","273158163","279188642","285373478","291752459","298271801","304932033","311832372","318935016","326272935","333989998","341992350","350514335","359107582","367561832","376388838","384920163","392974640","401640207","410883312","420542833","430465285","440305466","450279373","460218589","470693520","483150347","493951561","506399343","519989331","534524440","548658108","561040609","573237237","585939751","599275261","612751355","626553787","641963096","658162649","674132661","690520612","707248050","723930164","741362383","759831151","778734290","797793348","817412582","837410155","857018106","876449625","896306261","916477490","936789597","957873862","979839336","1001870564","1019145355","1042703808", +"Finland","FIN","Population, total","SP.POP.TOTL","4429634","4461005","4491443","4523309","4548543","4563732","4580869","4605744","4626469","4623785","4606307","4612124","4639657","4666081","4690574","4711440","4725664","4738902","4752528","4764690","4779535","4799964","4826933","4855787","4881803","4902206","4918154","4932123","4946481","4964371","4986431","5013740","5041992","5066447","5088333","5107790","5124573","5139835","5153498","5165474","5176209","5188008","5200598","5213014","5228172","5246096","5266268","5288720","5313399","5338871","5363352","5388272","5413971","5438972","5461512","5479531","5495303","5508214","5515525","5521606","5529543","5541017","5556106","5584264", +"Fiji","FJI","Population, total","SP.POP.TOTL","401841","414534","427695","441385","455214","469010","482358","494632","505979","516952","527634","538000","547918","557244","566296","575804","586607","599289","613611","628859","644582","660630","676967","693593","710561","727461","742658","754778","764370","772704","780430","784832","786859","789198","790803","792246","796538","804572","813947","823422","832509","841320","849891","858306","866694","874923","883083","890648","896731","901383","905169","908355","911059","913453","915560","917200","918371","919019","918996","918465","920422","924610","929766","936375", +"France","FRA","Population, total","SP.POP.TOTL","46649927","47161641","47679792","48189939","48733997","49282756","49817041","50334012","50817020","51272683","51724116","52185222","52637888","53053660","53415250","53715733","53966558","54221988","54486195","54753575","55052582","55371044","55694106","55992656","56275701","56569195","56865193","57168409","57472651","57766282","58044701","58557577","58849943","59106166","59327585","59543659","59756533","59969944","60192790","60504420","60921384","61367388","61816234","62256970","62716306","63188395","63628261","64021737","64379696","64710879","65030575","65345233","65662240","66002289","66312067","66548272","66724104","66918020","67158348","67388001","67571107","67764304","67971311","68170228", +"Faroe Islands","FRO","Population, total","SP.POP.TOTL","34154","34572","34963","35385","35841","36346","36825","37234","37630","38011","38416","38861","39304","39746","40189","40626","41054","41481","41965","42506","43054","43613","44164","44669","45135","45575","46011","46477","46959","47490","47479","46810","46005","45096","44131","43805","44138","44495","44865","45203","45660","46245","46813","47392","47989","48291","48313","48361","48411","48429","48410","48386","48392","48418","48465","48816","49500","50230","50955","51681","52415","52889","53090","53270", +"Micronesia, Fed. Sts.","FSM","Population, total","SP.POP.TOTL","42986","44563","46200","47758","49231","50759","52346","53940","55553","57236","58989","60673","62265","63889","65552","67121","68602","70144","71983","74114","76299","78531","80816","83153","85543","87966","90397","92845","94987","96796","98603","100427","102893","106030","108844","110328","110785","111133","111406","111539","111709","111948","111992","111805","111438","110940","110301","109532","108704","107868","107588","107887","108232","108609","109024","109462","109925","110430","110929","111379","112106","113131","114164","115224", +"Gabon","GAB","Population, total","SP.POP.TOTL","513340","519329","525754","532592","539830","547535","555748","564436","573611","584628","597192","609693","622289","635288","648922","663340","678660","694931","712135","730188","749078","768904","789585","811098","833417","856482","880340","905016","930464","956509","983028","1009995","1037446","1065390","1093611","1121964","1150601","1179806","1209832","1240764","1272935","1306590","1341696","1378398","1417110","1458353","1502534","1549774","1599978","1653542","1711105","1772500","1836705","1902226","1966855","2028517","2086206","2140215","2192012","2242785","2292573","2341179","2388992","2436566", +"United Kingdom","GBR","Population, total","SP.POP.TOTL","52400000","52800000","53250000","53650000","54000000","54348050","54648500","54943600","55211700","55441750","55663250","55896223","56086065","56194527","56229974","56225800","56211968","56193492","56196504","56246951","56314216","56333829","56313641","56332848","56422072","56550268","56681396","56802050","56928327","57076711","57247586","57424897","57580402","57718614","57865745","58019030","58166950","58316954","58487141","58682466","58892514","59119673","59370479","59647577","59987905","60401206","60846820","61322463","61806995","62276270","62766365","63258810","63700215","64128273","64602298","65116219","65611593","66058859","66460344","66836327","67081234","67026292","67791000","68350000", +"Georgia","GEO","Population, total","SP.POP.TOTL","3645600","3703600","3760300","3816100","3870300","3921600","3966700","4005800","4042300","4080300","4119900","4163000","4205300","4242500","4279500","4311200","4342400","4372100","4397700","4430200","4467700","4504500","4542800","4582900","4622200","4662900","4704500","4743500","4790700","4803300","4802000","4835900","4873500","4911100","4836076","4657722","4491699","4349913","4243607","4157192","4077131","4014373","3978515","3951736","3927340","3902469","3880347","3860158","3848449","3814419","3786695","3756441","3728874","3717668","3719414","3725276","3727505","3728004","3726549","3720161","3722716","3708610","3712502","3760365", +"Ghana","GHA","Population, total","SP.POP.TOTL","6911510","7109029","7281192","7458243","7640196","7827726","8019658","8216086","8418152","8629855","8861895","9108878","9365952","9637197","9918979","10209848","10509006","10825496","11163230","11515675","11865246","12212960","12584976","12984131","13342487","13651443","13971682","14310790","14671677","15052447","15446982","15843471","16241548","16643633","17040854","17438874","17844010","18268040","18714708","19176791","19665502","20195577","20758326","21329514","21906444","22496951","23098586","23708320","24326087","24950762","25574719","26205941","26858762","27525597","28196358","28870939","29554303","30222262","30870641","31522290","32180401","32833031","33475870","34121985", +"Gibraltar","GIB","Population, total","SP.POP.TOTL","21822","21907","22249","22796","23347","23910","24477","25047","25610","26162","26685","27069","27323","27558","27779","27973","28162","28337","28485","28618","28734","28819","28863","28855","28788","28674","28506","28272","28000","27688","27317","26988","26945","27118","27282","27412","27491","27564","27636","27695","27741","27721","27892","28301","28716","29155","29587","29996","30398","30819","31262","31701","32160","32411","32452","32520","32565","32602","32648","32685","32709","32669","32649","32688", +"Guinea","GIN","Population, total","SP.POP.TOTL","3516814","3578631","3642324","3707945","3775510","3845074","3916780","3990760","4067333","4145194","4222374","4298087","4372212","4445207","4517073","4588006","4658743","4730375","4804926","4885199","4972609","5067427","5170731","5282274","5402084","5531661","5671380","5820774","5977175","6136166","6354145","6615734","6832195","7046097","7262112","7468347","7683115","7842806","7992545","8174897","8336967","8445717","8577790","8772254","8961039","9140114","9330625","9547082","9779785","10021323","10270728","10527712","10788692","11055430","11333365","11625998","11930985","12240789","12554864","12877539","13205153","13531906","13859341","14190612", +"Gambia, The","GMB","Population, total","SP.POP.TOTL","399649","410801","422310","434173","446375","458908","471753","485132","499151","513686","528731","544317","560553","577488","594904","612909","631894","651934","672974","695155","718586","742846","768272","795563","824798","855958","888980","923914","960837","999732","1040616","1083536","1127152","1168309","1205882","1242155","1279070","1317002","1356189","1396499","1437539","1479449","1522223","1566257","1612225","1660368","1711294","1764883","1820542","1878119","1937275","1998212","2061014","2124869","2189019","2253133","2317206","2381182","2444916","2508883","2573995","2639916","2705992","2773168", +"Guinea-Bissau","GNB","Population, total","SP.POP.TOTL","577933","583107","590399","595802","590481","577638","570375","573380","583475","587880","591663","594501","595950","603203","623576","659635","701016","746588","794328","821598","831462","844957","858630","872394","886210","900088","914122","928408","943080","958239","973551","993856","1022904","1056761","1089617","1117222","1140604","1162443","1184071","1206474","1230849","1257380","1285678","1315653","1347009","1379713","1414091","1450572","1488431","1527196","1567220","1609017","1652717","1697753","1743309","1788919","1834552","1879826","1924955","1970457","2015828","2060721","2105566","2150842", +"Equatorial Guinea","GNQ","Population, total","SP.POP.TOTL","267351","272264","277490","283018","288852","295010","301517","308374","315325","318846","316955","311952","305362","298050","290558","283262","276000","271377","270866","273925","282509","296950","315741","336744","357995","378379","397276","414769","431587","448420","465549","483142","501334","520236","539992","560740","582573","605570","629734","655029","684977","719270","754115","789681","826355","864726","905418","948814","994971","1043686","1094524","1144588","1193636","1243941","1295183","1346973","1398927","1450694","1502091","1553031","1596049","1634466","1674908","1714671", +"Greece","GRC","Population, total","SP.POP.TOTL","8331725","8398050","8448233","8479625","8510429","8550333","8613651","8684088","8740765","8772764","8792806","8831036","8888628","8929086","8962022","9046541","9188150","9308479","9429959","9548258","9642505","9729350","9789513","9846627","9895801","9934300","9967213","10000595","10036983","10089498","10196792","10319927","10399061","10460415","10512922","10562153","10608800","10661259","10720509","10761698","10805808","10862132","10902022","10928070","10955141","10987314","11020362","11048473","11077841","11107017","11121341","11104899","11045011","10965211","10892413","10820883","10775971","10754679","10732882","10721582","10698599","10569207","10426919","10361295", +"Grenada","GRD","Population, total","SP.POP.TOTL","93772","95096","96052","96882","97613","98226","98692","98977","99056","98975","98794","98535","98225","97886","97528","97165","96781","96329","95811","95242","94838","95222","96534","98177","99618","100576","100893","100599","99877","99224","99047","99758","101040","102173","103174","104060","104846","105549","106200","106823","107432","107936","108231","108740","109516","110254","110988","111725","112478","113249","114039","114918","115912","116945","117972","118980","119966","120921","121838","122724","123663","124610","125438","126183", +"Greenland","GRL","Population, total","SP.POP.TOTL","32500","33700","35000","36400","37600","39200","40500","41900","43400","44900","46400","47200","48300","49000","49500","49600","49700","49400","49200","49600","50200","51000","51500","52100","52700","53200","53500","54100","54800","55300","55600","55500","55300","55200","55500","55800","55900","56000","56100","56100","56200","56350","56609","56765","56911","56935","56774","56555","56328","56323","56905","56890","56810","56483","56295","56114","56186","56172","56023","56225","56367","56653","56661","56865", +"Guatemala","GTM","Population, total","SP.POP.TOTL","4128880","4251911","4378604","4508444","4640795","4774984","4910790","5047435","5184095","5320100","5455197","5589563","5723759","5858466","5994300","6131151","6269983","6412667","6561919","6720582","6890346","7071186","7262658","7462585","7669863","7884034","8104921","8332446","8566331","8805995","9050115","9296814","9544055","9790619","10037522","10286786","10536942","10788362","11046215","11311078","11589761","11871565","12147518","12415334","12682108","12948292","13213330","13477017","13739299","14000190","14259687","14521515","14781942","15043981","15306316","15567419","15827690","16087418","16346950","16604026","16858333","17109746","17357886","17602431", +"Guam","GUM","Population, total","SP.POP.TOTL","72374","73873","75412","76996","78621","80255","81879","83480","85046","86534","88300","90505","92815","95100","97329","99478","101590","103676","105710","107790","110286","113221","116189","119067","121885","124675","127462","130259","133079","135759","138263","140739","143173","145541","147843","150094","152261","154330","156357","158395","160188","161524","162563","163385","164004","164430","164675","164763","164725","164580","164905","165649","166392","167054","167543","167978","168346","168606","168678","168624","169231","170534","171774","172952", +"Guyana","GUY","Population, total","SP.POP.TOTL","571990","588597","604833","620703","635957","650207","663241","675064","685887","695919","705261","713904","721994","729865","737701","745590","753553","761378","768609","774482","778176","779686","779639","778372","776007","772671","768508","763706","758450","752897","747116","744096","744998","747189","749546","751689","753571","755211","756697","758014","759051","759809","760323","760562","760424","759709","758367","756521","754150","751258","747932","744230","743966","747420","751115","755031","759087","763252","785514","798753","797202","804567","808726","813834", +"High income","HIC","Population, total","SP.POP.TOTL","907912413","919107547","930536680","941879887","953215721","964261686","974157526","983690017","993133232","1002691282","1012186875","1023331593","1033198607","1042769605","1052189245","1061393041","1070186825","1078894429","1087645025","1096681462","1105492737","1114189491","1122386268","1130028100","1137503635","1145056586","1152740549","1160564047","1168510076","1176763924","1184203705","1192917410","1201571467","1209574376","1217016521","1224100529","1231090974","1237913846","1244547641","1250881910","1256926406","1262875491","1268844485","1274957396","1281374060","1288177967","1296180548","1305161431","1314663441","1323316736","1330723736","1335858758","1342743557","1349905020","1357161865","1364282269","1371516373","1377929189","1383955367","1389172209","1393950970","1392964458","1395940386","1403021503", +"Hong Kong SAR, China","HKG","Population, total","SP.POP.TOTL","3114671","3168100","3305200","3420900","3504600","3597900","3629900","3722800","3802700","3863900","3959000","4045300","4123600","4241600","4377800","4461600","4518000","4583700","4667500","4929700","5063100","5183400","5264500","5345100","5397900","5456200","5524600","5580500","5627600","5686200","5704500","5752000","5800500","5901000","6035400","6156100","6435500","6489300","6543700","6606500","6665000","6714300","6744100","6730800","6783500","6813200","6857100","6916300","6957800","6972800","7024200","7071600","7150100","7178900","7229500","7291300","7336600","7393200","7452600","7507900","7481000","7413100","7346100","7536100", +"Honduras","HND","Population, total","SP.POP.TOTL","2078617","2139928","2202854","2267708","2334492","2403465","2474523","2547497","2622982","2701381","2782753","2867501","2956021","3046715","3136539","3231631","3334814","3441122","3550368","3662736","3777990","3895736","4015647","4137784","4261919","4387693","4515568","4645733","4778114","4913676","5053234","5196887","5344774","5496841","5652934","5812832","5976550","6144112","6308537","6477365","6656725","6837861","7019908","7201881","7383407","7564613","7745200","7924462","8101777","8277302","8450933","8622504","8792367","8960657","9127846","9294505","9460798","9626842","9792850","9958829","10121763","10278345","10432860","10593798", +"Heavily indebted poor countries (HIPC)","HPC","Population, total","SP.POP.TOTL","163453961","167427839","171555341","175832578","180294830","184949176","189744990","194742549","199980949","205388448","210973069","216706865","222495959","228507880","234861273","241415576","248105304","254798463","262035002","269571043","276049311","282020641","289043160","296920640","305097813","313452117","321846502","330566338","339527267","348860257","358121820","367531126","378502714","390576688","402287229","413913354","425839678","437721228","449883034","462533086","475127894","488040621","502494432","517663749","532571131","547936900","563930944","579864063","596301357","613535903","630953183","648927117","667520863","686620331","706617213","727129254","748356635","770390212","792615894","815100831","838066650","861156745","884288332","907995430", +"Croatia","HRV","Population, total","SP.POP.TOTL","4140181","4167292","4196712","4225675","4252876","4280923","4310701","4338683","4365628","4391490","4412252","4431275","4450564","4470161","4490660","4512082","4535934","4559571","4581085","4594778","4599782","4611509","4634234","4658254","4680285","4701417","4721446","4739745","4755207","4767260","4777368","4689022","4575818","4600463","4652024","4620030","4557097","4534920","4532135","4512597","4468302","4299642","4302174","4303399","4304600","4310145","4311159","4310217","4309705","4305181","4295427","4280622","4267558","4255689","4238389","4203604","4174349","4124531","4087843","4065253","4047680","3878981","3855641","3853200", +"Haiti","HTI","Population, total","SP.POP.TOTL","3901139","3974934","4049504","4122260","4196349","4274348","4352949","4432716","4514006","4596642","4680812","4766423","4853117","4940710","5030652","5124560","5222342","5323827","5428667","5536423","5646676","5760197","5877684","5997739","6119932","6245539","6375097","6508349","6644959","6784161","6925331","7066055","7205780","7345940","7486091","7627316","7770593","7915172","8060896","8208941","8360225","8511728","8661546","8812245","8961489","9111900","9266288","9420826","9575247","9730638","9842880","9954312","10108539","10261206","10412740","10563757","10713849","10863543","11012421","11160438","11306801","11447569","11584996","11724763", +"Hungary","HUN","Population, total","SP.POP.TOTL","9983967","10029321","10061734","10087947","10119835","10147935","10178653","10216604","10255815","10298723","10337910","10367537","10398489","10432055","10478720","10540525","10598677","10648031","10684822","10704152","10711122","10711848","10705535","10689463","10668095","10648713","10630564","10612741","10596487","10481719","10373988","10373400","10369341","10357523","10343355","10328965","10311238","10290486","10266570","10237530","10210971","10187576","10158608","10129552","10107146","10087065","10071370","10055780","10038188","10022650","10000023","9971727","9920362","9893082","9866468","9843028","9814023","9787966","9775564","9771141","9750149","9709891","9643048","9589872", +"IBRD only","IBD","Population, total","SP.POP.TOTL","1904142765","1925829506","1960383924","2006828445","2053311947","2100281677","2149863866","2199183946","2249980136","2302867176","2356892546","2412012184","2466068634","2519871313","2572840435","2624186688","2674969821","2724949752","2774937121","2825639414","2877115899","2930329552","2986059777","3042087759","3097942924","3154738668","3213395968","3273803609","3334531476","3394353995","3453648037","3511638756","3566912141","3620616438","3673830207","3726486149","3778679694","3830663657","3881872613","3931470705","3979356320","4026403756","4072303744","4117630166","4162927496","4207824263","4251458316","4293654594","4336867656","4380820406","4424528755","4469961043","4517846874","4566948798","4615651856","4662836842","4708313438","4752675645","4794094269","4832585266","4866828116","4894666421","4912348798","4937047867", +"IDA & IBRD total","IBT","Population, total","SP.POP.TOTL","2298247983","2329785708","2374555774","2431591328","2489084003","2547491977","2608851292","2670356128","2733794158","2799632817","2866639928","2934067335","3000875648","3068779645","3136417425","3202651220","3268442731","3333971696","3400614104","3468899419","3538125231","3609391186","3684291030","3760049450","3835772578","3913078525","3992634841","4074363345","4156642221","4238479661","4320048688","4400467505","4479108518","4557323479","4635143097","4712519365","4789922904","4867134757","4943812366","5019457363","5094293697","5169110817","5243694285","5317975833","5392175010","5466351480","5540049563","5612877854","5686788085","5762203524","5838903143","5917936328","5998753810","6079936045","6160835364","6240908648","6320624467","6400602851","6478776303","6555193386","6628629499","6696373761","6754104791","6819750360", +"IDA total","IDA","Population, total","SP.POP.TOTL","394105218","403956202","414171850","424762883","435772056","447210300","458987426","471172182","483814022","496765641","509747382","522055151","534807014","548908332","563576990","578464532","593472910","609021944","625676983","643260005","661009332","679061634","698231253","717961691","737829654","758339857","779238873","800559736","822110745","844125666","866400651","888828749","912196377","936707041","961312890","986033216","1011243210","1036471100","1061939753","1087986658","1114937377","1142707061","1171390541","1200345667","1229247514","1258527217","1288591247","1319223260","1349920429","1381383118","1414374388","1447975285","1480906936","1512987247","1545183508","1578071806","1612311029","1647927206","1684682034","1722608120","1761801383","1801707340","1841755993","1882702493", +"IDA blend","IDB","Population, total","SP.POP.TOTL","120817228","123787114","126862058","130088814","133448149","136945840","140571218","144289794","148122678","152090704","156188262","160311126","164564539","169101287","173882120","178942945","184255432","189819289","195597910","201759170","208958276","216739122","224210712","231163936","237939240","245258177","252983956","260915798","269037308","277221224","285458430","293790697","301587423","309380669","317628977","326152635","335062226","344022548","353079757","362258853","372181624","382432118","392011236","401318288","410960215","420690092","430617236","440957937","451665010","462819210","474626536","486354807","497317025","507906365","518378284","528669692","538868249","549511044","560698093","572192040","584212703","596608333","609342910","622553200", +"Indonesia","IDN","Population, total","SP.POP.TOTL","88382881","90816938","93345489","95962527","98675061","101157868","103561105","106260749","109138723","112149246","115228394","118347135","121504145","124709058","127945196","131213215","134521025","137861540","141250964","144693087","148177096","151686337","155228658","158790611","162331962","165791694","169135273","172421390","175694647","178949174","182159874","185361228","188558416","191737287","194928533","198140162","201373791","204628007","207855486","210996910","214072421","217112437","220115092","223080121","225938595","228805144","231797427","234858289","237936543","240981299","244016173","247099697","250222695","253275918","256229761","259091970","261850182","264498852","267066843","269582878","271857970","273753191","275501339","277534122", +"IDA only","IDX","Population, total","SP.POP.TOTL","273287990","280169088","287309792","294674069","302323907","310264460","318416208","326882388","335691344","344674937","353559120","361744025","370242475","379807045","389694870","399521587","409217478","419202655","430079073","441500835","452051056","462322512","474020541","486797755","499890414","513081680","526254917","539643938","553073437","566904442","580942221","595038052","610608954","627326372","643683913","659880581","676180984","692448552","708859996","725727805","742755753","760274943","779379305","799027379","818287299","837837125","857974011","878265323","898255419","918563908","939747852","961620478","983589911","1005080882","1026805224","1049402114","1073442780","1098416162","1123983941","1150416080","1177588680","1205099007","1232413083","1260149293", +"Isle of Man","IMN","Population, total","SP.POP.TOTL","48793","48422","48669","49131","49597","50057","50718","51731","52910","54099","55298","56431","57419","58325","59179","59949","60701","61506","62333","63172","64022","64558","64654","64598","64500","64376","64663","65554","66636","67740","68865","69770","70307","70710","71094","71454","71981","72793","73727","74668","75562","76398","77183","77939","78677","79415","80228","81100","81997","82915","83828","84350","84338","84144","83896","83593","83450","83580","83775","83933","84046","84263","84519","84710", +"India","IND","Population, total","SP.POP.TOTL","445954579","456351876","467024193","477933619","489059309","500114346","510992617","521987069","533431909","545314670","557501301","569999178","582837973","596107483","609721951","623524219","637451448","651685628","666267760","681248383","696828385","712869298","729169466","745826546","762895156","780242084","797878993","815716125","833729681","852012673","870452165","888941756","907574049","926351297","945261958","964279129","983281218","1002335230","1021434576","1040500054","1059633675","1078970907","1098313039","1117415123","1136264583","1154638713","1172373788","1189691809","1206734806","1223640160","1240613620","1257621191","1274487215","1291132063","1307246509","1322866505","1338636340","1354195680","1369003306","1383112050","1396387127","1407563842","1417173173","1428627663", +"Not classified","INX","Population, total","SP.POP.TOTL","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","", +"Ireland","IRL","Population, total","SP.POP.TOTL","2828600","2824400","2836050","2852650","2866550","2877300","2888800","2902450","2915550","2932650","2957250","2992050","3036850","3085950","3137500","3189550","3238050","3282200","3329100","3373750","3412800","3453000","3485800","3510600","3532423","3538082","3539690","3540057","3524949","3511009","3513974","3534235","3558430","3576261","3590386","3608841","3637510","3674171","3712696","3754786","3805174","3866243","3931947","3996521","4070262","4159914","4273591","4398942","4489544","4535375","4560155","4580084","4599533","4623816","4657740","4701957","4755335","4807388","4867316","4934340","4985382","5033164","5127170","5262382", +"Iran, Islamic Rep.","IRN","Population, total","SP.POP.TOTL","21388806","21983622","22605050","23259094","23948624","24667026","25398700","26133341","26875302","27643685","28449705","29273682","30111574","30981898","31895534","32856976","33841060","34876497","35993661","37205013","38520664","40476251","42500030","44027986","45628402","47266160","48913237","50541490","52111868","53644736","55793629","57990883","59372016","59755430","59985749","60794809","61598378","62480533","63461421","64474745","65544383","66674851","67327117","67954699","69061674","70182594","71275760","72319418","73318394","74322685","75373855","76342971","77324451","78458928","79961672","81790841","83306231","84505076","85617562","86564202","87290193","87923432","88550570","89172767", +"Iraq","IRQ","Population, total","SP.POP.TOTL","7084678","7260714","7481832","7735824","7997655","8270544","8553883","8848502","9156132","9476737","9811347","10154928","10507315","10872139","11243146","11617622","11999342","12400190","12819707","13233830","13653369","14067260","14467682","14903737","15377032","15753856","16148221","16598019","16987346","17442590","17658381","17846378","18385673","19295818","20248073","20948858","21639332","22330770","23053488","23820734","24628858","25425663","26255343","27068823","27858948","28698684","28905607","28660887","29218381","30289040","31264875","32378061","33864447","35481800","36746488","37757813","38697943","39621162","40590700","41563520","42556984","43533592","44496122","45504560", +"Iceland","ISL","Population, total","SP.POP.TOTL","175574","179029","182378","185653","188983","192286","195570","198751","201488","203369","204438","206098","209137","212317","215209","217979","220154","221799","223537","225735","228138","230755","233860","236977","239511","241405","243180","245859","249740","252852","254826","257797","261057","263725","266021","267468","268916","271128","274047","277381","281205","284968","287523","289521","292074","296734","303782","311566","317414","318499","318041","319014","320716","323764","327386","330815","335439","343400","352721","360563","366463","372520","382003","393600", +"Israel","ISR","Population, total","SP.POP.TOTL","2114020","2185000","2293000","2379000","2475000","2563000","2629000","2745000","2803000","2877000","2974000","3069000","3148000","3278000","3377000","3455000","3533000","3613000","3690000","3786000","3878000","3956000","4031000","4105000","4159000","4233000","4299000","4369000","4442000","4518000","4660000","4949000","5123000","5261000","5399000","5545000","5692000","5836000","5971000","6125000","6289000","6439000","6570000","6689700","6809000","6930100","7053700","7180100","7308800","7485600","7623600","7765800","7910500","8059500","8215700","8380100","8546000","8713300","8882800","9054000","9215100","9371400","9557500","9756700", +"Italy","ITA","Population, total","SP.POP.TOTL","50199700","50536350","50879450","51252000","51675350","52112350","52519000","52900500","53235750","53537950","53821850","54073490","54381345","54751406","55110868","55441001","55718260","55955411","56155143","56317749","56433883","56501675","56543548","56564074","56576718","56593071","56596155","56601931","56629288","56671781","56719240","56758521","56797087","56831821","56843400","56844303","56860281","56890372","56906744","56916317","56942108","56974100","57059007","57313203","57685327","57969484","58143979","58438310","58826731","59095365","59277417","59379449","59539717","60233948","60789140","60730582","60627498","60536709","60421760","59729081","59438851","59133173","58940425","58761146", +"Jamaica","JAM","Population, total","SP.POP.TOTL","1642331","1663754","1683761","1703868","1725181","1746977","1768803","1790580","1812209","1834615","1859091","1886143","1915299","1945320","1974880","2003094","2029486","2054927","2080485","2106937","2135546","2166657","2199606","2232782","2264095","2292030","2315871","2336245","2354805","2373365","2392030","2411867","2434574","2459062","2484182","2509372","2532894","2554954","2576567","2596271","2612205","2625405","2638244","2651027","2664024","2676863","2689660","2701221","2711373","2722401","2733896","2746169","2759817","2773129","2784543","2794445","2802695","2808376","2811835","2813773","2820436","2827695","2827377","2825544", +"Jordan","JOR","Population, total","SP.POP.TOTL","847936","891848","934615","978607","1029447","1093474","1172770","1265680","1366644","1466428","1557374","1636320","1704787","1767414","1827584","1886636","1945141","2005418","2069104","2138078","2216903","2306655","2406349","2514785","2629939","2751492","2879799","3014694","3157177","3310954","3480587","3666379","3866887","4075759","4278166","4458195","4608676","4733665","4844403","4950775","5056174","5163310","5275532","5396117","5532423","5678534","6075548","6473457","6632873","6780493","6931258","7109980","7211863","7694814","8658026","9494246","9964656","10215381","10459865","10698683","10928721","11148278","11285869","11337052", +"Japan","JPN","Population, total","SP.POP.TOTL","93216000","94055000","94933000","95900000","96903000","97952000","98851000","99879000","101011000","102219000","103403000","105697000","107188000","108707000","110162000","111573000","112775000","113872000","114913000","115890000","116807000","117661000","118480000","119307000","120083000","120837000","121482000","122069000","122578000","123069000","123478000","123964000","124425000","124829000","125178000","125472000","125757000","126057000","126400000","126631000","126843000","127149000","127445000","127718000","127761000","127773000","127854000","128001000","128063000","128047000","128070000","127833000","127629000","127445000","127276000","127141000","127076000","126972000","126811000","126633000","126261000","125681593","125124989","124516650", +"Kazakhstan","KAZ","Population, total","SP.POP.TOTL","9319283","9639302","9959414","10277790","10590934","10897644","11197568","11491228","11777849","12042478","12265305","12444338","12611997","12789985","12972497","13158942","13346173","13543521","13750291","13957795","14172710","14397391","14634179","14885966","15147590","15413315","15721289","16072478","16430590","16249500","16348000","16451711","16439095","16380672","16145766","15816243","15578227","15334405","15071640","14928374","14883626","14858335","14858948","14909019","15012984","15147029","15308085","15484192","15776938","16092822","16321872","16557202","16792090","17035551","17288285","17542806","17794055","18037776","18276452","18513673","18755666","19191356","19634983","19900177", +"Kenya","KEN","Population, total","SP.POP.TOTL","7751435","8047470","8363578","8697200","9047387","9417207","9802605","10201068","10613877","11039551","11473087","11898457","12322903","12760405","13203949","13651908","14102268","14577346","15087423","15620613","16187124","16785962","17411491","18069461","18753176","19452161","20160879","20882094","21626122","22387803","23162269","23918235","24655723","25391830","26133744","26878347","27615736","28364264","29137373","29965129","30851606","31800343","32779823","33767122","34791836","35843010","36925253","38036793","39186895","40364444","41517895","42635144","43725806","44792368","45831863","46851488","47894670","48948137","49953304","50951450","51985780","53005614","54027487","55100586", +"Kyrgyz Republic","KGZ","Population, total","SP.POP.TOTL","2172300","2255900","2333400","2413700","2495300","2573300","2655300","2736500","2818300","2894800","2959900","3022300","3088200","3153800","3223900","3292400","3358700","3423900","3487100","3552000","3617400","3685800","3759300","3838300","3916400","3990300","4066500","4144600","4218400","4307500","4391200","4463600","4515400","4516700","4515100","4560400","4628400","4696400","4769000","4840400","4898400","4945100","4990700","5043300","5104700","5162600","5218400","5268400","5318700","5383300","5447900","5514600","5607200","5719600","5835500","5956900","6079500","6198200","6322800","6456200","6579900","6773400","6974900","7100800", +"Cambodia","KHM","Population, total","SP.POP.TOTL","5541676","5664654","5788854","5913680","6040847","6170727","6299230","6426445","6553109","6679708","6708525","6696324","6766289","6852360","6913408","6727922","6307122","6040197","5961193","6051808","6198959","6364472","6619699","6881962","7133899","7376090","7661317","7975597","8269780","8570928","8910808","9259362","9718215","10243550","10636353","10919528","11182612","11431569","11669077","11899006","12118841","12338192","12561779","12787710","13016371","13246583","13477779","13714791","13943888","14155740","14363532","14573885","14786640","14999683","15210817","15417523","15624584","15830689","16025238","16207746","16396860","16589023","16767842","16944826", +"Kiribati","KIR","Population, total","SP.POP.TOTL","47093","48275","49508","50780","52092","53444","54428","54990","55511","56324","57437","58535","59606","60598","60953","60675","60310","59894","59465","59775","60813","61875","62977","64121","65338","66708","68266","69946","71680","73436","75124","76612","77901","79093","80264","81481","82832","84308","85805","87289","88826","90531","92400","94302","96224","98164","100083","101998","103966","105996","107995","109871","111618","113311","114985","116707","118513","120362","122261","124241","126463","128874","131232","133515", +"St. Kitts and Nevis","KNA","Population, total","SP.POP.TOTL","56660","56247","55404","54391","53255","52016","50683","49269","47772","46135","44968","44583","44416","44242","44056","43888","43740","43603","43465","43278","43097","42953","42794","42600","42380","42144","41889","41617","41321","40992","40636","40542","40900","41447","42001","42550","43097","43656","44230","44825","45461","45986","46264","46431","46580","46725","46874","47015","47156","47286","47403","47581","47727","47767","47789","47790","47788","47785","47761","47712","47642","47606","47657","47755", +"Korea, Rep.","KOR","Population, total","SP.POP.TOTL","25012374","25765673","26513030","27261747","27984155","28704674","29435571","30130983","30838302","31544266","32240827","32882704","33505406","34103149","34692266","35280725","35848523","36411795","36969185","37534236","38123775","38723248","39326352","39910403","40405956","40805744","41213674","41621690","42031247","42449038","42869283","43295704","43747962","44194628","44641540","45092991","45524681","45953580","46286503","46616677","47008111","47370164","47644736","47892330","48082519","48184561","48438292","48683638","49054708","49307835","49554112","49936638","50199853","50428893","50746659","51014947","51217803","51361911","51585058","51764822","51836239","51769539","51672569","51712619", +"Kuwait","KWT","Population, total","SP.POP.TOTL","305415","339697","378190","420494","465748","513840","565463","621242","681117","743044","802786","858734","913785","970527","1030426","1095998","1168791","1247225","1329074","1412266","1493870","1573026","1652921","1736028","1813986","1888975","1968093","2048477","2129153","2210013","1674938","1339500","1620633","1653645","1641106","1655222","1703318","1761468","1819544","1877427","1934901","1991674","2047364","2101506","2153481","2235403","2363409","2506769","2650930","2795550","2943356","3143825","3394663","3646518","3761584","3908743","4048085","4124904","4317185","4441100","4360444","4250114","4268873","4310108", +"Latin America & Caribbean (excluding high income)","LAC","Population, total","SP.POP.TOTL","194711112","200250715","205949399","211793513","217767514","223847681","229988384","236176636","242412816","248701446","255049279","261469430","267987160","274614064","281334755","288125444","294984501","302010242","309220692","316512545","323797061","330950954","338095672","345367369","352669319","359944435","367182475","374403954","381662610","388933687","396328556","403768603","411115420","418431327","425740147","433010808","440183193","447290040","454334962","461289769","468125382","474817217","481353718","487688819","493917791","500076606","506094784","511989821","517759389","523473668","528978305","535014773","541048298","546954103","552781789","558562792","564377885","570381211","576620516","582701622","588011178","592503434","596596955","600825676", +"Lao PDR","LAO","Population, total","SP.POP.TOTL","2122532","2171141","2221615","2273219","2325513","2379456","2434861","2491927","2551070","2612111","2675283","2740732","2808290","2877561","2946882","3012720","3072017","3125742","3177945","3233700","3297519","3370993","3453691","3543861","3639956","3741604","3848390","3959697","4074961","4193532","4314443","4437225","4561106","4685296","4807950","4927432","5043914","5150538","5246922","5340056","5430853","5519707","5606101","5689065","5768167","5852970","5946593","6041348","6135861","6229930","6323418","6416327","6508803","6600742","6691454","6787419","6891363","6997917","7105006","7212053","7319399","7425057","7529475","7633779", +"Lebanon","LBN","Population, total","SP.POP.TOTL","1798092","1853295","1911959","1971511","2030440","2087445","2145646","2203202","2262291","2323823","2381791","2442137","2505965","2569841","2632880","2691586","3070419","3457617","3183405","2902164","2963702","3027222","3070133","3106990","3163558","3226750","3308010","3390870","3457148","3525502","3593700","3666734","3745407","3818796","3888144","3959640","4034243","4107551","4178784","4250020","4320642","4389200","4446666","4504807","4574797","4643044","4719864","4809608","4887613","4951135","4995800","5045056","5178337","5678851","6274342","6398940","6258619","6109252","5950839","5781907","5662923","5592631","5489739","5353930", +"Liberia","LBR","Population, total","SP.POP.TOTL","1137026","1165005","1194085","1224169","1255197","1287315","1320315","1354287","1389453","1425879","1463563","1501658","1540995","1582697","1626283","1671632","1718482","1768092","1820861","1875566","1932169","1989690","2047602","2109151","2174194","2239724","2305860","2372449","2439639","2507600","2209731","1939236","2052626","2132771","2125198","2142422","2203966","2383300","2639224","2789743","2895224","2981648","3060599","3085173","3122447","3266318","3455397","3632740","3783887","3905066","4019956","4181150","4331740","4427313","4519398","4612329","4706097","4796631","4889391","4985289","5087584","5193416","5302681","5418377", +"Libya","LBY","Population, total","SP.POP.TOTL","1426986","1478760","1535157","1594758","1652102","1700072","1739831","1778578","1819393","1862823","1909177","1958320","2012796","2084256","2179446","2291841","2413760","2541805","2676117","2816917","2962720","3112015","3265457","3423592","3564547","3684313","3800110","3911939","4021565","4130042","4236983","4341971","4444820","4544970","4641296","4733063","4820066","4902346","4980962","5057998","5154790","5275916","5405326","5542641","5687563","5837986","5973369","6097177","6228370","6360191","6491988","6188132","5869870","5985221","6097764","6192235","6282196","6378261","6477793","6569088","6653942","6735277","6812341","6888388", +"St. Lucia","LCA","Population, total","SP.POP.TOTL","91614","92761","93823","94887","95948","97024","98126","99257","100400","101605","103090","104781","106457","108114","109740","111497","113421","115385","117397","119463","121633","123909","126194","128440","130625","132751","134810","136780","138660","140457","142301","144268","146420","148595","150561","152348","153969","155454","156855","158256","159500","160594","161799","163047","164239","165386","166470","167518","168576","169688","170935","172145","173124","173978","174804","175623","176413","177163","177888","178583","179237","179651","179857","180251", +"Latin America & Caribbean","LCN","Population, total","SP.POP.TOTL","219142626","225304612","231638540","238127927","244742056","251458185","258225265","265030167","271885703","278797542","285779012","292852914","300036114","307345195","314759757","322249100","329807630","337531513","345450768","353452209","361451180","369321289","377189872","385189898","393227113","401251731","409259052","417266298","425320442","433393694","441597528","449847635","458008075","466139063","474258790","482331291","490304061","498199382","506010566","513714410","521281149","528688278","535935546","542976557","549897638","556739532","563424119","569972223","576386180","582738079","588873862","595510008","602139396","608642242","615046755","621390109","627667493","633795231","639626265","645293844","650533026","654978670","659306928","664155299", +"Least developed countries: UN classification","LDC","Population, total","SP.POP.TOTL","243747624","249669012","255852360","262222227","268840613","275712411","282750085","290061165","297680657","305463862","313150585","320137304","327434877","335785808","344428047","352974187","361378199","370063476","379602942","389654865","398831237","407724663","418029153","429385050","441083473","452925370","464719751","476678929","488634944","500927368","513410293","525967892","540073235","555402795","570349227","585085744","599913754","614755340","629930825","645681010","661430964","677492970","695099275","713279960","731086901","749189504","767538041","785635469","803947600","823002155","842807198","863421305","884653995","906405074","928661685","951184941","974516186","998532743","1022731692","1047426093","1072970944","1098791080","1124396999","1150346774", +"Low income","LIC","Population, total","SP.POP.TOTL","135762574","138934269","142232863","145659986","149260915","153026043","156903784","160978695","165256142","169632655","174131565","178729317","183334870","188076728","193061843","198178476","203399737","208592240","214272852","220230887","225097677","229413733","234808317","240996976","247448306","254069015","260658473","267469591","274348618","281571278","288759638","296103521","304997572","314673487","323847963","333181004","343031111","352755561","362458276","372579993","382593480","392924294","404771898","417212831","429354375","441886612","455313027","469010772","482640782","496609143","510897321","525506329","540002626","553835758","567702296","582173028","597683499","613946858","630865826","648755452","667053670","685250041","703727949","722984063", +"Liechtenstein","LIE","Population, total","SP.POP.TOTL","16472","16834","17221","17625","18058","18500","18957","19467","20011","20558","21089","21517","21873","22251","22638","23030","23416","23803","24205","24616","25003","25346","25689","26055","26420","26785","27159","27542","27944","28357","28765","29168","29581","30012","30447","30890","31337","31770","32190","32615","33026","33376","33693","34000","34300","34603","34889","35150","35401","35675","35926","36189","36505","36806","37096","37355","37609","37889","38181","38482","38756","39039","39327","39584", +"Sri Lanka","LKA","Population, total","SP.POP.TOTL","9783871","10022888","10267067","10517531","10774086","11035224","11299721","11571008","11846815","12119207","12388769","12654651","12914457","13169737","13418276","13662873","13910170","14159052","14414816","14680387","14943645","15198918","15438753","15658442","15872577","16092338","16317995","16547139","16773736","16990575","17204094","17416596","17624457","17825611","18011744","18177572","18322506","18449123","18560798","18670411","18776371","18920275","19110707","19303180","19490431","19673866","19870706","20078655","20285643","20482477","20668557","20859743","21017147","21131756","21239457","21336697","21425494","21506813","21670000","21803000","21919000","22156000","22181000","22037000", +"Lower middle income","LMC","Population, total","SP.POP.TOTL","829304553","849662240","870571996","892122183","914179691","936474497","958866819","981653792","1005182826","1029398298","1053935945","1078143512","1103176231","1129871655","1157235978","1184993312","1213431181","1242976775","1273039062","1304106034","1337497873","1372467577","1407836955","1443482185","1479546761","1516442333","1554102862","1592185751","1630669927","1669623556","1711089696","1750747711","1789953429","1829681824","1870097460","1910485587","1950796431","1991303064","2032158426","2073121889","2114855470","2157133128","2198877481","2240162906","2281546588","2322476208","2362904109","2403305272","2443449823","2483987657","2525974118","2568598935","2610684758","2653214685","2695950000","2737695800","2779326476","2821058566","2862391122","2903108878","2943860780","2983113040","3020375650","3059564861", +"Low & middle income","LMY","Population, total","SP.POP.TOTL","2115448034","2144909359","2187603468","2242530229","2297892571","2354293010","2414341591","2474366272","2536379782","2600890229","2666686848","2732913368","2798370133","2864850432","2930934760","2995490712","3059382497","3123017003","3187834084","3254332897","3321713494","3391165252","3464327390","3538429935","3612283886","3687723465","3765515230","3845508773","3926185019","4006647335","4089544168","4169497287","4247999679","4325985835","4403499627","4480641078","4558031834","4635223420","4711799589","4787566559","4863090613","4938731447","5014109152","5088853415","5163432770","5237940420","5311879939","5384897109","5458824459","5533964000","5610455957","5689033832","5769216950","5849715412","5929949445","6009439133","6088698400","6168617518","6247396829","6324580903","6398830423","6467799496","6527353351","6593137026", +"Lesotho","LSO","Population, total","SP.POP.TOTL","737838","760895","784681","809138","834215","860220","887841","918923","952992","987909","1023481","1059879","1097242","1135631","1175369","1216180","1256478","1294435","1331213","1368917","1407672","1447501","1488399","1530331","1573267","1616697","1659793","1698939","1733733","1767091","1798997","1829509","1858507","1885478","1910642","1934079","1955098","1972579","1985639","1994243","1998630","1999473","1997534","1993030","1985384","1977424","1976780","1983465","1995014","2009169","2022747","2037677","2054718","2073939","2095242","2118521","2143872","2170617","2198017","2225702","2254100","2281454","2305825","2330318", +"Late-demographic dividend","LTE","Population, total","SP.POP.TOTL","1095548725","1097728985","1112142897","1137971547","1163376707","1189485776","1218319662","1246291107","1275030950","1305235738","1336152939","1367659433","1397522486","1426459153","1453964650","1479273067","1503509107","1526366884","1548637582","1570920160","1593099029","1615957004","1640893480","1665773694","1689771008","1714481164","1740698024","1768376867","1796192544","1822788469","1847821461","1871805819","1894353796","1915623786","1936398016","1956331335","1975855844","1995080443","2013531302","2030612791","2046026051","2060709239","2074581734","2088087419","2101394737","2114863550","2128474052","2142072086","2155970810","2169765463","2182659481","2196448219","2212426916","2228642364","2244311001","2258792292","2272847109","2287248399","2299720675","2310338402","2318233156","2323185156","2325328254","2326833223", +"Lithuania","LTU","Population, total","SP.POP.TOTL","2778550","2823550","2863350","2898950","2935200","2971450","3008050","3044400","3078850","3107321","3139689","3179041","3213622","3244438","3273894","3301652","3328664","3355036","3379514","3397842","3413202","3432947","3457179","3485192","3514205","3544543","3578914","3616367","3655049","3684255","3697838","3704134","3700114","3682613","3657144","3629102","3601613","3575137","3549331","3524238","3499536","3470818","3443067","3415213","3377075","3322528","3269909","3231294","3198231","3162916","3097282","3028115","2987773","2957689","2932367","2904910","2868231","2828403","2801543","2794137","2794885","2800839","2831639","2871897", +"Luxembourg","LUX","Population, total","SP.POP.TOTL","313970","316845","320750","324100","327750","331500","333895","334995","335850","337500","339171","342421","346600","350450","355050","358950","360731","361358","362007","362856","364150","365225","365525","365622","365998","366706","368355","370750","373450","377100","381850","387000","392175","397475","402925","408625","414225","419450","424700","430475","436300","441525","446175","451630","458095","465158","472637","479993","488650","497783","506953","518347","530946","543360","556319","569604","582014","596336","607950","620001","630419","640064","653103","668606", +"Latvia","LVA","Population, total","SP.POP.TOTL","2120979","2152681","2181586","2210919","2240623","2265919","2283217","2301220","2323619","2343173","2359164","2376389","2395674","2415819","2437186","2456130","2470989","2485073","2497921","2505953","2511701","2519421","2531080","2546011","2562047","2578873","2599892","2626583","2653434","2666955","2663151","2650581","2614338","2563290","2520742","2485056","2457222","2432851","2410019","2390482","2367550","2337170","2310173","2287955","2263122","2238799","2218357","2200325","2177322","2141669","2097555","2059709","2034319","2012647","1993782","1977527","1959537","1942248","1927174","1913822","1900449","1884490","1879383","1881750", +"Macao SAR, China","MAC","Population, total","SP.POP.TOTL","177014","178672","186039","193618","201380","209278","217232","225151","232929","240416","247284","249832","248669","247838","247280","246919","246661","246405","246048","245605","245332","248695","256692","266253","276591","287700","299491","311808","324478","337336","350227","362390","372370","380712","388779","396641","404297","411700","418776","425518","431896","439122","449665","462533","475529","488619","501863","515330","529038","543021","557297","571003","582766","593374","604167","615239","626688","638609","650991","663653","676283","686607","695168","704149", +"St. Martin (French part)","MAF","Population, total","SP.POP.TOTL","4135","4258","4388","4524","4666","4832","5044","5294","5497","5646","5802","5957","6114","6278","6447","6656","6896","7131","7357","7572","7776","7963","8957","10992","13299","15714","18234","20853","23552","26303","28127","28736","29035","29247","29380","29435","29407","29299","29102","29099","29610","30387","31160","31929","32697","33452","34183","34887","35541","36132","36458","36350","36026","35639","35261","35020","34811","34496","33852","33121","32553","31948","31791","32077", +"Morocco","MAR","Population, total","SP.POP.TOTL","11769774","12081713","12404757","12726686","13044254","13381880","13738502","14109755","14490077","14876982","15274351","15677300","16081438","16489452","16902383","17325325","17756516","18206472","18679859","19167661","19678444","20208260","20746765","21287381","21817271","22335077","22824446","23279935","23720590","24148104","24570814","24988083","25400676","25806777","26201551","26599048","26999093","27397118","27791825","28176997","28554415","28930097","29301817","29661270","30033125","30431902","30833022","31232633","31634992","32042877","32464865","32903699","33352169","33803527","34248603","34680458","35107264","35528115","35927511","36304408","36688772","37076584","37457971","37840044", +"Monaco","MCO","Population, total","SP.POP.TOTL","21797","21907","22106","22442","22766","23022","23198","23281","23481","23875","24270","24610","24889","25102","25262","25524","25898","26242","26553","26834","27076","27284","27573","27985","28407","28807","29171","29500","29802","30078","30329","30564","30794","31024","31253","31482","31719","31968","32209","32394","32465","32444","32386","32316","32236","32141","32011","31823","31862","32401","33178","33945","34700","35425","36110","36760","37071","37044","37029","37034","36922","36686","36469","36297", +"Moldova","MDA","Population, total","SP.POP.TOTL","2074015","2127854","2177676","2222675","2264461","2301425","2336782","2369729","2400264","2429193","2456514","2483032","2509550","2536068","2563389","2590711","2618032","2643746","2668657","2692764","2716068","2740175","2765889","2792407","2819728","2847050","2875175","2904907","2931424","2952317","2965978","2973210","2975621","2974817","2967585","2953200","2947293","2936413","2935227","2930622","2924668","2918135","2911385","2903198","2896023","2888985","2880967","2874299","2868833","2865213","2862354","2860699","2860324","2859558","2857815","2835978","2803186","2755189","2707203","2664224","2635130","2595809","2538894","2486891", +"Madagascar","MDG","Population, total","SP.POP.TOTL","5073342","5206239","5343117","5484252","5630024","5780453","5936461","6099529","6270528","6450324","6639751","6840457","7051090","7268560","7491935","7720859","7955197","8195142","8440919","8692289","8948162","9207310","9470990","9740088","10015017","10297746","10588428","10890514","11206789","11536734","11882762","12245260","12623342","13020100","13436121","13869138","14317454","14778903","15250934","15730885","16216431","16709665","17211934","17724310","18250774","18792171","19350299","19924958","20513599","21117092","21731053","22348158","22966240","23588073","24215976","24850912","25501941","26169542","26846541","27533134","28225177","28915653","29611714","30325732", +"Maldives","MDV","Population, total","SP.POP.TOTL","91650","93952","96332","98775","101241","104566","108713","112547","116049","119569","123243","127066","130990","134940","138944","143126","147468","151792","156025","160326","164887","169663","174523","179339","184388","190383","197225","204256","211160","217937","224957","232150","239136","245845","252201","258208","263841","269040","273796","278111","282507","287324","292284","297226","302135","307018","314401","325126","336883","349037","361575","374440","387539","400728","416738","435582","454252","472442","489758","504508","514438","521457","523787","521021", +"Middle East & North Africa","MEA","Population, total","SP.POP.TOTL","104958259","107670788","110538003","113518054","116624655","119831991","123155200","126678043","130258116","133970600","137811201","141732410","145744541","149964066","154334030","159064212","164465177","169960807","174922290","180155296","186021685","192641039","199419033","205927091","212683895","219522781","226490767","233512587","240428079","247406122","256203998","263445808","270652251","276897626","282903612","289154944","295366235","301680248","308041622","314472124","321037453","327691655","333949565","340215354","347044925","354462370","362633997","371324802","380294099","389332369","397997557","406045323","414117603","422790409","431664579","440506473","448917409","456885486","465073490","473201775","479966649","486174763","493279469","500787313", +"Mexico","MEX","Population, total","SP.POP.TOTL","36268055","37439317","38683283","39982118","41333878","42737991","44180437","45656963","47170337","48714394","50289306","51897675","53543436","55228203","56945880","58691882","60452543","62262505","64123997","65972912","67705186","69233769","70656783","72080310","73489654","74872006","76224365","77553504","78892015","80233749","81720428","83351595","84993164","86648447","88314424","89969572","91586555","93183094","94767284","96334810","97873442","99394288","100917081","102429341","103945813","105442402","106886790","108302973","109684489","111049428","112532401","114150481","115755909","117290686","118755887","120149897","121519221","122839258","124013861","125085311","125998302","126705138","127504125","128455567", +"Marshall Islands","MHL","Population, total","SP.POP.TOTL","15374","15867","16387","16947","17537","18154","18794","19665","21001","22623","23969","24680","25084","25522","26174","27047","27964","28912","29892","30902","31988","33219","34569","35975","37437","38962","40527","42122","43687","44988","46047","47053","48015","48944","49840","50702","51538","52358","53164","53834","54224","54413","54496","54493","54435","54337","54208","54038","53816","53593","53416","52971","52203","51352","50419","49410","48329","47187","45989","44728","43413","42050","41569","41996", +"Middle income","MIC","Population, total","SP.POP.TOTL","1979685460","2005975090","2045370605","2096870243","2148631656","2201266967","2257437807","2313387577","2371123640","2431257574","2492555283","2554184051","2615035263","2676773704","2737872917","2797312236","2855982760","2914424763","2973561232","3034102010","3096615817","3161751519","3229519073","3297432959","3364835580","3433654450","3504856757","3578039182","3651836401","3725076057","3800784530","3873393766","3943002107","4011312348","4079651664","4147460074","4215000723","4282467859","4349341313","4414986566","4480497133","4545807153","4609337254","4671640584","4734078395","4796053808","4856566912","4915886337","4976183677","5037354857","5099558636","5163527503","5229214324","5295879654","5362247149","5427266105","5491014901","5554670660","5616531003","5675825451","5731776753","5782549455","5823625402","5870152963", +"North Macedonia","MKD","Population, total","SP.POP.TOTL","1462368","1481112","1497338","1511854","1529507","1547982","1567707","1588649","1610537","1633502","1656783","1679012","1701498","1725228","1749329","1774013","1799332","1825299","1851978","1879354","1907023","1935200","1958275","1974441","1988682","2001504","2012926","2023097","2031932","2039426","2044174","2036686","2018023","1996893","1982458","1983964","1994226","1996869","2007523","2017142","2026350","2034882","2020157","2022725","2016186","2005330","1994287","1982933","1971493","1958782","1946298","1937398","1929821","1922716","1917557","1912430","1906313","1898657","1889051","1876262","1856124","1837114","1831712","1811980", +"Mali","MLI","Population, total","SP.POP.TOTL","5346792","5420247","5494845","5570462","5647380","5726382","5806572","5888497","5973762","6061764","6153587","6247878","6347158","6455257","6569273","6687293","6807648","6935336","7072938","7218079","7372581","7532864","7696349","7863944","8030099","8187651","8334588","8474329","8617474","8774122","8945026","9123969","9310572","9506510","9711797","9921094","10131906","10359301","10620475","10916993","11239101","11583824","11952660","12342165","12751995","13180551","13623541","14080912","14551117","15032635","15529181","16039734","16514687","17004033","17551814","18112907","18700106","19311355","19934298","20567424","21224040","21904983","22593590","23293698", +"Malta","MLT","Population, total","SP.POP.TOTL","326550","325250","323900","322550","321250","318800","315200","311550","307900","304300","302650","302700","302450","302200","301996","304222","305774","306970","310182","313342","316645","318982","325898","330524","330593","336452","342121","344485","347325","350722","354170","363845","367618","371308","374797","377419","379905","382791","385287","387578","390087","393028","395969","398582","401268","403834","405308","406724","409379","412477","414508","416268","420028","425967","434558","445053","455356","467999","484630","504062","515332","518536","531113","553214", +"Myanmar","MMR","Population, total","SP.POP.TOTL","21720697","22203109","22699703","23210687","23737818","24286878","24854704","25440029","26044111","26659479","27284112","27914953","28551949","29165356","29751936","30344276","30941375","31554598","32185601","32821779","33465781","34110098","34742586","35424262","36159838","36881020","37572340","38233171","38868270","39489419","40099553","40680533","41237813","41788302","42337109","42880186","43423369","43972046","44516185","45041636","45538332","46014826","46480230","46924293","47338446","47724471","48088274","48445647","48729486","49015836","49390988","49794522","50218185","50648334","51072436","51483949","51892349","52288341","52666014","53040212","53423198","53798084","54179306","54577997", +"Middle East & North Africa (excluding high income)","MNA","Population, total","SP.POP.TOTL","97179656","99620285","102159899","104817905","107577280","110431969","113410132","116518346","119706733","122973346","126316235","129707914","133164152","136734072","140444545","144500701","149188764","153922894","158089953","162482818","167489905","173266699","179198278","184832095","190720860","196641041","202653537","208687611","214593293","220541237","228846359","235243716","241132429","246410264","251564545","256953719","262236018","267566671","272938873","278356861","283899110","289544085","294813993","300102895","305945780","311948573","317983066","324080392","330293304","336675037","343313330","349770162","356239722","363310225","370756356","378137339","385054538","391607422","398375344","405259403","411810124","418047201","424328381","430857111", +"Montenegro","MNE","Population, total","SP.POP.TOTL","480579","491140","502558","513409","521753","526327","526419","522796","517481","513340","512407","515449","521785","530220","538902","546487","552562","557576","562065","566888","572608","579445","587001","594506","600884","605398","607711","608144","607413","606571","606372","607105","608516","610170","611389","611712","611003","609520","607662","606001","604950","607389","609828","612267","613353","614261","615025","615875","616969","618294","619428","620079","620601","621207","621810","622159","622303","622373","622227","622028","621306","619211","617213","616177", +"Mongolia","MNG","Population, total","SP.POP.TOTL","977903","1011502","1045315","1075888","1104017","1134072","1165746","1198197","1230406","1261887","1293880","1327781","1363835","1402309","1443130","1485691","1529084","1572516","1615868","1657448","1697780","1739221","1781797","1825773","1871652","1919744","1969912","2021502","2073771","2120825","2161433","2200077","2236494","2270311","2301510","2330334","2357033","2381771","2405148","2428488","2450979","2472601","2494617","2516454","2537949","2559255","2581242","2605643","2633887","2666713","2702520","2743938","2792349","2845153","2902823","2964749","3029555","3096030","3163991","3232430","3294335","3347782","3398366","3447157", +"Northern Mariana Islands","MNP","Population, total","SP.POP.TOTL","8702","8965","9252","9561","9890","10229","10577","10720","10440","9952","10143","11279","12730","14094","14905","15269","15595","15901","16194","16494","17613","19902","22647","25594","28735","32041","35459","38923","42381","45859","48002","48302","48128","47948","47780","48717","53367","60817","68501","76237","80338","79479","77162","74623","71898","69025","66060","63050","60032","57056","54087","52520","52359","52141","51856","51514","51133","50729","50304","49858","49587","49481","49551","49796", +"Mozambique","MOZ","Population, total","SP.POP.TOTL","6788375","6917521","7060376","7209807","7363639","7524154","7689643","7859471","8035529","8217930","8411676","8622890","8860585","9123668","9404221","9703732","10019210","10363575","10741128","11127844","11413587","11640015","11901827","12163328","12426223","12680065","12909797","12964793","12956772","13087604","13303459","13561175","13816881","14206254","14912873","15594830","16079553","16521724","16923195","17337893","17768505","18220716","18694946","19186754","19694411","20211114","20735982","21280513","21845571","22436660","23073723","23760421","24487611","25251731","26038704","26843246","27696493","28569441","29423878","30285595","31178239","32077072","32969518","33897354", +"Mauritania","MRT","Population, total","SP.POP.TOTL","838478","861663","885938","911290","937830","965621","994697","1024992","1056393","1088832","1122198","1156361","1191376","1227358","1264352","1302436","1341604","1381329","1421786","1463514","1506694","1551687","1598332","1646343","1695675","1746265","1798009","1851092","1905847","1955040","2006027","2066302","2147527","2237064","2315191","2380341","2428816","2484278","2550501","2620611","2695003","2761823","2821703","2883326","2946575","3012360","3081229","3153508","3233336","3322616","3419461","3524249","3636113","3742959","3843174","3946220","4051890","4160015","4270712","4383849","4498604","4614974","4736139","4862989", +"Mauritius","MUS","Population, total","SP.POP.TOTL","676683","680757","700349","718861","736381","753000","768813","783917","798413","812405","826000","839230","852053","864819","878042","892000","906507","921379","933499","949888","966039","980462","992521","1001691","1012221","1020528","1028360","1036082","1043239","1051260","1058775","1070266","1084441","1097374","1112846","1122457","1133996","1148284","1160421","1175267","1186873","1196287","1204621","1213370","1221003","1228254","1233996","1239630","1244121","1247429","1250400","1252404","1255882","1258927","1261208","1262879","1263747","1264887","1265577","1265985","1266014","1266334","1262523","1261041", +"Malawi","MWI","Population, total","SP.POP.TOTL","3621081","3708193","3799155","3893628","3990361","4089097","4190764","4295762","4403430","4512861","4625141","4742480","4865978","4996239","5134199","5280965","5438226","5611712","5808810","6029140","6267369","6519891","6784347","7058317","7339002","7625078","7909819","8295993","8754781","9174895","9539665","9831584","10115420","10257233","10131799","10112816","10310528","10512678","10732456","10973956","11229387","11498818","11784498","12087965","12411342","12755648","13118307","13495463","13889423","14298932","14718422","15146094","15581251","16024775","16477966","16938942","17405624","17881167","18367883","18867337","19377061","19889742","20405317","20931751", +"Malaysia","MYS","Population, total","SP.POP.TOTL","7833782","8074805","8324218","8579350","8835925","9091016","9340240","9582086","9821308","10061684","10306508","10552557","10801619","11062664","11335187","11617947","11910081","12218924","12543892","12875011","13215707","13564594","13921029","14292862","14686454","15108135","15558740","16033103","16524616","17020143","17517054","18017464","18526708","19050077","19588703","20136888","20689051","21249178","21810542","22368655","22945150","23542517","24142445","24739411","25333247","25923536","26509413","27092604","27664296","28217204","28717731","29184133","29660212","30134807","30606459","31068833","31526418","31975806","32399271","32804020","33199993","33573874","33938221","34308525", +"North America","NAC","Population, total","SP.POP.TOTL","198624756","202007500","205198600","208253700","211262900","214031100","216659000","219176000","221503000","223759000","226431000","229677632","232168663","234454577","236715369","239169275","241538008","244018243","246601803","249310344","251795337","254340965","256836391","259214381","261488476","263823014","266290660","268793450","271349094","274154622","277373464","281077441","284943859","288662674","292185983","295640057","299064347","302623445","306070116","309502571","312909974","316052314","319047304","321813719","324807845","327823485","331015628","334184981","337406537","340467234","343398169","345987266","348655855","351205940","353885533","356508729","359247112","361731076","363974737","366012359","369619464","370352605","372274062","375076145", +"Namibia","NAM","Population, total","SP.POP.TOTL","590181","601424","613808","627358","642054","657887","674818","693063","712427","732881","754467","776995","800610","824918","850091","876572","901840","926109","942023","957334","975994","987394","1005520","1033085","1061995","1093311","1127989","1165430","1207949","1288070","1369011","1415617","1461687","1509834","1558449","1605370","1650066","1693242","1735953","1778277","1819141","1856402","1888525","1915425","1939406","1962865","1986558","2011492","2038552","2067919","2099271","2132340","2167470","2204510","2243001","2282704","2323352","2364534","2405680","2446644","2489098","2530151","2567012","2604172", +"New Caledonia","NCL","Population, total","SP.POP.TOTL","79000","81200","83400","85700","88100","90500","93500","96500","99500","104000","112000","120000","125500","128500","131000","132500","134000","136000","137500","138500","140050","142650","145700","148700","151650","154450","157350","160500","163650","166898","170899","175362","179799","184496","189482","193816","197564","201418","205279","209214","213230","217324","221490","225296","228750","232250","235750","239250","242750","245950","249750","254350","259000","263650","268050","269460","270220","270810","271170","271240","271080","270390","269215","267940", +"Niger","NER","Population, total","SP.POP.TOTL","3497431","3602530","3711068","3822697","3937008","4053524","4172501","4294283","4417954","4542993","4669708","4797068","4926318","5059382","5196579","5339497","5488658","5644703","5810351","5987151","6173177","6366262","6564445","6766606","6973849","7187618","7408364","7636591","7872252","8116075","8370648","8634640","8907644","9193078","9493324","9813918","10149937","10494201","10854920","11231469","11622665","12031430","12456517","12900790","13366885","13855221","14365168","14897873","15455175","16037915","16647543","17283112","17954407","18653199","19372014","20128124","20921743","21737922","22577058","23443393","24333639","25252722","26207977","27202843", +"Nigeria","NGA","Population, total","SP.POP.TOTL","44928342","45855507","46821845","47822569","48856332","49925799","51020296","52106681","53210119","54360750","55569264","56837614","58173834","59605446","61157931","62851312","64658315","66589655","68633344","70750307","72951439","75175387","77388067","79351586","81337553","83585251","85804185","88044187","90351467","92744064","95214257","97685360","100182045","102775465","105456121","108187610","110956183","113791181","116690527","119695565","122851984","126152678","129583026","133119801","136756848","140490722","144329764","148294028","152382506","156595758","160952853","165463745","170075932","174726123","179379016","183995785","188666931","193495907","198387623","203304492","208327405","213401323","218541212","223804632", +"Nicaragua","NIC","Population, total","SP.POP.TOTL","1789684","1844630","1901451","1960155","2020941","2084097","2150003","2219001","2291300","2366635","2444767","2525481","2603182","2682747","2769211","2857461","2947454","3038680","3128544","3214311","3303309","3397659","3491906","3584610","3674501","3763034","3852017","3941463","4033291","4129447","4227820","4327289","4427172","4526689","4625260","4721929","4812391","4895962","4974552","5049878","5123222","5192764","5259006","5323062","5386223","5454678","5529811","5607453","5687744","5770639","5855734","5942553","6030607","6119379","6208676","6298598","6389235","6480532","6572233","6663924","6755895","6850540","6948392","7046310", +"Netherlands","NLD","Population, total","SP.POP.TOTL","11486631","11638712","11805689","11965966","12127120","12294732","12456251","12598201","12729721","12877984","13038526","13194497","13328593","13439322","13545056","13666335","13774037","13856185","13941700","14038270","14149800","14247208","14312690","14367070","14424211","14491632","14572278","14665037","14760094","14848907","14951510","15069798","15184166","15290368","15382838","15459006","15530498","15610650","15707209","15812088","15925513","16046180","16148929","16225302","16281779","16319868","16346101","16381696","16445593","16530388","16615394","16693074","16754962","16804432","16865008","16939923","17030314","17131296","17231624","17344874","17441500","17533044","17700982","17879488", +"Norway","NOR","Population, total","SP.POP.TOTL","3581239","3609800","3638918","3666537","3694339","3723168","3753012","3784539","3816486","3847707","3875763","3903039","3933004","3960612","3985258","4007313","4026152","4043205","4058671","4072517","4085620","4099702","4114787","4128432","4140099","4152516","4167354","4186905","4209488","4226901","4241473","4261732","4286401","4311991","4336613","4359184","4381336","4405157","4431464","4461913","4490967","4513751","4538159","4564855","4591910","4623291","4660677","4709153","4768212","4828726","4889252","4953088","5018573","5079623","5137232","5188607","5234519","5276968","5311916","5347896","5379475","5408320","5457127","5519594", +"Nepal","NPL","Population, total","SP.POP.TOTL","10167941","10365144","10570716","10782717","11002819","11232951","11470199","11715579","11970411","12231874","12501285","12774870","13052220","13335963","13626301","13925541","14230738","14550430","14888770","15238564","15600442","15969792","16347124","16740664","17141610","17540571","17936926","18326204","18720745","19145077","19616530","20130779","20702133","21267359","21794751","22305571","22783969","23249417","23703328","24143157","24559500","24956071","25332178","25682908","26003965","26285110","26518971","26713655","26881544","27026941","27161567","27266399","27330694","27381555","27462106","27610325","27861186","28183426","28506712","28832496","29348627","30034989","30547580","30896590", +"Nauru","NRU","Population, total","SP.POP.TOTL","4582","4753","4950","5198","5484","5804","6021","6114","6288","6508","6663","6778","6883","6990","7096","7199","7306","7441","7541","7586","7635","7691","7672","7832","8125","8313","8527","8759","9022","9306","9598","9902","10129","10226","10274","10316","10345","10363","10377","10383","10377","10363","10351","10344","10335","10318","10294","10267","10243","10233","10241","10283","10444","10694","10940","11185","11437","11682","11924","12132","12315","12511","12668","12780", +"New Zealand","NZL","Population, total","SP.POP.TOTL","2371800","2419700","2482000","2531800","2585400","2628400","2675900","2724100","2748100","2772800","2810700","2853000","2903900","2961300","3023700","3083100","3110500","3120200","3121200","3109000","3112900","3124900","3156100","3199300","3227100","3247100","3246300","3274400","3283400","3299200","3329800","3495100","3531700","3572200","3620000","3673400","3732000","3781300","3815000","3835100","3857700","3880500","3948500","4027200","4087500","4133900","4184600","4223800","4259800","4302600","4350700","4384000","4408100","4442100","4516500","4609400","4714100","4813600","4900600","4979200","5090200","5111300","5117200","5223100", +"OECD members","OED","Population, total","SP.POP.TOTL","807630906","818832113","830289099","841722274","853200694","864404090","875187633","885770688","896137038","906483797","916668377","928686457","939481333","949978422","960279174","970331948","979795121","989288517","998939909","1008706437","1018252563","1027442087","1036208122","1044699000","1052818983","1060967506","1069253878","1077596775","1086103456","1095110298","1104791543","1115756696","1126417384","1136605361","1146214585","1155551702","1164716390","1173865390","1182690089","1191524686","1200179492","1209244330","1218395106","1227424218","1236495045","1245446032","1254649829","1263898714","1273582233","1282496705","1290949310","1297593832","1305512665","1313642010","1322072133","1330316951","1338792226","1346867182","1354843844","1362032167","1369502262","1371972508","1377465841","1385005653", +"Oman","OMN","Population, total","SP.POP.TOTL","536553","546443","557139","568603","580824","593808","607538","622042","637379","653593","670693","688803","708045","728597","754676","787194","824081","866124","912750","963351","1017462","1075624","1138301","1204626","1273306","1353289","1443446","1533351","1623433","1713838","1804524","1895187","1985227","2071868","2133675","2172672","2209958","2245588","2279727","2312600","2344253","2374653","2403659","2431600","2468855","2515192","2560649","2605700","2651028","2697537","2881914","3206870","3535579","3816680","4009267","4191776","4398070","4541854","4601157","4602768","4543399","4520471","4576298","4644384", +"Other small states","OSS","Population, total","SP.POP.TOTL","5445174","5532509","5640179","5749318","5857846","5962762","6060863","6152516","6244897","6341408","6444640","6558201","6677914","6799972","6918886","7042972","7179114","7323252","7467190","7614238","7762924","7905510","8047473","8189296","8333235","8490467","8657428","8831225","9011880","9197384","9392516","9587391","9669343","9727386","9819529","9906710","10031623","10168611","10308101","10465432","10620985","10764561","10909992","11056256","11222098","11405515","11594881","11789816","11986192","12174812","12328684","12440374","12569929","12725773","12900102","13082531","13258300","13439650","13608679","13751038","13853034","13943732","14095313","14240737", +"Pakistan","PAK","Population, total","SP.POP.TOTL","45954226","47060915","48161841","49325050","50552592","51841626","53199414","54629793","56124743","57676805","59290872","60878781","62509565","64285624","66149169","68126999","70230923","72451105","74789330","77407341","80624057","84270202","87828198","91080372","94003867","97121552","100618523","104251093","107967838","111670386","115414069","119203569","122375179","125546615","129245139","133117476","137234810","141330267","145476106","149694462","154369924","159217727","163262807","166876680","170648620","174372098","178069984","181924521","185931955","190123222","194454498","198602738","202205861","205337562","208251628","210969298","213524840","216379655","219731479","223293280","227196741","231402117","235824862","240485658", +"Panama","PAN","Population, total","SP.POP.TOTL","1126989","1160832","1196289","1233267","1271461","1310556","1350462","1391072","1432255","1473965","1516188","1559072","1602646","1646580","1690676","1734876","1779037","1823146","1867313","1911814","1956987","2003092","2050247","2098499","2147577","2197065","2246960","2297231","2347821","2398535","2449968","2502044","2554382","2607499","2661385","2716067","2771606","2827992","2885177","2943120","3001731","3061024","3120990","3181608","3243311","3305868","3368573","3431614","3495276","3559343","3623617","3688674","3754862","3821556","3888793","3957099","4026336","4096063","4165255","4232532","4294396","4351267","4408581","4468087", +"Peru","PER","Population, total","SP.POP.TOTL","10172207","10478096","10792094","11112665","11442301","11781581","12127990","12481626","12843249","13213739","13562371","13911968","14292437","14674785","15057175","15441497","15826813","16224613","16638480","17059185","17492406","17932344","18374372","18826906","19285646","19746610","20208437","20671360","21143799","21624311","22109099","22583006","23047248","23513882","23983258","24449055","24907304","25365386","25818226","26252239","26654439","27014909","27334503","27623341","27893911","28147267","28381078","28600387","28806185","29009326","29229572","29477721","29749589","30038809","30353951","30711863","31132779","31605486","32203944","32824861","33304756","33715471","34049588","34352719", +"Philippines","PHL","Population, total","SP.POP.TOTL","28486871","29342411","30185979","31043711","31916622","32805538","33704749","34616857","35544973","36477170","37435586","38421746","39412479","40406234","41388324","42394433","43474370","44646518","45890739","47154232","48419546","49679330","50938522","52219685","53514959","54812660","56109838","57415175","58755923","60127343","61558898","63039751","64543525","66083321","67650283","69250468","70944969","72718837","74491918","76249064","77958223","79626086","81285572","82942837","84607501","86261250","87901835","89561377","91252326","92946951","94636700","96337913","98032317","99700107","101325201","103031365","104875266","106738501","108568836","110380804","112190977","113880328","115559009","117337368", +"Palau","PLW","Population, total","SP.POP.TOTL","9446","9639","9851","10076","10318","10563","10813","10992","11079","11159","11366","11740","12172","12541","12662","12607","12539","12463","12387","12300","12252","12386","12666","12973","13299","13644","13985","14309","14632","14957","15293","15640","16004","16380","16770","17209","17732","18297","18852","19380","19726","19828","19851","19880","19907","19831","19619","19366","19102","18826","18540","18240","17946","17805","17796","17794","17816","17837","17864","17916","17972","18024","18055","18058", +"Papua New Guinea","PNG","Population, total","SP.POP.TOTL","1985666","2035672","2082562","2129222","2175409","2222178","2271490","2322647","2375356","2430922","2489059","2549315","2610700","2672144","2733313","2794462","2855837","2917572","2979606","3041902","3104788","3169073","3235264","3303677","3374465","3447579","3522916","3600343","3679651","3764112","3864972","3990995","4136644","4291588","4451694","4616439","4785895","4960439","5138829","5321388","5508297","5698489","5892596","6090980","6293166","6498818","6708217","6921066","7137988","7358890","7583269","7806637","8026545","8245627","8464153","8682174","8899169","9114796","9329227","9542486","9749640","9949437","10142619","10329931", +"Poland","POL","Population, total","SP.POP.TOTL","29637450","29964000","30308500","30712000","31139450","31444950","31681000","31987155","32294655","32548300","32664300","32783500","33055650","33357200","33678899","34015199","34356300","34689050","34965600","35247217","35574150","35898587","36230481","36571808","36904134","37201885","37456119","37668045","37824487","37961529","38110782","38246193","38363667","38461408","38542652","38594998","38624370","38649660","38663481","38660271","38258629","38248076","38230364","38204570","38182222","38165445","38141267","38120560","38125759","38151603","38042794","38063255","38063164","38040196","38011735","37986412","37970087","37974826","37974750","37965475","37899070","37747124","36821749","36685849", +"Pre-demographic dividend","PRE","Population, total","SP.POP.TOTL","188484894","192890980","197549304","202413011","207480357","212742196","218153165","223721654","229504001","235497996","241726476","248182949","254807021","261772896","269215218","277019356","285016249","293346289","302442287","311978056","320890339","328651565","336918508","346223339","356024795","366116135","376136620","386270164","396251031","406731853","417144782","427363888","439447569","453282283","468345219","483031809","495937962","508962926","523022619","537918075","553089230","568734640","586023563","604077372","621974508","640493810","659115651","677333522","697003893","718121906","739525992","761717101","784822780","808542070","832469778","856420253","880891473","905987912","931467165","957503246","984213438","1011043183","1038012552","1065710613", +"Puerto Rico","PRI","Population, total","SP.POP.TOTL","2358000","2399722","2450322","2504530","2554066","2594000","2624995","2645674","2662064","2684150","2718000","2762190","2817256","2878786","2939299","2994000","3043854","3088690","3129421","3168088","3206000","3242552","3277453","3311138","3344190","3377000","3409554","3441850","3473898","3505650","3537000","3562110","3585176","3615497","3649237","3683103","3724655","3759430","3781101","3800081","3810605","3818774","3823701","3826095","3826878","3821362","3805214","3782995","3760866","3740410","3721525","3678732","3634488","3593077","3534874","3473232","3406672","3325286","3193354","3193694","3281557","3262693","3220113","3205691", +"Korea, Dem. People's Rep.","PRK","Population, total","SP.POP.TOTL","11655666","11916515","12180505","12475236","12787523","13105946","13444048","13821409","14216305","14605481","14996879","15381626","15768363","16128122","16437002","16723252","16987170","17231389","17472094","17719172","17973650","18235202","18502087","18771363","19045154","19325487","19613038","19903893","20197464","20494965","20799523","21115534","21439991","21773017","22105225","22385536","22614347","22827373","23023636","23204498","23367059","23512522","23638411","23781707","23948930","24100982","24235761","24356506","24469047","24581509","24686435","24783789","24887770","25001819","25126131","25258015","25389611","25516321","25638149","25755441","25867467","25971909","26069416","26160821", +"Portugal","PRT","Population, total","SP.POP.TOTL","8857716","8929316","8993985","9030355","9035365","8998595","8930990","8874520","8836650","8757705","8680431","8643756","8630430","8633100","8754365","9093470","9355810","9455675","9558250","9661265","9766312","9851362","9911771","9957865","9996232","10023613","10032734","10030031","10019610","10005000","9983218","9960235","9952494","9964675","9991525","10026176","10063945","10108977","10160196","10217828","10289898","10362722","10419631","10458821","10483861","10503330","10522288","10542964","10558177","10568247","10573100","10557560","10514844","10457295","10401062","10358076","10325452","10300300","10283822","10286263","10297081","10361831","10409704","10525347", +"Paraguay","PRY","Population, total","SP.POP.TOTL","1894829","1941208","1989376","2039390","2090840","2143153","2195955","2248882","2301887","2355122","2408787","2463777","2521508","2583160","2648082","2714664","2782624","2852430","2924370","2999415","3078912","3163299","3251678","3343276","3437892","3535498","3636027","3739050","3844437","3951288","4059195","4167996","4277051","4386202","4495301","4603917","4711655","4818289","4923449","5026031","5123819","5211541","5286512","5353254","5416324","5476878","5534675","5590145","5645148","5702574","5768613","5843939","5923322","6005652","6090721","6177950","6266615","6355404","6443328","6530026","6618695","6703799","6780744","6861524", +"West Bank and Gaza","PSE","Population, total","SP.POP.TOTL","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","1978248","2068845","2163591","2262676","2366298","2474666","2587997","2706518","2776568","2848431","2922153","2997784","3075373","3154969","3236626","3320396","3406334","3494496","3591977","3689099","3786161","3882986","3979998","4076708","4173398","4270092","4367088","4454805","4569087","4685306","4803269","4922749","5043612","5165775", +"Pacific island small states","PSS","Population, total","SP.POP.TOTL","905537","932520","960258","988767","1017629","1046929","1075580","1102445","1128479","1154784","1180979","1206288","1230989","1255419","1280025","1305437","1332485","1361037","1390769","1422213","1454737","1487956","1521474","1555359","1590087","1625232","1659314","1691381","1721273","1749210","1776243","1800161","1822819","1846876","1870257","1892547","1917072","1945783","1976146","2006341","2035672","2064193","2091909","2119122","2146140","2172802","2199540","2226078","2251506","2276149","2301401","2327284","2353058","2379069","2405308","2431426","2457814","2484263","2510226","2536070","2566819","2602173","2639019","2677728", +"Post-demographic dividend","PST","Population, total","SP.POP.TOTL","755575073","764678914","773971699","783063134","792060920","800834639","809130400","817080267","824785271","832436871","839994662","849355911","857312419","864799662","872040235","878923921","885095643","891148506","897250576","903640940","909780809","915881806","921481239","926626734","931426792","936237496","941302405","946544990","952006529","957909363","964048985","971176019","977958696","984265557","989907298","995212216","1000693857","1005936747","1010875500","1015710581","1020793420","1025680356","1030817778","1035933493","1041239406","1046467578","1052106051","1058252734","1064632148","1070086582","1075047440","1077986944","1082488131","1087228563","1092176251","1097076319","1102054942","1106262382","1110198958","1113410921","1117530670","1116651310","1114354147","1119478514", +"French Polynesia","PYF","Population, total","SP.POP.TOTL","84851","86921","89208","91963","95192","98674","102281","105995","109832","113803","117891","122108","126457","130883","135349","139833","144356","149007","153745","158563","163591","168892","174343","179042","183146","187578","192196","196856","201740","206571","211089","215444","219621","223714","227682","231446","235189","239036","242882","246821","250927","255049","259137","263173","267132","271060","274901","278178","280558","282283","283788","285265","286584","288032","289873","291787","293541","295450","297606","299717","301920","304032","306279","308872", +"Qatar","QAT","Population, total","SP.POP.TOTL","36385","40111","45123","50950","57531","64843","73102","82517","93022","104517","118007","133096","148338","163734","179299","195043","210990","227177","243624","260368","277450","294887","312608","330454","348241","365868","382328","397391","412142","426896","441675","456486","471293","486041","500683","515133","529265","550591","580997","613302","645937","678831","713186","748525","777943","848710","1015060","1231893","1444277","1610274","1713504","1804171","1905660","2035501","2214465","2414573","2595166","2711755","2766732","2807235","2760385","2688235","2695122","2716391", +"Romania","ROU","Population, total","SP.POP.TOTL","18406905","18555250","18676550","18797850","18919126","19031576","19215450","19534242","19799831","20009141","20250398","20461567","20657957","20835681","21029429","21293583","21551634","21756096","21951464","22090488","22207282","22353070","22475741","22560478","22640547","22732999","22836841","22949430","23057662","23161458","23201835","23001155","22794284","22763280","22730211","22684270","22619004","22553978","22507344","22472040","22442971","22131970","21730496","21574326","21451748","21319685","21193760","20882982","20537875","20367487","20246871","20147528","20058035","19983693","19908979","19815616","19702267","19588715","19473970","19371648","19265250","19122059","19047009","19056116", +"Russian Federation","RUS","Population, total","SP.POP.TOTL","119897000","121236000","122591000","123960000","125345000","126745000","127468000","128196000","128928000","129664000","130404000","131155000","131909000","132669000","133432000","134200000","135147000","136100000","137060000","138027000","139010000","139941000","140823000","141668000","142745000","143858000","144894000","145908000","146857000","147721000","147969406","148394216","148538197","148458777","148407912","148375787","148160129","147915361","147670784","147214776","146596869","145976482","145306497","144648618","144067316","143518814","143049637","142805114","142742366","142785348","142849468","143018195","143378447","143805638","144237223","144640716","145015460","145293260","145398106","145453291","145245148","144746762","144236933","143826130", +"Rwanda","RWA","Population, total","SP.POP.TOTL","2966162","3046654","3122124","3191311","3263640","3348631","3444021","3549461","3662010","3777879","3896367","4015403","4135579","4259484","4386369","4515756","4648207","4783252","4921953","5074374","5247532","5441966","5652900","5859396","6056729","6266752","6497804","6735829","6953975","7141974","7319962","7485681","7657208","7904740","6732665","5686897","6715510","7666732","7914645","8009587","8109989","8223941","8372306","8567992","8791853","9026299","9270066","9523168","9781996","10043737","10309031","10576932","10840334","11101350","11368451","11642959","11930899","12230339","12531808","12835028","13146362","13461888","13776698","14094683", +"South Asia","SAS","Population, total","SP.POP.TOTL","571192428","584794755","598784274","613149540","627867470","642649029","657382046","672401853","688013461","704112818","720399195","736135444","752397791","770083670","788213169","806592758","825140213","844199483","863852185","884031584","904993069","926216545","948043890","970938323","994345688","1018142776","1042169001","1066371857","1091004504","1116147699","1141312704","1166480561","1192390433","1219180082","1246157499","1272877742","1299407301","1326007987","1352849350","1379874856","1406945493","1434314654","1462070145","1489358080","1515703001","1541263909","1565892885","1589454615","1612709085","1636411632","1660546144","1684898004","1708706729","1731683901","1754030304","1775545180","1797072648","1818931519","1840534093","1861598514","1882531620","1901911604","1919348000","1938549529", +"Saudi Arabia","SAU","Population, total","SP.POP.TOTL","4165563","4306048","4458516","4621655","4795130","4978922","5173237","5381026","5604582","5844843","6106191","6396658","6724260","7088758","7483506","7897544","8319556","8755219","9210564","9682002","10171710","10678211","11201154","11746020","12310361","12890245","13483349","14089798","14713715","15353227","16004763","16654276","17281350","17846461","18367528","18888857","19410280","19938377","20472580","21009660","21547390","22085929","22623415","23150847","23661808","24397644","25382870","26400068","27437353","28483797","29411929","30150945","30821543","31482498","32125564","32749848","33416270","34193122","35018133","35827362","35997107","35950396","36408820","36947025", +"Sudan","SDN","Population, total","SP.POP.TOTL","8326462","8577490","8841338","9115091","9406702","9712785","10014505","10320500","10638899","10966145","11305206","11668921","12057260","12469591","12950962","13497543","14066007","14667218","15305806","15973034","16673586","17404336","18128631","18733995","19165837","19517196","19887452","20230532","20453819","20718709","21090886","21453711","21780059","22163251","22703631","23290602","23862258","24454372","25029144","25634162","26298773","26947253","27570318","28188977","28831550","29540577","30332968","31191163","32065241","32948155","33739933","34419624","35159792","35990704","37003245","38171178","39377169","40679828","41999059","43232093","44440486","45657202","46874204","48109006", +"Senegal","SEN","Population, total","SP.POP.TOTL","3273177","3367082","3463524","3562469","3664599","3770874","3881994","3997869","4117659","4240859","4367744","4498616","4633452","4772039","4911421","5047922","5181195","5308297","5433225","5564474","5703869","5852029","6008392","6171874","6341801","6520705","6710885","6909837","7113636","7321832","7536001","7754289","7974514","8196551","8416997","8632681","8843423","9051539","9261526","9478564","9704287","9938027","10180950","10434504","10698691","10974057","11263387","11563869","11872929","12195029","12530121","12875880","13231833","13595566","13970308","14356181","14751356","15157793","15574909","16000781","16436120","16876720","17316449","17763163", +"Singapore","SGP","Population, total","SP.POP.TOTL","1646400","1702400","1750200","1795000","1841600","1886900","1934400","1977600","2012000","2042500","2074507","2112900","2152400","2193000","2229800","2262600","2293300","2325300","2353600","2383500","2413945","2532835","2646466","2681061","2732221","2735957","2733373","2774789","2846108","2930901","3047132","3135083","3230698","3313471","3419048","3524506","3670704","3796038","3927213","3958723","4027887","4138012","4175950","4114826","4166664","4265762","4401365","4588599","4839396","4987573","5076732","5183688","5312437","5399162","5469724","5535002","5607283","5612253","5638676","5703569","5685807","5453566","5637022","5917648", +"Solomon Islands","SLB","Population, total","SP.POP.TOTL","133440","136780","140254","143863","147609","151495","155514","159667","163973","168399","172833","177264","181876","186816","192155","197853","204082","210932","218193","225786","233668","241827","250250","258945","267913","277158","286527","295836","305132","314560","324171","333952","343916","354086","364505","375189","386069","397050","408145","419229","429978","440395","450760","461216","471785","482486","493430","504619","516001","527833","540394","553721","567763","582365","597375","612660","628102","643634","659249","674993","691191","707851","724273","740424", +"Sierra Leone","SLE","Population, total","SP.POP.TOTL","2301310","2341065","2382914","2426750","2472686","2520576","2569736","2620396","2672370","2724901","2778557","2832392","2886642","2942333","2998843","3055916","3112863","3172195","3235170","3300032","3367477","3437108","3509197","3585773","3666262","3749419","3842917","3947865","4056215","4159163","4325388","4378169","4301566","4295689","4314953","4324149","4347370","4405028","4449975","4475145","4584067","4857096","5140113","5350907","5533329","5683334","5809774","5939163","6090860","6259842","6436698","6612385","6788587","6964859","7140688","7314773","7493913","7677565","7861281","8046828","8233970","8420641","8605718","8791092", +"El Salvador","SLV","Population, total","SP.POP.TOTL","2779327","2858896","2937821","3014885","3095170","3179506","3266436","3354611","3443251","3530958","3619090","3708010","3798109","3890639","3984049","4076751","4166890","4256699","4346522","4433041","4508992","4549173","4599904","4689680","4782219","4876757","4970788","5067200","5170440","5270825","5367179","5461070","5552206","5630987","5693038","5748195","5797140","5842638","5885083","5923852","5958482","5988095","6011275","6026849","6035655","6037817","6034436","6044131","6068099","6091188","6114034","6137349","6161289","6185642","6209526","6231066","6250510","6266654","6276342","6280217","6292731","6314167","6336392","6364943", +"San Marino","SMR","Population, total","SP.POP.TOTL","15556","15895","16242","16583","16926","17273","17588","17907","18291","18403","18169","18212","18575","19010","19439","19803","20160","20482","20795","21087","21346","21596","21804","21973","22096","22241","22390","22437","22542","22803","23132","23459","23808","24181","24535","24886","25235","25596","25997","26404","26823","27335","27969","28601","29093","29508","29959","30372","30700","31059","31608","32495","33132","33285","33389","33570","33834","34056","34156","34178","34007","33745","33660","33642", +"Somalia","SOM","Population, total","SP.POP.TOTL","2870732","2945662","3022827","3102170","3183590","3267593","3353665","3441799","3532420","3625274","3720977","3818389","3918220","4022336","4125823","4228289","4333779","4449505","4777703","5408813","5892224","5934938","5951805","6142513","6369020","6630637","6908579","7158004","7160461","7035378","6999096","6732702","6428141","6620729","6959828","7210930","7472450","7734313","8056862","8384479","8721465","9070747","9411103","9758281","10117354","10467292","10784973","11118092","11444870","11730037","12026649","12216837","12440326","12852485","13309235","13763906","14292847","14864221","15411094","15981300","16537016","17065581","17597511","18143378", +"Serbia","SRB","Population, total","SP.POP.TOTL","6608000","6655000","6696000","6732000","6765000","6794000","6841000","6880000","6915000","6945000","6972000","7013000","7053000","7091000","7128000","7163000","7214000","7258000","7297000","7332000","7362000","7405000","7440000","7468000","7489000","7504000","7536000","7558000","7572000","7581000","7586000","7595636","7646424","7699307","7734639","7625357","7617794","7596501","7567745","7540401","7516346","7503433","7496522","7480591","7463157","7440769","7411569","7381579","7350222","7320807","7291436","7234099","7199077","7164132","7130576","7095383","7058322","7020858","6982604","6945235","6899126","6834326","6664449","6618026", +"Sub-Saharan Africa (excluding high income)","SSA","Population, total","SP.POP.TOTL","227907169","233440376","239236580","245252887","251519652","258031054","264705303","271583274","278745760","286159536","293846963","301784530","309907107","318407872","327408911","336773625","346400565","356181976","366625933","377712957","388730206","400196739","412345689","424282035","436198927","448690191","461690512","475181847","488696153","502447913","516560181","530646532","544828860","559341649","574019932","589252781","605109645","620988006","637119672","653802851","671131355","689080780","707609717","726702652","746464327","766895808","788025400","809934231","832555779","855798400","879707649","904194713","929240350","955006753","981415249","1008605380","1036061312","1063789431","1092307211","1121451424","1151203619","1181063755","1211070124","1241778044", +"South Sudan","SSD","Population, total","SP.POP.TOTL","2907724","2948953","2992270","3036238","3088701","3143622","3185305","3221957","3261725","3301892","3342410","3396808","3464715","3542465","3629608","3718279","3808615","3901044","3995911","4092792","4192012","4293866","4398297","4502541","4603039","4706975","4819667","4893809","4814879","4706626","4750817","4867185","4956969","5018172","5142863","5302042","5434894","5589410","5699436","5850145","6114440","6394431","6686100","6992367","7317118","7662654","8029517","8417823","8823888","9229227","9714419","10243050","10701604","11106031","11213284","11194299","11066105","10658226","10395329","10447666","10606227","10748272","10913164","11088796", +"Sub-Saharan Africa","SSF","Population, total","SP.POP.TOTL","227948869","233483265","239280622","245298063","251565974","258078554","264754002","271633185","278796894","286211901","293900563","301839225","309963136","318464764","327466848","336832917","346461069","356243762","366688083","377775643","388793467","400260774","412410102","424346370","436263644","448755435","461756164","475250346","488764908","502517080","516629688","530716971","544899623","559413902","574094137","589328085","605186062","621065325","637198518","653883261","671212486","689161982","707693440","726785433","746546802","766978666","788110000","810019264","832642735","855885698","879797419","904282154","929328653","955096702","981506608","1008698799","1036155989","1063885274","1092403973","1121549049","1151302081","1181163013","1211190002","1241897817", +"Small states","SST","Population, total","SP.POP.TOTL","8070458","8225676","8401577","8580103","8757487","8930497","9095506","9251753","9407426","9566803","9730952","9902092","10070625","10233631","10392684","10557672","10736698","10924932","11113127","11304120","11498324","11688698","11878455","12068158","12260362","12465844","12678894","12894358","13114086","13337402","13568047","13799674","13924518","14028001","14165955","14301580","14478832","14672238","14869600","15083838","15294390","15491585","15689535","15887550","16103414","16334853","16572025","16814517","17057446","17291609","17490321","17645826","17821789","18026868","18251250","18483937","18709361","18940564","19177011","19377482","19526038","19674424","19881389","20086203", +"Sao Tome and Principe","STP","Population, total","SP.POP.TOTL","68038","68705","69520","70272","70992","71730","72567","73564","74739","76059","77583","79226","80835","82472","84189","86037","88078","90299","92659","95017","97210","99170","100931","102650","104497","106607","108966","111610","114513","117445","120343","123084","125648","128182","130666","133077","135412","137656","139790","141808","143714","146258","149841","153762","157697","161680","165725","169845","174004","178128","182138","186044","189924","193757","197497","201124","204632","208036","211344","214599","218641","223107","227380","231856", +"Suriname","SUR","Population, total","SP.POP.TOTL","268396","277969","288291","299332","310288","321069","332142","343620","355468","367618","379918","392026","397529","396331","394519","392137","389231","385810","381885","377362","375112","375859","377288","379409","382617","387171","392372","396867","402139","408360","412756","415981","419521","422375","426548","434490","443834","452887","461749","470458","478998","487394","495666","503780","510572","516220","522023","527946","533938","539987","546080","552146","558111","563947","569682","575475","581453","587559","593715","600301","607065","612985","618040","623236", +"Slovak Republic","SVK","Population, total","SP.POP.TOTL","4068095","4191667","4238188","4282017","4327341","4370983","4411666","4449367","4483915","4518607","4538223","4557449","4596622","4641445","4689623","4739105","4789507","4840501","4890125","4938973","4979815","5016105","5055099","5091971","5127097","5161768","5193838","5222840","5250596","5275942","5299187","5303294","5305016","5325305","5346331","5361999","5373361","5383291","5390516","5396020","5388720","5378867","5376912","5373374","5372280","5372807","5373054","5374622","5379233","5386406","5391428","5398384","5407579","5413393","5418649","5423801","5430798","5439232","5446771","5454147","5458827","5447247","5431752","5426740", +"Slovenia","SVN","Population, total","SP.POP.TOTL","1584720","1594131","1603649","1616971","1632114","1649160","1669905","1689528","1704546","1713874","1724891","1738335","1752233","1766697","1776132","1793581","1820249","1842377","1862548","1882599","1901315","1906531","1910334","1922321","1932154","1941641","1965964","1989776","1995196","1996351","1998161","1999429","1996498","1991746","1989443","1989872","1988628","1985956","1981629","1983045","1988925","1992060","1994530","1995733","1997012","2000474","2006868","2018122","2021316","2039669","2048583","2052843","2057159","2059953","2061980","2063531","2065042","2066388","2073894","2088385","2102419","2108079","2111986","2120937", +"Sweden","SWE","Population, total","SP.POP.TOTL","7484656","7519998","7561588","7604328","7661354","7733853","7807797","7867931","7912273","7968072","8042801","8098334","8122300","8136312","8159955","8192437","8222286","8251540","8275599","8293678","8310531","8320503","8325263","8329033","8336605","8350386","8369829","8397804","8436489","8492964","8558835","8617375","8668067","8718561","8780745","8826939","8840998","8846062","8850974","8857874","8872109","8895960","8924958","8958229","8993531","9029572","9080505","9148092","9219637","9298515","9378126","9449213","9519374","9600379","9696110","9799186","9923085","10057698","10175214","10278887","10353442","10415811","10486941","10536632", +"Eswatini","SWZ","Population, total","SP.POP.TOTL","345065","352971","361070","369527","378531","388317","398861","409638","420373","431366","442865","454913","467512","480668","494624","509535","525457","542328","560236","579091","598564","616210","634439","655505","677303","702400","730150","758669","794434","825952","854011","889712","925165","953451","953737","953573","973587","990734","1005158","1018370","1030496","1041396","1050809","1058797","1065764","1071886","1077735","1084008","1089870","1094886","1099920","1105371","1111444","1118319","1125865","1133936","1142524","1151390","1160428","1169613","1180655","1192271","1201670","1210822", +"Sint Maarten (Dutch part)","SXM","Population, total","SP.POP.TOTL","2646","2888","3171","3481","3811","4161","4531","4930","5354","5795","6260","6736","7226","7750","8312","8906","9523","10172","10850","11542","12243","13134","14418","15927","17474","19064","20703","22395","24139","25952","27845","29820","31345","31823","31735","31596","31410","31195","31240","31084","30519","30600","30777","31472","32488","33011","33441","33811","33964","34238","34056","33435","34640","36607","37685","38825","38992","38615","38934","39648","40350","40708","40888","41163", +"Seychelles","SYC","Population, total","SP.POP.TOTL","41700","42889","44042","45176","46322","47500","48699","49911","51134","52365","53600","54695","56029","56892","57937","59292","60504","61786","62150","62686","63261","64035","64413","64335","64717","65244","65652","68499","68755","69167","69507","70439","70763","72253","74205","75304","76417","77319","78846","80410","81131","81202","83723","82781","82475","82858","84600","85033","86956","87298","89770","87441","88303","89949","91359","93419","94677","95843","96762","97625","98462","99258","119878","119773", +"Syrian Arab Republic","SYR","Population, total","SP.POP.TOTL","4610712","4751534","4894995","5045245","5202846","5368451","5542003","5723306","5912715","6111364","6319199","6538526","6768544","7003114","7244901","7497126","7758673","8029313","8310217","8600747","8898954","9203635","9510754","9835461","10183138","10540926","10907619","11281107","11657772","12034097","12408996","12782281","13156406","13537060","13922626","14313450","14708879","15103996","15500542","15901201","16307654","16727948","17164021","17611356","18084007","18583557","19432009","20703005","21474059","21827220","22337563","22730733","22605577","21495821","20072232","19205178","18964252","18983373","19333463","20098251","20772595","21324367","22125249","23227014", +"Turks and Caicos Islands","TCA","Population, total","SP.POP.TOTL","5604","5625","5633","5634","5642","5650","5652","5662","5668","5663","5665","5742","5896","6068","6249","6451","6668","6885","7110","7332","7598","7957","8355","8758","9166","9577","9986","10400","10816","11227","11709","12329","13014","13704","14402","15101","15806","16515","17239","17984","18744","19578","20598","21739","22869","23995","25128","26268","27422","28581","29726","30816","32081","33594","34985","36538","38246","39844","41487","43080","44276","45114","45703","46062", +"Chad","TCD","Population, total","SP.POP.TOTL","3028688","3087657","3148242","3210296","3273419","3336338","3398664","3461664","3526770","3595152","3667394","3742534","3824399","3912905","4000559","4084110","4163051","4238551","4313479","4402942","4408230","4409225","4622828","4859173","4920556","4967590","5118160","5300852","5483038","5670619","5827069","6042428","6302926","6448280","6592998","6888856","7200291","7450874","7709115","7981889","8259137","8538804","8838369","9196366","9613503","10005012","10365614","10722731","11098664","11496128","11894727","12317730","12754906","13216766","13697126","14140274","14592585","15085884","15604210","16126866","16644701","17179740","17723315","18278568", +"East Asia & Pacific (IDA & IBRD countries)","TEA","Population, total","SP.POP.TOTL","884811163","884080493","895683380","918644019","941205716","964393486","990895866","1016638561","1043384828","1071859681","1101191924","1131150405","1159394712","1186691481","1212479337","1235769316","1257283747","1277634904","1298297421","1319182209","1339615160","1360714010","1384060325","1407492473","1429843232","1452832120","1477285491","1503204089","1529464061","1555164786","1580447407","1604798136","1627823212","1650184274","1672325604","1693952154","1715256519","1736404220","1756774303","1775819557","1793649873","1810599718","1826844868","1842469495","1857622964","1872697597","1887496209","1901960228","1916309337","1930470829","1944510719","1959494275","1976386829","1993077336","2009149689","2024511016","2039794828","2055414680","2068898629","2080648616","2090523535","2097669023","2103055378","2107522258", +"Europe & Central Asia (IDA & IBRD countries)","TEC","Population, total","SP.POP.TOTL","307953778","312686272","317409940","322186073","326984010","331556829","335465854","339609605","343674963","347542691","351124926","354670274","358419274","362163691","365946532","369767028","373766849","377764919","381667915","385496921","389387079","393300463","397182700","401165360","405412775","409624220","413810265","418015169","422066390","425429530","428052009","430432700","432107597","433448069","434390109","434917015","435576314","436133770","436418552","436318238","435939387","435557974","435215194","435286231","435582965","435960155","436478592","436815160","437966129","439636046","441572315","443764567","445808734","448060105","450338927","452672729","454966816","457063732","459012381","461027359","462304330","463035774","457342249","457326090", +"Togo","TGO","Population, total","SP.POP.TOTL","1651367","1678788","1706841","1736697","1772652","1820396","1882458","1957164","2038765","2120486","2197383","2267211","2330704","2390909","2450335","2509713","2569671","2630626","2693400","2761240","2838110","2925865","3023343","3126635","3232244","3336508","3439370","3544927","3653420","3763657","3875947","3990215","4106219","4078392","4092612","4279566","4445883","4592550","4728297","4867941","5008035","5145426","5281538","5421001","5565218","5711597","5874240","6047537","6222482","6398624","6571855","6748672","6926635","7106229","7288383","7473229","7661354","7852795","8046679","8243094","8442580","8644829","8848699","9053799", +"Thailand","THA","Population, total","SP.POP.TOTL","26596584","27399963","28242174","29114124","30013573","30940270","31883754","32839341","33807357","34787583","35791728","36807997","37834384","38873060","39900961","40908471","41882128","42843802","43806715","44760091","45737753","46727292","47700340","48670565","49636724","50594940","51542094","52479181","53410965","54324004","55228410","56099865","56939020","57776082","58610010","59424834","60211096","60989108","61745217","62442651","63066603","63649892","64222580","64776956","65311166","65821360","66319525","66826754","67328239","67813654","68270489","68712846","69157023","69578602","69960943","70294397","70607037","70898202","71127802","71307763","71475664","71601103","71697030","71801279", +"Tajikistan","TJK","Population, total","SP.POP.TOTL","2131992","2208026","2287181","2368868","2452671","2538295","2625653","2714959","2806566","2899854","2993019","3085961","3180461","3277487","3377758","3482125","3590606","3703010","3818114","3932682","4045965","4160745","4278908","4401502","4529501","4660598","4798281","4946293","5100020","5264332","5417860","5556306","5656208","5717806","5803993","5916173","6035600","6117069","6156805","6189565","6272998","6408810","6541755","6672492","6801204","6929145","7057417","7188391","7324627","7468596","7621779","7784819","7956382","8136610","8326348","8524063","8725318","8925525","9128132","9337003","9543207","9750064","9952787","10143543", +"Turkmenistan","TKM","Population, total","SP.POP.TOTL","1602052","1658569","1716868","1776387","1836621","1897095","1957557","2018024","2078581","2139557","2201432","2264434","2328374","2393323","2459325","2525760","2592280","2659019","2726327","2794392","2862903","2932934","3005972","3082202","3162165","3246887","3336773","3430501","3525110","3621303","3720278","3821782","3926369","4031698","4133037","4226623","4301093","4363672","4431517","4501079","4569132","4635094","4698968","4758988","4819792","4885775","4954029","5024894","5100083","5180957","5267970","5360811","5458682","5560095","5663152","5766431","5868561","5968383","6065066","6158420","6250438","6341855","6430770","6516100", +"Latin America & the Caribbean (IDA & IBRD countries)","TLA","Population, total","SP.POP.TOTL","209162089","215120638","221237659","227495728","233883553","240382110","246943392","253554578","260217279","266932380","273707085","280564073","287536583","294641967","301866994","309188500","316602089","324205734","332018547","339930244","347846551","355632695","363395735","371274829","379186379","387082933","394960383","402834273","410749065","418679329","426738769","434864266","442918815","450949564","458977501","466965316","474848687","482663302","490409338","498053021","505569501","512930188","520132018","527128668","534010124","540822976","547495145","554042691","560459472","566813381","572949377","579610152","586263141","592784484","599226878","605613677","611946736","618155029","624120970","629795751","634961078","639469895","643884393","648763330", +"Timor-Leste","TLS","Population, total","SP.POP.TOTL","468573","475796","483324","491117","499136","507477","516197","525274","534649","544242","554021","563953","574014","584035","592277","600126","609650","619308","627671","634549","642224","649250","655112","662412","671373","682109","694250","707762","722690","739735","758106","772655","783705","795179","807115","819226","831269","843341","855409","866649","878360","893001","909639","926721","945989","969313","994564","1019362","1043076","1065540","1088486","1112976","1137676","1161555","1184830","1205813","1224562","1243235","1261845","1280438","1299995","1320942","1341296","1360596", +"Middle East & North Africa (IDA & IBRD countries)","TMN","Population, total","SP.POP.TOTL","97179656","99620285","102159899","104817905","107577280","110431969","113410132","116518346","119706733","122973346","126316235","129707914","133164152","136734072","140444545","144500701","149188764","153922894","158089953","162482818","167489905","173266699","179198278","184832095","190720860","196641041","202653537","208687611","214593293","220541237","226868111","233174871","238968838","244147588","249198247","254479053","259648021","264860153","270162305","275508430","280976957","286546301","291738620","296947926","302709154","308628177","314576732","320585896","326701327","332985938","339527169","345887176","352259724","359233517","366582958","373867247","380687450","387152617","393806257","400574097","407006855","413124452","419284769","425691336", +"Tonga","TON","Population, total","SP.POP.TOTL","67428","69391","71388","73441","75544","77686","79794","81725","83430","84997","86484","87904","89275","90611","92007","93477","94921","95847","96227","96506","96708","96846","96931","96981","97022","97055","97078","97392","97939","98379","98727","99010","99260","99492","99731","99977","100195","100658","101343","101982","102603","103210","103804","104410","105036","105633","106190","106638","106932","107144","107383","107611","107502","107089","106626","106122","105707","105415","105150","104951","105254","106017","106858","107773", +"South Asia (IDA & IBRD)","TSA","Population, total","SP.POP.TOTL","571192428","584794755","598784274","613149540","627867470","642649029","657382046","672401853","688013461","704112818","720399195","736135444","752397791","770083670","788213169","806592758","825140213","844199483","863852185","884031584","904993069","926216545","948043890","970938323","994345688","1018142776","1042169001","1066371857","1091004504","1116147699","1141312704","1166480561","1192390433","1219180082","1246157499","1272877742","1299407301","1326007987","1352849350","1379874856","1406945493","1434314654","1462070145","1489358080","1515703001","1541263909","1565892885","1589454615","1612709085","1636411632","1660546144","1684898004","1708706729","1731683901","1754030304","1775545180","1797072648","1818931519","1840534093","1861598514","1882531620","1901911604","1919348000","1938549529", +"Sub-Saharan Africa (IDA & IBRD countries)","TSS","Population, total","SP.POP.TOTL","227948869","233483265","239280622","245298063","251565974","258078554","264754002","271633185","278796894","286211901","293900563","301839225","309963136","318464764","327466848","336832917","346461069","356243762","366688083","377775643","388793467","400260774","412410102","424346370","436263644","448755435","461756164","475250346","488764908","502517080","516629688","530716971","544899623","559413902","574094137","589328085","605186062","621065325","637198518","653883261","671212486","689161982","707693440","726785433","746546802","766978666","788110000","810019264","832642735","855885698","879797419","904282154","929328653","955096702","981506608","1008698799","1036155989","1063885274","1092403973","1121549049","1151302081","1181163013","1211190002","1241897817", +"Trinidad and Tobago","TTO","Population, total","SP.POP.TOTL","847063","865028","881519","897658","913399","928462","942599","955681","967699","978642","988890","1000130","1013031","1026563","1040291","1054017","1067696","1081693","1096569","1112310","1127852","1142695","1157140","1171273","1184747","1199785","1216370","1231442","1244633","1256210","1266518","1276224","1285502","1293974","1301393","1307822","1313434","1318171","1322572","1327063","1332203","1338567","1345964","1353548","1361172","1369075","1376919","1384861","1392803","1401191","1410296","1420020","1430377","1440729","1450661","1460177","1469330","1478607","1504709","1519955","1518147","1525663","1531044","1534937", +"Tunisia","TUN","Population, total","SP.POP.TOTL","4195467","4236386","4281744","4332926","4389417","4457282","4548972","4661271","4785003","4915162","5047404","5182040","5320148","5463650","5613116","5769074","5929998","6092769","6254876","6416191","6578156","6744050","6914963","7091270","7279157","7476092","7675499","7874302","8068788","8256396","8440023","8622853","8802540","8977173","9143141","9294102","9430550","9557948","9677148","9788067","9893316","9995123","10094561","10193798","10292225","10388344","10483558","10580395","10680380","10784504","10895063","11032528","11174383","11300284","11428948","11557779","11685667","11811443","11933041","12049314","12161723","12262946","12356117","12458223", +"Turkiye","TUR","Population, total","SP.POP.TOTL","27510980","28255002","29033647","29827877","30612821","31374536","32172785","33026490","33884075","34721990","35540990","36359957","37188035","38028236","38863420","39673590","40500997","41385656","42292206","43187476","44089069","44981877","45949991","47026425","48106764","49175673","50223885","51250152","52275890","53305234","54324142","55321172","56302037","57296008","58310245","59305490","60293786","61277426","62242204","63185615","64113547","65072018","65988663","66867327","67785075","68704715","69601333","70158112","71051678","72039206","73142150","74223629","75175827","76147624","77181884","78218479","79277962","80312698","81407204","82579440","83384680","84147318","84979913","85326000", +"Tuvalu","TUV","Population, total","SP.POP.TOTL","5404","5436","5471","5503","5525","5548","5591","5657","5729","5779","5814","5854","5891","5934","6100","6381","6677","6984","7297","7552","7731","7874","7993","8099","8197","8329","8496","8665","8844","9017","9182","9354","9466","9517","9559","9585","9611","9630","9634","9640","9638","9621","9609","9668","9791","9912","10030","10149","10272","10408","10550","10700","10854","10918","10899","10877","10852","10828","10865","10956","11069","11204","11312","11396", +"Tanzania","TZA","Population, total","SP.POP.TOTL","10042458","10337891","10644622","10960161","11289556","11630603","11981932","12346286","12739965","13167782","13618192","14092218","14595699","15123504","15671316","16243826","16838919","17454627","18080005","18698636","19297659","19890930","20499922","21170717","21857176","22569625","23324270","24099415","24844147","25522898","26206012","26890906","27580723","28469017","29598323","30560071","31140733","31785846","32626498","33499772","34463704","35414469","36353531","37333918","38360879","39439505","40562052","41716497","42870884","43957933","45110527","46416031","47786137","49253643","50814552","52542823","54401802","56267032","58090443","59872579","61704518","63588334","65497748","67438106", +"Uganda","UGA","Population, total","SP.POP.TOTL","7617746","7838440","8068828","8311013","8564755","8829056","9104743","9393432","9696370","10006526","10317212","10616338","10885563","11146099","11428676","11730959","12045227","12369253","12701999","13011511","13284026","13563558","13880052","14228932","14617944","15038915","15486807","15974216","16489323","17028543","17586630","18171935","18801966","19462958","20125021","20680831","21249572","21876935","22537658","23279247","24020697","24763325","25545090","26354736","27146084","27946588","28773227","29629804","30509862","31412520","32341728","33295738","34273295","35273570","36336539","37477356","38748299","40127085","41515395","42949080","44404611","45853778","47249585","48582334", +"Ukraine","UKR","Population, total","SP.POP.TOTL","42767251","43365219","43924755","44445903","44941406","45387091","45809120","46235370","46635196","46990889","47279086","47597756","47974187","48301548","48602694","48892187","49144535","49357430","49536615","49739734","49973920","50221000","50384000","50564000","50754000","50917000","51097000","51293000","51521000","51773000","51891400","52000500","52150400","52179200","51921400","51512800","51057800","50594600","50144500","49674000","49176500","48662400","48202470","47812949","47451626","47105171","46787786","46509355","46258189","46053331","45870741","45706086","45593342","45489648","45272155","45167350","45038236","44880758","44690584","44474512","44207754","43848986","38000000","37000000", +"Upper middle income","UMC","Population, total","SP.POP.TOTL","1150380907","1156312850","1174798609","1204748060","1234451965","1264792470","1298570988","1331733785","1365940814","1401859276","1438619338","1476040539","1511859032","1546902049","1580636939","1612318924","1642551579","1671447988","1700522170","1729995976","1759117944","1789283942","1821682118","1853950774","1885288819","1917212117","1950753895","1985853431","2021166474","2055452501","2089694834","2122646055","2153048678","2181630524","2209554204","2236974487","2264204292","2291164795","2317182887","2341864677","2365641663","2388674025","2410459773","2431477678","2452531807","2473577600","2493662803","2512581065","2532733854","2553367200","2573584518","2594928568","2618529566","2642664969","2666297149","2689570305","2711688425","2733612094","2754139881","2772716573","2787915973","2799436415","2803249752","2810588102", +"Uruguay","URY","Population, total","SP.POP.TOTL","2529021","2561153","2592441","2622936","2652376","2680427","2707030","2731847","2754417","2773957","2790265","2805492","2821086","2836825","2853588","2871947","2891094","2909327","2925840","2940729","2953750","2966076","2979182","2993285","3008255","3024218","3041205","3058787","3077760","3097889","3117012","3135374","3153732","3171747","3189945","3208300","3226633","3245069","3262683","3278963","3292224","3300939","3306441","3310202","3313801","3317665","3322282","3328651","3336126","3344156","3352651","3361637","3371133","3381180","3391662","3402818","3413766","3422200","3427042","3428409","3429086","3426260","3422794","3423108", +"United States","USA","Population, total","SP.POP.TOTL","180671000","183691000","186538000","189242000","191889000","194303000","196560000","198712000","200706000","202677000","205052000","207661000","209896000","211909000","213854000","215973000","218035000","220239000","222585000","225055000","227225000","229466000","231664000","233792000","235825000","237924000","240133000","242289000","244499000","246819000","249623000","252981000","256514000","259919000","263126000","266278000","269394000","272657000","275854000","279040000","282162411","284968955","287625193","290107933","292805298","295516599","298379912","301231207","304093966","306771529","309327143","311583481","313877662","316059947","318386329","320738994","323071755","325122128","326838199","328329953","331526933","332048977","333271411","334914895", +"Uzbekistan","UZB","Population, total","SP.POP.TOTL","8372311","8692048","9038222","9394588","9758147","10130096","10504969","10881533","11261600","11641640","12011361","12370120","12733242","13107928","13494711","13894347","14307397","14731709","15154314","15558907","15947129","16335642","16735643","17152857","17594364","18063201","18560008","19077170","19600028","20102902","20510000","20952000","21449000","21942000","22377000","22785000","23225000","23667000","24051000","24311650","24650400","24964450","25271850","25567650","25864350","26167000","26488250","26868000","27302800","27767400","28562400","29339400","29774500","30243200","30757700","31298900","31847900","32388600","32956100","33580350","34232050","34915100","35648100","36412350", +"St. Vincent and the Grenadines","VCT","Population, total","SP.POP.TOTL","84141","85666","87183","88638","90053","91495","92957","94382","95758","97126","98459","99699","100843","101924","102951","103879","104709","105499","106236","106882","107480","108191","108974","109684","110329","110906","111388","111770","112076","112320","112487","112780","113222","113621","113944","114174","114290","114276","114165","113995","113813","113641","113450","113108","112608","112043","111427","110824","110316","109840","109308","108703","108083","107450","106912","106482","105963","105549","105281","104924","104632","104332","103948","103698", +"Venezuela, RB","VEN","Population, total","SP.POP.TOTL","8156937","8453106","8754082","9059953","9371333","9688138","10010685","10338848","10672654","11011335","11355475","11705674","12061621","12424804","12796220","13176387","13566112","13965250","14372959","14788523","15210443","15638426","16071654","16509596","16953234","17402304","17860872","18328655","18800770","19275292","19750579","20226214","20700461","21172100","21640833","22107286","22572110","23037561","23503819","23966960","24427729","24880203","25330929","25782029","26226927","26668785","27102081","27525097","27933833","28327892","28715022","29096159","29470426","29838021","30193258","30529716","30741464","30563433","29825653","28971683","28490453","28199867","28301696","28838499", +"British Virgin Islands","VGB","Population, total","SP.POP.TOTL","7850","7885","7902","7919","7949","8018","8139","8337","8649","9117","9581","9813","9907","10018","10146","10282","10428","10578","10727","10876","11109","11472","11889","12315","12753","13202","13656","14117","14593","15091","15617","16090","16476","16855","17255","17674","18120","18591","19079","19586","20104","20657","21288","21982","22715","23497","24323","25191","26115","27044","27556","27962","28421","28657","28971","29366","29739","30060","30335","30610","30910","31122","31305","31538", +"Virgin Islands (U.S.)","VIR","Population, total","SP.POP.TOTL","32500","34300","35000","39800","40800","43500","46200","49100","55700","60300","63476","70937","76319","84121","89941","94484","96166","93203","95929","96183","99636","99853","100068","100348","100600","100760","100842","100901","100952","101041","103963","104807","105712","106578","107318","107818","108095","108357","108537","108599","108642","108549","108509","108505","108466","108453","108369","108337","108397","108404","108357","108290","108188","108041","107882","107712","107516","107281","107001","106669","106290","105870","105413","104917", +"Viet Nam","VNM","Population, total","SP.POP.TOTL","32718461","33621982","34533889","35526727","36509166","37466077","38388210","39282564","40145287","41015865","41928849","42916624","43906019","44891281","45898698","46969616","48163573","49418150","50701458","51831389","52968270","54280394","55632153","57011444","58406863","59811313","61221107","62630787","64037514","65466361","66912613","68358820","69788747","71176405","72501087","73759110","74946448","76058603","77128424","78123713","79001142","79817777","80642308","81475825","82311227","83142095","83951800","84762269","85597241","86482923","87411012","88349117","89301326","90267739","91235504","92191398","93126529","94033048","94914330","95776716","96648685","97468029","98186856","98858950", +"Vanuatu","VUT","Population, total","SP.POP.TOTL","64608","66462","68391","70400","72493","74677","76945","79311","81782","84350","87019","89796","92687","95687","98790","102010","105341","108769","112185","115344","118156","120887","123748","126743","129873","133119","136488","139956","143528","147181","150882","154678","158577","162548","166560","170612","174714","178871","183088","187432","192074","197034","202125","207258","212422","217632","222923","228345","233952","239689","245453","251294","257313","263534","269927","276438","283218","290239","297298","304404","311685","319137","326740","334506", +"World","WLD","Population, total","SP.POP.TOTL","3031517384","3072470012","3126894230","3193470069","3260479625","3328242834","3398509802","3468395137","3540185668","3614592846","3690229198","3767950635","3843630361","3920044841","3995920225","4070060140","4143135434","4215876682","4289852068","4365802882","4442416674","4520993169","4602785312","4684967631","4766740755","4850182355","4936116651","5024401475","5113495865","5202686551","5293498452","5382640911","5470271607","5556732311","5642156981","5726848893","5811694918","5896174827","5979851049","6062415429","6144444748","6226487141","6308284566","6389592840","6471033757","6552787172","6635162568","6717583637","6801421733","6885608628","6969894715","7053988749","7141430933","7229458453","7317304568","7404251118","7490956237","7577110140","7661177849","7742724795","7821271846","7888963821","7951595433","8024997028", +"Samoa","WSM","Population, total","SP.POP.TOTL","113335","116820","120163","123416","126582","129789","132976","135752","138154","140457","142771","145064","147332","149587","152240","155263","158136","160362","161988","163489","164905","166190","166885","166944","166779","166517","166365","166773","167452","167886","168186","168701","169799","171362","173107","174902","176713","178543","180385","182211","184008","185530","186630","187440","188073","188626","189379","190478","191787","193176","194672","196351","198124","199939","201757","203571","205544","207630","209701","211905","214929","218764","222382","225681", +"Kosovo","XKX","Population, total","SP.POP.TOTL","990150","1014211","1038618","1063175","1087700","1111812","1135522","1159611","1184645","1211011","1238238","1267634","1300787","1335431","1370857","1406891","1443492","1480318","1516206","1551605","1589395","1627819","1665977","1706004","1746874","1787432","1827149","1865129","1898987","1931017","1964986","2001982","2039030","2073990","2107947","2141405","2173716","2204865","2090490","1888579","1823286","1840256","1846786","1839425","1832239","1825050","1817659","1810222","1803370","1797466","1792563","1799338","1807106","1818117","1812771","1788196","1777557","1791003","1797085","1788878","1790133","1786038","1768086","1756374", +"Yemen, Rep.","YEM","Population, total","SP.POP.TOTL","5542459","5646668","5753386","5860197","5973803","6097298","6228430","6368014","6515904","6673981","6843607","7024196","7215835","7417736","7630190","7855657","8094985","8348182","8615301","8899922","9204938","9529105","9872292","10237391","10625687","11036918","11465444","11915563","12387238","12872362","13375121","13895851","14433771","14988047","15553171","16103339","16614326","17108681","17608133","18114552","18628700","19143457","19660653","20188799","20733406","21320671","21966298","22641538","23329004","24029589","24743946","25475610","26223391","26984002","27753304","28516545","29274002","30034389","30790513","31546691","32284046","32981641","33696614","34449825", +"South Africa","ZAF","Population, total","SP.POP.TOTL","16520441","16989464","17503133","18042215","18603097","19187194","19789771","20410677","21050540","21704214","22368306","23031441","23698507","24382513","25077016","25777964","26480300","27199838","27943445","28697014","29463549","30232561","31022417","31865176","32768207","33752964","34877834","36119333","37393853","38668684","39877570","40910959","41760755","42525440","43267982","43986084","44661603","45285048","45852166","46364681","46813266","47229714","47661514","48104048","48556071","49017147","49491756","49996094","50565812","51170779","51784921","52443325","53145033","53873616","54729551","55876504","56422274","56641209","57339635","58087055","58801927","59392255","59893885","60414495", +"Zambia","ZMB","Population, total","SP.POP.TOTL","3119430","3219451","3323427","3431381","3542764","3658024","3777680","3901288","4029173","4159007","4281671","4399919","4523581","4653289","4789038","4931249","5079672","5233292","5391355","5553462","5720438","5897481","6090818","6291070","6488072","6686449","6890967","7095185","7294325","7491275","7686401","7880466","8074337","8270917","8474216","8684135","8902019","9133156","9372430","9621238","9891136","10191964","10508294","10837973","11188040","11564870","11971567","12402073","12852966","13318087","13792086","14265814","14744658","15234976","15737793","16248230","16767761","17298054","17835893","18380477","18927715","19473125","20017675","20569737", +"Zimbabwe","ZWE","Population, total","SP.POP.TOTL","3806310","3925952","4049778","4177931","4310332","4447149","4588529","4734694","4886347","5044163","5202918","5363423","5532842","5712712","5903530","6097083","6288387","6453044","6549349","6655833","7049926","7506526","7803855","8106356","8398567","8690515","8983044","9277488","9568739","9846346","10113893","10377815","10641501","10794918","10858594","10994041","11178171","11362401","11548364","11716454","11834676","11910978","11984644","12075828","12160881","12224753","12330490","12450568","12550347","12679810","12839771","13025785","13265331","13555422","13855753","14154937","14452704","14751101","15052184","15354608","15669666","15993524","16320537","16665409", diff --git a/typescript/quicksight/lib/data-transforms.ts b/typescript/quicksight/lib/data-transforms.ts new file mode 100644 index 000000000..8826108f5 --- /dev/null +++ b/typescript/quicksight/lib/data-transforms.ts @@ -0,0 +1,391 @@ +import { CfnDataSet } from "aws-cdk-lib/aws-quicksight"; +/** + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-dataset-transformoperation.html + */ +export const dataTransforms: CfnDataSet.TransformOperationProperty[] = [ + { + "castColumnTypeOperation": { + "columnName": "1960", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1961", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1962", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1963", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1964", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1965", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1966", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1967", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1968", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1969", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1970", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1971", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1972", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1973", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1974", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1975", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1976", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1977", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1978", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1979", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1980", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1981", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1982", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1983", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1984", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1985", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1986", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1987", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1988", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1989", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1990", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1991", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1992", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1993", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1994", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1995", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1996", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1997", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1998", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "1999", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2000", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2001", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2002", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2003", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2004", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2005", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2006", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2007", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2008", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2009", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2010", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2011", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2012", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2013", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2014", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2015", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2016", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2017", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2018", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2019", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2020", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2021", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2022", + "newColumnType": "INTEGER" + } + }, + { + "castColumnTypeOperation": { + "columnName": "2023", + "newColumnType": "INTEGER" + } + } +] + diff --git a/typescript/quicksight/lib/input-columns.ts b/typescript/quicksight/lib/input-columns.ts new file mode 100644 index 000000000..782a7bd8d --- /dev/null +++ b/typescript/quicksight/lib/input-columns.ts @@ -0,0 +1,72 @@ +import { CfnDataSet } from "aws-cdk-lib/aws-quicksight"; +/** + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-dataset-inputcolumn.html + */ +export const inputColumns: CfnDataSet.InputColumnProperty[] = [ + { "name": "Country Name", "type": "STRING"}, + { "name": "Country Code", "type": "STRING"}, + { "name": "1960", "type": "STRING"}, + { "name": "1961", "type": "STRING"}, + { "name": "1962", "type": "STRING"}, + { "name": "1963", "type": "STRING"}, + { "name": "1964", "type": "STRING"}, + { "name": "1965", "type": "STRING"}, + { "name": "1966", "type": "STRING"}, + { "name": "1967", "type": "STRING"}, + { "name": "1968", "type": "STRING"}, + { "name": "1969", "type": "STRING"}, + { "name": "1970", "type": "STRING"}, + { "name": "1971", "type": "STRING"}, + { "name": "1972", "type": "STRING"}, + { "name": "1973", "type": "STRING"}, + { "name": "1974", "type": "STRING"}, + { "name": "1975", "type": "STRING"}, + { "name": "1976", "type": "STRING"}, + { "name": "1977", "type": "STRING"}, + { "name": "1978", "type": "STRING"}, + { "name": "1979", "type": "STRING"}, + { "name": "1980", "type": "STRING"}, + { "name": "1981", "type": "STRING"}, + { "name": "1982", "type": "STRING"}, + { "name": "1983", "type": "STRING"}, + { "name": "1984", "type": "STRING"}, + { "name": "1985", "type": "STRING"}, + { "name": "1986", "type": "STRING"}, + { "name": "1987", "type": "STRING"}, + { "name": "1988", "type": "STRING"}, + { "name": "1989", "type": "STRING"}, + { "name": "1990", "type": "STRING"}, + { "name": "1991", "type": "STRING"}, + { "name": "1992", "type": "STRING"}, + { "name": "1993", "type": "STRING"}, + { "name": "1994", "type": "STRING"}, + { "name": "1995", "type": "STRING"}, + { "name": "1996", "type": "STRING"}, + { "name": "1997", "type": "STRING"}, + { "name": "1998", "type": "STRING"}, + { "name": "1999", "type": "STRING"}, + { "name": "2000", "type": "STRING"}, + { "name": "2001", "type": "STRING"}, + { "name": "2002", "type": "STRING"}, + { "name": "2003", "type": "STRING"}, + { "name": "2004", "type": "STRING"}, + { "name": "2005", "type": "STRING"}, + { "name": "2006", "type": "STRING"}, + { "name": "2007", "type": "STRING"}, + { "name": "2008", "type": "STRING"}, + { "name": "2009", "type": "STRING"}, + { "name": "2010", "type": "STRING"}, + { "name": "2011", "type": "STRING"}, + { "name": "2012", "type": "STRING"}, + { "name": "2013", "type": "STRING"}, + { "name": "2014", "type": "STRING"}, + { "name": "2015", "type": "STRING"}, + { "name": "2016", "type": "STRING"}, + { "name": "2017", "type": "STRING"}, + { "name": "2018", "type": "STRING"}, + { "name": "2019", "type": "STRING"}, + { "name": "2020", "type": "STRING"}, + { "name": "2021", "type": "STRING"}, + { "name": "2022", "type": "STRING"}, + { "name": "2023", "type": "STRING"} +] diff --git a/typescript/quicksight/lib/quicksight-example-stack.ts b/typescript/quicksight/lib/quicksight-example-stack.ts new file mode 100644 index 000000000..704850296 --- /dev/null +++ b/typescript/quicksight/lib/quicksight-example-stack.ts @@ -0,0 +1,205 @@ +import {Construct} from 'constructs'; +import {BlockPublicAccess, Bucket, BucketAccessControl, BucketEncryption} from 'aws-cdk-lib/aws-s3'; +import {BucketDeployment, Source} from 'aws-cdk-lib/aws-s3-deployment'; +import {CfnDataSet, CfnDataSource, CfnTemplate} from 'aws-cdk-lib/aws-quicksight'; +import {CfnManagedPolicy} from 'aws-cdk-lib/aws-iam'; +import {Stack} from 'aws-cdk-lib'; +import {dataTransforms} from './data-transforms'; +import {inputColumns} from './input-columns'; + +interface QuicksightExampleProps { + quicksightAccountArn: string; +} + +export class QuicksightExampleStack extends Stack { + /** + * location of the manifest json file in the s3 bucket. + * Used by quicksight to discover the csv files. + * */ + public static MANIFEST_KEY = 'manifests/manifest.json'; + /** + * Name of the datasource in quicksight + */ + public static QUICKSIGHT_DATASOURCE_NAME = 's3DataSourceExample'; + /** + * By default, Amazon QuickSight uses a role named aws-quicksight-service-role-v0. + * @see https://docs.aws.amazon.com/lake-formation/latest/dg/qs-integ-lf.html + */ + public static QUICKSIGHT_SERVICE_ROLE = 'aws-quicksight-service-role-v0'; + + public static QUICKSIGHT_DATASET_NAME = 'quicksightExampleDataset'; + + constructor(scope: Construct, id: string, props: QuicksightExampleProps) { + super(scope, id); + + const { bucket, deployment } = this.createBucket(); + this.createQuicksightResources(bucket, deployment, props.quicksightAccountArn); + } + + // creates s3 bucket and deploys test data + public createBucket(): {bucket: Bucket, deployment: BucketDeployment} { + const bucketName = 'example-bucket'; + + // Set up a bucket + const bucket = new Bucket(this, bucketName, { + accessControl: BucketAccessControl.BUCKET_OWNER_FULL_CONTROL, + encryption: BucketEncryption.S3_MANAGED, + blockPublicAccess: BlockPublicAccess.BLOCK_ALL + }); + + const manifest = { + fileLocations: [ + { + URIPrefixes: [`s3://${bucket.bucketName}`] + }, + ], + globalUploadSettings: { + format: 'CSV', + delimiter: ',', + } + }; + + // turn manifest JSON and s3 key into source object + const sourceInternal = Source.jsonData( + QuicksightExampleStack.MANIFEST_KEY, + manifest + ); + // deploy them and the files stored in the data directory + const deployment = new BucketDeployment(this, 'BucketDeployment', { + sources: [sourceInternal, Source.asset('./data')], + destinationBucket: bucket, + }); + return { bucket, deployment }; + } + + public createQuicksightResources(bucket: Bucket, deployment: BucketDeployment, quicksightAccountArn: string) { + + const quicksightDataSourcePermissions: CfnTemplate.ResourcePermissionProperty[] = [ + { + principal: quicksightAccountArn, + actions: [ + 'quicksight:DescribeDataSource', + 'quicksight:DescribeDataSourcePermissions', + 'quicksight:PassDataSource', + 'quicksight:UpdateDataSource' + ], + } + ]; + + const quicksightDatasetPermissions: CfnTemplate.ResourcePermissionProperty[] = [ + { + principal: quicksightAccountArn, + actions: [ + 'quicksight:DescribeDataSet', + 'quicksight:DescribeDataSetPermissions', + 'quicksight:PassDataSet', + 'quicksight:DescribeIngestion', + 'quicksight:ListIngestions', + 'quicksight:UpdateDataSet', + 'quicksight:DeleteDataSet', + 'quicksight:CreateIngestion', + 'quicksight:CancelIngestion', + 'quicksight:UpdateDataSetPermissions' + ] + } + ]; + + const policyName = 'quicksightExamplePolicy' + const managedPolicy = new CfnManagedPolicy( + this, + policyName, + { + managedPolicyName: policyName, + policyDocument: { + 'Statement': [ + { + 'Effect': 'Allow', + 'Action': ['s3:ListAllMyBuckets'], + 'Resource': ['arn:aws:s3:::*'] + }, + { + 'Effect': 'Allow', + 'Action': ['s3:*'], + 'Resource': [ + `arn:aws:s3:::${bucket.bucketName}`, + `arn:aws:s3:::${bucket.bucketName}/*` + ] + } + ], + 'Version': '2012-10-17' + }, + roles: [ QuicksightExampleStack.QUICKSIGHT_SERVICE_ROLE ] + } + ); + + + const quicksightS3DataSource = new CfnDataSource( + this, + 'S3DataSource', + { + awsAccountId: this.account, + dataSourceId: QuicksightExampleStack.QUICKSIGHT_DATASOURCE_NAME, + name: QuicksightExampleStack.QUICKSIGHT_DATASOURCE_NAME, + dataSourceParameters: { + s3Parameters: { + manifestFileLocation: { + bucket: bucket.bucketName, + key: QuicksightExampleStack.MANIFEST_KEY + } + } + }, + type: 'S3', + sslProperties: { + disableSsl: false + }, + permissions: quicksightDataSourcePermissions + } + ) + + // quicksight needs these to be created so we're waiting for the creation of these resources + quicksightS3DataSource.node.addDependency(managedPolicy); + quicksightS3DataSource.node.addDependency(deployment); + + /** + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-dataset-physicaltable.html + */ + const physicalTableProperties: CfnDataSet.PhysicalTableProperty = { + s3Source: { + dataSourceArn: quicksightS3DataSource.attrArn, + inputColumns, + uploadSettings: { + format: 'CSV', + delimiter: ',', + containsHeader: true, + startFromRow: 5 + } + } + } + + /** + * @see https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-quicksight-dataset-logicaltable.html + */ + const logicalTableProperties: CfnDataSet.LogicalTableProperty = { + alias: 's3-extract-data-cast', + source: { + physicalTableId: QuicksightExampleStack.QUICKSIGHT_DATASOURCE_NAME + }, + dataTransforms + } + + + new CfnDataSet( + this, + QuicksightExampleStack.QUICKSIGHT_DATASET_NAME, + { + awsAccountId: this.account, + physicalTableMap: {[QuicksightExampleStack.QUICKSIGHT_DATASOURCE_NAME]: physicalTableProperties}, + logicalTableMap: {[QuicksightExampleStack.QUICKSIGHT_DATASOURCE_NAME]: logicalTableProperties}, + name: QuicksightExampleStack.QUICKSIGHT_DATASET_NAME, + dataSetId: QuicksightExampleStack.QUICKSIGHT_DATASET_NAME, + permissions: quicksightDatasetPermissions, + importMode: 'SPICE' + } + ); + } +} diff --git a/typescript/quicksight/package.json b/typescript/quicksight/package.json new file mode 100644 index 000000000..c0302e659 --- /dev/null +++ b/typescript/quicksight/package.json @@ -0,0 +1,26 @@ +{ + "name": "quicksight-example", + "version": "0.1.0", + "bin": { + "quicksight-example": "bin/quicksight-example.js" + }, + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "cdk": "cdk" + }, + "devDependencies": { + "@types/jest": "^29.5.12", + "@types/node": "20.14.9", + "aws-cdk": "2.156.0", + "jest": "^29.7.0", + "ts-jest": "^29.1.5", + "ts-node": "^10.9.2", + "typescript": "~5.5.3" + }, + "dependencies": { + "aws-cdk-lib": "2.156.0", + "constructs": "^10.0.0", + "source-map-support": "^0.5.21" + } +} diff --git a/typescript/quicksight/tsconfig.json b/typescript/quicksight/tsconfig.json new file mode 100644 index 000000000..aaa7dc510 --- /dev/null +++ b/typescript/quicksight/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": [ + "es2020", + "dom" + ], + "declaration": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "typeRoots": [ + "./node_modules/@types" + ] + }, + "exclude": [ + "node_modules", + "cdk.out" + ] +} From a25bb9eb873b5f18b725dc537a46d70500f69927 Mon Sep 17 00:00:00 2001 From: Pedram Hamidehkhan Date: Mon, 4 Nov 2024 15:20:20 +0100 Subject: [PATCH 4/4] add stepfunctions with external asl definition file (#1087) * add stepfunctions with external asl definition file * Delete typescript/stepfunction-external-definition/test/stepfunction-external-definition.test.ts Does not implement test * Update package.json Does not implement test * Delete typescript/stepfunction-external-definition/jest.config.js Does not implement test * change permission setting --------- Co-authored-by: Michael Kaiser Co-authored-by: Michael Kaiser --- .../.gitignore | 8 ++ .../.npmignore | 6 ++ .../README.md | 14 ++++ .../bin/stepfunction-external-definition.ts | 21 +++++ .../stepfunction-external-definition/cdk.json | 78 +++++++++++++++++ .../stepfunction-external-definition-stack.ts | 38 +++++++++ .../package.json | 23 +++++ .../tsconfig.json | 31 +++++++ .../workflow/stepfunction.json.asl | 83 +++++++++++++++++++ 9 files changed, 302 insertions(+) create mode 100644 typescript/stepfunction-external-definition/.gitignore create mode 100644 typescript/stepfunction-external-definition/.npmignore create mode 100644 typescript/stepfunction-external-definition/README.md create mode 100644 typescript/stepfunction-external-definition/bin/stepfunction-external-definition.ts create mode 100644 typescript/stepfunction-external-definition/cdk.json create mode 100644 typescript/stepfunction-external-definition/lib/stepfunction-external-definition-stack.ts create mode 100644 typescript/stepfunction-external-definition/package.json create mode 100644 typescript/stepfunction-external-definition/tsconfig.json create mode 100644 typescript/stepfunction-external-definition/workflow/stepfunction.json.asl diff --git a/typescript/stepfunction-external-definition/.gitignore b/typescript/stepfunction-external-definition/.gitignore new file mode 100644 index 000000000..f60797b6a --- /dev/null +++ b/typescript/stepfunction-external-definition/.gitignore @@ -0,0 +1,8 @@ +*.js +!jest.config.js +*.d.ts +node_modules + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/typescript/stepfunction-external-definition/.npmignore b/typescript/stepfunction-external-definition/.npmignore new file mode 100644 index 000000000..c1d6d45dc --- /dev/null +++ b/typescript/stepfunction-external-definition/.npmignore @@ -0,0 +1,6 @@ +*.ts +!*.d.ts + +# CDK asset staging directory +.cdk.staging +cdk.out diff --git a/typescript/stepfunction-external-definition/README.md b/typescript/stepfunction-external-definition/README.md new file mode 100644 index 000000000..3c7b0da83 --- /dev/null +++ b/typescript/stepfunction-external-definition/README.md @@ -0,0 +1,14 @@ +# Welcome to your CDK TypeScript project + +This is a Tyepscript CDK project which enables implementing stepfunctions with external asl(Amazon States Language) file. This can be useful in usecases where it is desired to leverage local development flow of the stepfunction statemachines,e.g. AWS toolkit for VScode, and directly import the asl file into your project without rewriting it in CDK. + +The `cdk.json` file tells the CDK Toolkit how to execute your app. + +## Useful commands + +* `npm run build` compile typescript to js +* `npm run watch` watch for changes and compile +* `npm run test` perform the jest unit tests +* `npx cdk deploy` deploy this stack to your default AWS account/region +* `npx cdk diff` compare deployed stack with current state +* `npx cdk synth` emits the synthesized CloudFormation template diff --git a/typescript/stepfunction-external-definition/bin/stepfunction-external-definition.ts b/typescript/stepfunction-external-definition/bin/stepfunction-external-definition.ts new file mode 100644 index 000000000..8620751e2 --- /dev/null +++ b/typescript/stepfunction-external-definition/bin/stepfunction-external-definition.ts @@ -0,0 +1,21 @@ +#!/usr/bin/env node +import 'source-map-support/register'; +import * as cdk from 'aws-cdk-lib'; +import { StepfunctionExternalDefinitionStack } from '../lib/stepfunction-external-definition-stack'; + +const app = new cdk.App(); +new StepfunctionExternalDefinitionStack(app, 'StepfunctionExternalDefinitionStack', { + /* If you don't specify 'env', this stack will be environment-agnostic. + * Account/Region-dependent features and context lookups will not work, + * but a single synthesized template can be deployed anywhere. */ + + /* Uncomment the next line to specialize this stack for the AWS Account + * and Region that are implied by the current CLI configuration. */ + // env: { account: process.env.CDK_DEFAULT_ACCOUNT, region: process.env.CDK_DEFAULT_REGION }, + + /* Uncomment the next line if you know exactly what Account and Region you + * want to deploy the stack to. */ + // env: { account: '123456789012', region: 'us-east-1' }, + + /* For more information, see https://docs.aws.amazon.com/cdk/latest/guide/environments.html */ +}); \ No newline at end of file diff --git a/typescript/stepfunction-external-definition/cdk.json b/typescript/stepfunction-external-definition/cdk.json new file mode 100644 index 000000000..257e669bc --- /dev/null +++ b/typescript/stepfunction-external-definition/cdk.json @@ -0,0 +1,78 @@ +{ + "app": "npx ts-node --prefer-ts-exts bin/stepfunction-external-definition.ts", + "watch": { + "include": [ + "**" + ], + "exclude": [ + "README.md", + "cdk*.json", + "**/*.d.ts", + "**/*.js", + "tsconfig.json", + "package*.json", + "yarn.lock", + "node_modules", + "test" + ] + }, + "context": { + "@aws-cdk/aws-lambda:recognizeLayerVersion": true, + "@aws-cdk/core:checkSecretUsage": true, + "@aws-cdk/core:target-partitions": [ + "aws", + "aws-cn" + ], + "@aws-cdk-containers/ecs-service-extensions:enableDefaultLogDriver": true, + "@aws-cdk/aws-ec2:uniqueImdsv2TemplateName": true, + "@aws-cdk/aws-ecs:arnFormatIncludesClusterName": true, + "@aws-cdk/aws-iam:minimizePolicies": true, + "@aws-cdk/core:validateSnapshotRemovalPolicy": true, + "@aws-cdk/aws-codepipeline:crossAccountKeyAliasStackSafeResourceName": true, + "@aws-cdk/aws-s3:createDefaultLoggingPolicy": true, + "@aws-cdk/aws-sns-subscriptions:restrictSqsDescryption": true, + "@aws-cdk/aws-apigateway:disableCloudWatchRole": true, + "@aws-cdk/core:enablePartitionLiterals": true, + "@aws-cdk/aws-events:eventsTargetQueueSameAccount": true, + "@aws-cdk/aws-ecs:disableExplicitDeploymentControllerForCircuitBreaker": true, + "@aws-cdk/aws-iam:importedRoleStackSafeDefaultPolicyName": true, + "@aws-cdk/aws-s3:serverAccessLogsUseBucketPolicy": true, + "@aws-cdk/aws-route53-patters:useCertificate": true, + "@aws-cdk/customresources:installLatestAwsSdkDefault": false, + "@aws-cdk/aws-rds:databaseProxyUniqueResourceName": true, + "@aws-cdk/aws-codedeploy:removeAlarmsFromDeploymentGroup": true, + "@aws-cdk/aws-apigateway:authorizerChangeDeploymentLogicalId": true, + "@aws-cdk/aws-ec2:launchTemplateDefaultUserData": true, + "@aws-cdk/aws-secretsmanager:useAttachedSecretResourcePolicyForSecretTargetAttachments": true, + "@aws-cdk/aws-redshift:columnId": true, + "@aws-cdk/aws-stepfunctions-tasks:enableEmrServicePolicyV2": true, + "@aws-cdk/aws-ec2:restrictDefaultSecurityGroup": true, + "@aws-cdk/aws-apigateway:requestValidatorUniqueId": true, + "@aws-cdk/aws-kms:aliasNameRef": true, + "@aws-cdk/aws-autoscaling:generateLaunchTemplateInsteadOfLaunchConfig": true, + "@aws-cdk/core:includePrefixInUniqueNameGeneration": true, + "@aws-cdk/aws-efs:denyAnonymousAccess": true, + "@aws-cdk/aws-opensearchservice:enableOpensearchMultiAzWithStandby": true, + "@aws-cdk/aws-lambda-nodejs:useLatestRuntimeVersion": true, + "@aws-cdk/aws-efs:mountTargetOrderInsensitiveLogicalId": true, + "@aws-cdk/aws-rds:auroraClusterChangeScopeOfInstanceParameterGroupWithEachParameters": true, + "@aws-cdk/aws-appsync:useArnForSourceApiAssociationIdentifier": true, + "@aws-cdk/aws-rds:preventRenderingDeprecatedCredentials": true, + "@aws-cdk/aws-codepipeline-actions:useNewDefaultBranchForCodeCommitSource": true, + "@aws-cdk/aws-cloudwatch-actions:changeLambdaPermissionLogicalIdForLambdaAction": true, + "@aws-cdk/aws-codepipeline:crossAccountKeysDefaultValueToFalse": true, + "@aws-cdk/aws-codepipeline:defaultPipelineTypeToV2": true, + "@aws-cdk/aws-kms:reduceCrossAccountRegionPolicyScope": true, + "@aws-cdk/aws-eks:nodegroupNameAttribute": true, + "@aws-cdk/aws-ec2:ebsDefaultGp3Volume": true, + "@aws-cdk/aws-ecs:removeDefaultDeploymentAlarm": true, + "@aws-cdk/custom-resources:logApiResponseDataPropertyTrueDefault": false, + "@aws-cdk/aws-s3:keepNotificationInImportedBucket": false, + "@aws-cdk/aws-ecs:reduceEc2FargateCloudWatchPermissions": true, + "@aws-cdk/aws-ec2:ec2SumTImeoutEnabled": true, + "@aws-cdk/aws-appsync:appSyncGraphQLAPIScopeLambdaPermission": true, + "@aws-cdk/aws-rds:setCorrectValueForDatabaseInstanceReadReplicaInstanceResourceId": true, + "@aws-cdk/core:cfnIncludeRejectComplexResourceUpdateCreatePolicyIntrinsics": true, + "@aws-cdk/aws-lambda-nodejs:sdkV3ExcludeSmithyPackages": true + } +} diff --git a/typescript/stepfunction-external-definition/lib/stepfunction-external-definition-stack.ts b/typescript/stepfunction-external-definition/lib/stepfunction-external-definition-stack.ts new file mode 100644 index 000000000..8daf0da0d --- /dev/null +++ b/typescript/stepfunction-external-definition/lib/stepfunction-external-definition-stack.ts @@ -0,0 +1,38 @@ +import * as cdk from 'aws-cdk-lib'; +import { Construct } from 'constructs'; +import * as apigateway from "aws-cdk-lib/aws-apigateway"; +import * as stepfunctions from "aws-cdk-lib/aws-stepfunctions"; +import * as logs from 'aws-cdk-lib/aws-logs'; +import * as iam from "aws-cdk-lib/aws-iam"; +import * as fs from "fs"; + +export class StepfunctionExternalDefinitionStack extends cdk.Stack { + constructor(scope: Construct, id: string, props?: cdk.StackProps) { + super(scope, id, props); + + const logGroup = new logs.LogGroup(this, 'MyStateMachineLogGroup', { + logGroupName: '/aws/vendedlogs/states/MyStateMachine', + retention: logs.RetentionDays.ONE_WEEK, + }); + + const workflow = fs.readFileSync('./workflow/stepfunction.json.asl', 'utf8'); + const stateMachine= new stepfunctions.StateMachine(this, 'MyStateMachine', { + stateMachineType: stepfunctions.StateMachineType.EXPRESS, + definitionBody: stepfunctions.DefinitionBody.fromString(workflow.toString()), + logs: { + destination: logGroup, + level: stepfunctions.LogLevel.ALL, + includeExecutionData: true, + }, + }); + logGroup.grantWrite(stateMachine.role); + + const api = new apigateway.RestApi(this, "StepFuncApi", { + restApiName: "StepFuncApi", + description: "StepFuncApi", + endpointTypes: [apigateway.EndpointType.REGIONAL] + }); + const resource = api.root.addResource("orders"); + resource.addMethod("GET", apigateway.StepFunctionsIntegration.startExecution(stateMachine)); + } +} diff --git a/typescript/stepfunction-external-definition/package.json b/typescript/stepfunction-external-definition/package.json new file mode 100644 index 000000000..8bffbf265 --- /dev/null +++ b/typescript/stepfunction-external-definition/package.json @@ -0,0 +1,23 @@ +{ + "name": "stepfunction-external-definition", + "version": "0.1.0", + "bin": { + "stepfunction-external-definition": "bin/stepfunction-external-definition.js" + }, + "scripts": { + "build": "tsc", + "watch": "tsc -w", + "cdk": "cdk" + }, + "devDependencies": { + "@types/node": "22.5.4", + "aws-cdk": "2.162.1", + "ts-node": "^10.9.2", + "typescript": "~5.6.2" + }, + "dependencies": { + "aws-cdk-lib": "2.162.1", + "constructs": "^10.0.0", + "source-map-support": "^0.5.21" + } +} diff --git a/typescript/stepfunction-external-definition/tsconfig.json b/typescript/stepfunction-external-definition/tsconfig.json new file mode 100644 index 000000000..aaa7dc510 --- /dev/null +++ b/typescript/stepfunction-external-definition/tsconfig.json @@ -0,0 +1,31 @@ +{ + "compilerOptions": { + "target": "ES2020", + "module": "commonjs", + "lib": [ + "es2020", + "dom" + ], + "declaration": true, + "strict": true, + "noImplicitAny": true, + "strictNullChecks": true, + "noImplicitThis": true, + "alwaysStrict": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": false, + "inlineSourceMap": true, + "inlineSources": true, + "experimentalDecorators": true, + "strictPropertyInitialization": false, + "typeRoots": [ + "./node_modules/@types" + ] + }, + "exclude": [ + "node_modules", + "cdk.out" + ] +} diff --git a/typescript/stepfunction-external-definition/workflow/stepfunction.json.asl b/typescript/stepfunction-external-definition/workflow/stepfunction.json.asl new file mode 100644 index 000000000..29fd3b5aa --- /dev/null +++ b/typescript/stepfunction-external-definition/workflow/stepfunction.json.asl @@ -0,0 +1,83 @@ +{ + "Comment": "smiple workflow for the car company", + "StartAt": "Order Received", + "States": { + "Order Received": { + "Comment": "Order revieved.", + "Type": "Pass", + "Next": "RiskyCustomer" + }, + "RiskyCustomer": { + "Comment": "No risky business!", + "Type": "Choice", + "Choices": [ + { + "Variable": "$.risk", + "BooleanEquals": true, + "Next": "Yes" + }, + { + "Variable": "$.risk", + "BooleanEquals": false, + "Next": "No" + } + ], + "Default": "Yes" + }, + "Yes": { + "Type": "Pass", + "Next": "organize pickup" + }, + "No": { + "Type": "Fail", + "Cause": "Not Hello World" + }, + "organize pickup": { + "Comment": "wait for client to pickup", + "Type": "Wait", + "Seconds": 3, + "Next": "wait for 6 months" + }, + "wait for 6 months": { + "Comment": "wait for 6 months", + "Type": "Wait", + "Seconds": 3, + "Next": "organize return" + }, + "organize return": { + "Comment": "wait for client to return", + "Type": "Wait", + "Seconds": 3, + "Next": "Parallel State" + }, + "Parallel State": { + "Comment": "A Parallel state can be used to create parallel branches of execution in your state machine.", + "Type": "Parallel", + "Next": "return", + "Branches": [ + { + "StartAt": "book", + "States": { + "book": { + "Type": "Pass", + "End": true + } + } + }, + { + "StartAt": "calculate damage", + "States": { + "calculate damage": { + "Type": "Pass", + "End": true + } + } + } + ] + }, + "return": { + "Type": "Pass", + "End": true + } + } + } \ No newline at end of file