Part 2: Configure AWS Services (Cognito, DynamoDB, S3, IAM) using the AWS Console.
In the previous post I introduced the AmazonSwiftStarter app with a simulated backend. Now we need to set up the AWS services for the app, and replace the simulated backend with real AWS logic. In this post you will set up the AWS services. At the end of this post you will have your own configured AWS backend, ready to be used with the app. In part 3 you will connect the app with the backend, and let everything work together smoothly.
Disclaimer: My goal is to share my AWS “adventures” to help others, and to learn from your feedback. AWS can be pretty overwhelming for beginners. Therefore I like to keep things as simple as possible. My most important goal is to research the features I need for my commercial app, and prototype them in this demo app. The demo app will definitely not be of production quality!
Part 1: Introduction to the AmazonSwiftStarter demo app and a pattern for backend abstraction
Part 2: Configure AWS Services (Cognito, DynamoDB, S3, IAM) using the AWS Console
Part 3: Run AmazonSwiftStarter with the configured AWS services using the AWS iOS SDK
I will start with an overview of the services that the app uses. Next I will explain how to configure them, one by one.
Let’s take a short look at what these services do:
- Cognito: An identity service that lets you create unique identifiers for your users through a number of public login providers (like Amazon, Facebook, Twitter etc.). It also supports unauthenticated users. In our app we will use unauthenticated users.
- DynamoDB: a fully managed NoSQL database service. In our app we will use it to store data.
- S3: Simple Storage Service, offers secure and highly scalable cloud storage. Our app uses this service to store user profile photos.
- IAM: Identity and Access Management securely controls access to AWS services and resources for the app users. It can be configured to create roles, groups, and uses permissions to allow and deny app users access to AWS resources. In our app we will configure how app users are allowed to access data in DynamoDB and S3.
The image below shows how these services work together (abstracting from a lot of detail). The arrow represents a “Used By” relationship. The other lines (without arrowhead) represent an unspecified association. Cognito, S3 and DynamoDB are directly used by the app. IAM will take care of identity management and access control behind the scenes.
On a side note: The image was made with Archi, an open source tool for Enterprise Architecture Modelling in the Archimate language. I have worked for a company specialised in Enterprise Architecture. They develop their own (closed source) tools. For this company I have developed an iPad editor for Archimate.
To put this architecture in perspective you might want to take a look at Amazon’s mobile backend reference architecture (pdf). I will definitely explore other key features of this architecture, like the Api Gateway and Lambda. I consider Lambda as a viable alternative for Parse Cloudcode.
Now that we have an overview of our high level architecture we can start setting it up. This is done by configuration via the AWS console. This tutorial assumes that you already have created an account on AWS.
Our app will use Cognito for anonymous sign in.
Go to the AWS Cognito dashboard, click New Identity Pool and enter the data as shown below. Don’t forget to check Enable access to unauthenticated identities. This is important for our app, we only have unauthenticated identities.
The identity pool is where the identities of the app users are stored. Every time a new user signs in to the app a new identity is added to this pool.
Click CreatePool, and on the next screen click View Details. You’ll see that 2 roles already have been created, Cognito_AmazonSwiftStarterAuth_Role and Cognito_AmazonSwiftStarterUnauth_Role. For this app we are only interested in Cognito_AmazonSwiftStarterUnauth_Role. This role has some default permissions, which do not include access to DynamoDB or S3. We will set that up later. If you are interested you can click View Policy Document, to get a first impression of a policy document.
Click Allow. You’ll see a page with sample code for Java. Ignore this, and in the top right corner of this page click Edit Identity Pool. Here you will find the Identity pool ID generated by Cognito (in the image I have used the placeholder YOUR_COGNITO_IDENTITY_POOL_ID). Copy your Identity pool ID string and keep it somewhere. You will need it later when configuring the app.
We’re done setting up Cognito. There’s more configuration work ahead.
We will use DynamoDB to store the data of our app. First go to the DynamoDB dashboard and click Create Table
You’ll see a screen similar to the one below. You have to enter a name for your table. This table will store the User data, so choose something meaningful. I will refer to your table name as YOUR_DYNAMO_DB_USERS_TABLE. DynamoDB table names must be unique within an AWS region. In the Primary Key field add the data exactly as shown in the image (userId of type String).
You have to realise that DynamoDB automatically distributes your data across table partitions, which are stored on multiple servers. It uses the primary key (or more precise a hash of the primary key) to determine the partitioning details. I consider this out of scope for this blog post. I’d rather focus on integrating all services and making this simple app work before exploring all details. For production apps it is important, for reasons of scalability, performance and costs. Anyway, if you are interested in the DynamoDB details, you might want to take a look at the DynamoDB documentation.
Click Create, and you will be taken to the next screen (this might take a minute or so). It presents an overview of your DynamoDB tables.
You need to remember the ARN (Amazon Resource Name) of your table (shown as YOUR_DYNAMODB_USERS_TABLE_ARN). We will need that later, when configuring access policies.
You’re done configuring DynamoDB!
Just one more thing that is good to know. Pricing of DynamoDB works a bit different than you might expect. You are charged based on provisioned capacity for reads and writes.You need to provide an initial estimation, and you are charged accordingly. The free tier does apply to a certain maximum.
Our app will use S3 to store profile photos. Go to the S3 dashboard and click Create Bucket. Enter a name for the bucket. A bucket name must be globally unique. In this blog I will refer to the bucket name as YOUR_S3BUCKET_USERS.
After adding the bucket name click Create
You’re done configuring S3! This was the easiest one!
In the next step you will need the ARN of the bucket. The full ARN of a bucket is determined by its bucket name, prefixed with some aditional characters as shown here:
YOUR_S3BUCKET_USERS_ARN = arn:aws:s3:::YOUR_S3BUCKET_USERS
Setup Access Permissions on IAM
We have configured DynamoDB and S3, but we have not stated anywhere what kind of rights our app users have to access these services. We can solve this by configuring access permissions on AWS IAM for the unauthenticated user role.
Go to the IAM dashboard and click Roles (on the left). The following screen will appear:
These roles have been created for you while setting up Cognito. Now click Cognito_AmazonSwiftStarterUnauth_Role. This is the role of the unauthenticated user.
On the policy near the bottom of the screen click Edit Policy
Replace the existing policy with the policy that is shown below.
Replace the placeholders that start with YOUR_* by the values that you wrote down earlier. In the policy, behind the YOUR_S3BUCKET_USERS_ARN is a *. Be careful not to delete it accidentally while replacing the placeholder.
This policy allows users with the role Cognito_AmazonSwiftStarterUnauth_Role access to your DynamoDB table and your S3 bucket. I have not given creation of secure policy statements a high priority in my research yet. My primary goal was to make the app work for this blog. I succeeded, but with this policy the app security is insufficient for production code. I will dive into that topic some other time. If you are interested you can take a look at the Overview of IAM Policies document.
Click Validate Policy (a syntax check) and Apply Policy
You have now configured access policies for the services that you have set up.
We’re done. The server configuration is ready. You have created a highly scalable backend that is waiting to be called by the app. In the next post we are going to use it! We will replace the simulated backend by logic that talks to the AWS services you just configured. At the end of part 3 we will have a working app!