Wednesday, January 8, 2014

Create OAI and Canonical User using .NET code


There are some tasks which we can’t achieve using the cloud formation scripts for all those we can always use the server side code to do that either JAVA or .NET.

If you're using Amazon S3 for your origin, you can use an origin access identity to require users to access your content using a CloudFront URL instead of the Amazon S3 URL.
Manually it’s very easy to create the OAI and link it to the S3 bucket, but when we want creating bucket and distribution using the Cloud formation scripts we need to create the OAI user using the server side code. Reason for this OAI creation will take time when we are running the piece of server side code for the same.

In Cloud formation script we can execute the exe file (server side code) which first generates the OAI user and then we can link it to the scripts. Below I have pasted the server side code for OAI creation.
These are the steps we need to follow when we want to automate the bucket and distribution creation using Cloud formation script.


Steps to follow:

  1. First Create the OAI user using the .NET/Java code and store the OAI id in some file.
  2. Once the ID is created pass the ID as parameter to the cloud formation script.



Script:
aws cloudformation create-stack --stack-name projecttemplate --template-body file://project.json --parameters file://Data.json

  1. project.json : Will have the Script to create bucket and distribution
  2. Data.json: Will have the parameter like OAI ID or any other variable such as bucket name etc.


  

.NET Source Code : To create the OAI User and store it in some JSON file.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Amazon.CloudFront;
using Amazon.CloudFront.Model;
using System.Collections.Specialized;
using System.Configuration;
using Amazon.CloudFormation.Model;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Data;
using System.IO;

// Require AWS SDK for .NET http://aws.amazon.com/sdkfornet/

namespace AWS_Test
{
    class Program
    {
        static string accessKeyID = ConfigurationSettings.AppSettings["accessKeyID"].ToString();
        static string secretAccessKeyID = ConfigurationSettings.AppSettings["secretAccessKeyID"].ToString();

        static string configComment = ConfigurationSettings.AppSettings["Comment"].ToString();
        static string configCallerReference = ConfigurationSettings.AppSettings["CallerReference"].ToString();
        static AmazonCloudFrontClient cfClient = null;

        static void Main(string[] args)
        {


            using (cfClient = (AmazonCloudFrontClient)Amazon.AWSClientFactory.CreateAmazonCloudFrontClient(accessKeyID, secretAccessKeyID))
            {

                Console.WriteLine("Create CloudFront Origin Access Identity");
                CreateCloudFrontOAI();

                Console.WriteLine("Get CloudFront Origin Access Identity");
                GetCloudFrontOAI();

                Console.WriteLine("Finish");
            }

            Console.WriteLine("Press any key to continue...");
            //Console.Read();
        }

        /// <summary>
        /// POST Origin Access Identity
        /// http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/index.html?CreateOAI.html
        /// </summary>
        static void CreateCloudFrontOAI()
        {
            try
            {
                CloudFrontOriginAccessIdentityConfig config = new CloudFrontOriginAccessIdentityConfig();
                config.Comment = configComment;
                config.CallerReference = configCallerReference;

                CreateCloudFrontOriginAccessIdentityRequest req = new CreateCloudFrontOriginAccessIdentityRequest();
                req.CloudFrontOriginAccessIdentityConfig = config;

                var res = cfClient.CreateCloudFrontOriginAccessIdentity(req);

                CloudFrontOriginAccessIdentity id = res.CloudFrontOriginAccessIdentity;
                String xml = res.ResponseMetadata.ToString();

                Console.WriteLine("OAI id:" + id.Id);
                Console.WriteLine("OAI S3CanonicalUserId:" + id.S3CanonicalUserId);
                Console.WriteLine(xml);

                writeinfile(id.Id);

            }
            catch (AmazonCloudFrontException cfEx)
            {
                Console.WriteLine("An Error, number {0}, occurred when create cloud distribution with the message '{1}", cfEx.ErrorCode, cfEx.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("UnknownError:{0}", ex.Message);
            }
        }

        /// <summary>
        /// GET Origin Access Identity
        /// http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/index.html?GetOAI.html
        /// </summary>
        static void GetCloudFrontOAI()
        {
            try
            {
                GetCloudFrontOriginAccessIdentityConfigRequest request = new GetCloudFrontOriginAccessIdentityConfigRequest();
                request.Id = "ORIGIN_ACCESS_IDENTITY_ID";

                GetCloudFrontOriginAccessIdentityConfigResponse response = cfClient.GetCloudFrontOriginAccessIdentityConfig(request);

                //String xml = response.XML;
                //Console.WriteLine(xml);

                Console.WriteLine("Etag: " + response.ETag);
            }
            catch (AmazonCloudFrontException cfEx)
            {
                Console.WriteLine("An Error, number {0}, occurred when create cloud distribution with the message '{1}", cfEx.ErrorCode, cfEx.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("UnknownError:{0}", ex.Message);
            }
        }

        /// <summary>
        /// GET Origin Access Identity List
        /// http://docs.amazonwebservices.com/AmazonCloudFront/latest/APIReference/index.html?ListOAIs.html
        /// </summary>
        static void ListCloudFrontOAI()
        {
            try
            {
                ListCloudFrontOriginAccessIdentitiesResponse response = cfClient.ListCloudFrontOriginAccessIdentities();

                String xml = response.ResponseMetadata.ToString();
                Console.WriteLine(xml);
            }
            catch (AmazonCloudFrontException cfEx)
            {
                Console.WriteLine("An Error, number {0}, occurred when create cloud distribution with the message '{1}", cfEx.ErrorCode, cfEx.Message);
            }
            catch (Exception ex)
            {
                Console.WriteLine("UnknownError:{0}", ex.Message);
            }
        }


        /// <summary>
        /// function to update the json file with the OAIID value
        /// </summary>
        /// <param name="OAIID"></param>
        static void writeinfile(string OAIID)
        {
            string jsonString = string.Empty;

            StreamReader re = File.OpenText(ConfigurationSettings.AppSettings["filepath"].ToString() + "DevData.json");
            JsonTextReader reader = new JsonTextReader(re);
            JArray root = JArray.Load(reader);

            foreach (JObject o in root)
            {

                if (o.GetValue("ParameterKey").ToString() == "oaiid")
                {
                    o["ParameterValue"] = OAIID;
                }

                if (jsonString.ToString() == string.Empty)
                {
                    jsonString += o.ToString();
                }
                else
                {
                    jsonString += "," + o.ToString();
                }
            }

            jsonString = "[" + jsonString + "]";
            re.Close();
            System.IO.File.WriteAllText(ConfigurationSettings.AppSettings["filepath"].ToString() + "DevData" + ".json", jsonString);
        }
    }

}

References: