{"id":10353,"date":"2025-01-26T18:37:03","date_gmt":"2025-01-26T18:37:03","guid":{"rendered":"https:\/\/putridparrot.com\/blog\/?p=10353"},"modified":"2025-01-26T18:37:03","modified_gmt":"2025-01-26T18:37:03","slug":"aws-cloudformation","status":"publish","type":"post","link":"https:\/\/putridparrot.com\/blog\/aws-cloudformation\/","title":{"rendered":"AWS CloudFormation"},"content":{"rendered":"<p><em>Disclaimer: This post sat in draft for a while as I&#8217;m not using AWS at the moment I cannot guarantee that all works still or the post is 100% complete, but I&#8217;m going to publish it anyway, in case it&#8217;s of use.<\/em><\/p>\n<p>AWS CloudFormation is a service that is essentially a way to group together AWS resources into a <em>stack<\/em>. We can define the stack using the AWS Dashboard or using either JSON or YAML.<\/p>\n<p>For example, in JSON<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n{\r\n  &quot;Resources&quot;: {\r\n    &quot;S3Bucket&quot;: {\r\n      &quot;Type&quot;: &quot;AWS::S3::Bucket&quot;,\r\n      &quot;Properties&quot;: {\r\n        &quot;BucketName&quot;: &quot;mybucket&quot;\r\n      }\r\n    }\r\n  }\r\n}\r\n<\/pre>\n<p>or in YAML<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\nResources:\r\n  S3Bucket:\r\n    Type: &#039;AWS::S3::Bucket&#039;\r\n    Properties:\r\n      BucketName: mybucket\r\n<\/pre>\n<p>In this example the S3 bucket will be created within the <em>Stack<\/em>. Remember the bucket name must be unique across all accounts.<\/p>\n<ul>\n<li>From the dashboard type <em>CloudFormation<\/em> into the search box<\/li>\n<li>Once you&#8217;re on the <em>CloudFormation<\/em> page click the <em>Create stack<\/em> button<\/li>\n<\/ul>\n<p>From the <em>Create stack<\/em> page you can select a JSON or YAML template from your local machine, an Amazon S3 URL or from a Git repos. using the <em>Template is ready<\/em> option. Or you can <em>Use a sample template<\/em> to load a pre-existing stack, for example LAMP, Ruby on Rails, WordPress etc. Or you can select the <em>Create template in designer<\/em> option to use the stack designer.<\/p>\n<p>Let&#8217;s see what we can do with <em>CloudFormation<\/em> by creating our simple Echo service web API and let some tools generate our <em>CloudFormation<\/em> configuration file for us.<\/p>\n<p><strong>Setting up our credentials<\/strong><\/p>\n<p>First we&#8217;re going to need to set up our credentials. <\/p>\n<p><em>You&#8217;ll hopefully have stored the credentials when you create your IAM user, access id and secret are what&#8217;s required for this next step.<\/em><\/p>\n<p>If you prefer to handle this from a UI such as Visual Studio Extensions, then you can use the edit credential button in the <em>AWS Explorer<\/em> (load via the menu View | AWS Explorer) but let&#8217;s first do this ourselves.<\/p>\n<p>Credentials are obviously meant to be kept secret, so they&#8217;re stored on your local machine in the folder <em>C:\\Users\\&lt;your-username&gt;\\.aws<\/em> in the file named <em>credentials<\/em>. The file is an INI type file and should look like this when you&#8217;ve added your credentials<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&#x5B;profilename]\r\naws_access_key_id = IDSUPPLIEDBYAWS\r\naws_secret_access_key = SECRETSUPPLIEDBYAWS\r\n<\/pre>\n<p>The <em>profilename<\/em> is the profile name as seen in tools such as AWS Explorer or will be used in the CLI, this allows us to have multiple access key\/secrets for multiple apps. <\/p>\n<p><em>Note: if you edit this file via AWS Explorer it will add further information to the profile<\/em><\/p>\n<p><strong>Using Visual Studio Extensions<\/strong><\/p>\n<p>If you install the AWS extensions for Visual Studio, you can create <em>CloudFormation<\/em> based applications using the project templates. If you create yourself a project based upon <em>AWS Serverless Application (.NET Core &#8211; C#)<\/em> for example, you&#8217;ll then get the option to choose a project type, I chose Minimal Wweb API.<\/p>\n<p>The resultant project includes everything you need to build and deploy your application to AWS serverless. <\/p>\n<p>For example from Visual Studio 2022 with the current AWS Extensions installed<\/p>\n<ul>\n<li>Create a new project, select <em>AWS Serverless Application (.NET Core &#8211; C#)<\/em> or the <em>with Tests<\/em> version<\/li>\n<li>Once create simply replace the minimal API root method with the following\n<pre class=\"brush: csharp; title: ; notranslate\" title=\"\">\r\napp.MapGet(&quot;\/&quot;, () =&gt; &quot;Use \/echo?text=&lt;text&gt;&quot;);\r\napp.MapGet(&quot;\/echo&quot;, (string text) =&gt; $&quot;Echo: {text}&quot;);\r\n<\/pre>\n<\/li>\n<li>Open the <em>serverless.template<\/em> file and change the <em>Descriptiom<\/em> to something meaningful to your project<\/li>\n<li>Build and run locally to check everything works, i.e. <em>\/echo?text=Scooby<\/em> should echo back <em>Scooby<\/em><\/li>\n<li>We can now simply right mouse click on the <em>serverless.template<\/em> file and select <em>Publish to AWS Lambda<\/em><\/li>\n<li>From the <em>Publish to AWS Lambda<\/em> popup, enter a <em>Stack Name<\/em> if it doesn&#8217;t exist it will be created<\/li>\n<li>Enter an <em>S3 Bucket<\/em> name or click the <em>New<\/em> button and supply a name<\/li>\n<li>You might need to change the <em>AWS Credentials<\/em> if required for your specific application and <em>Region<\/em><\/li>\n<li>Click <em>Publish<\/em> and if all goes well, your application will be published to a stack in AWS and upon completion the AWS extension will show the URL for you service and you can go and try it<\/li>\n<\/ul>\n<p>At this point if you log into AWS using the same IAM account that your stack was deployed to, go to <em>CloudFormation<\/em> and you&#8217;ll see our stack was added, it should show <em>Status<\/em> as <em>CREATE_COMPLETE<\/em> it&#8217;ll have the desription we changed in the <em>serverless.template<\/em> file. In the <em>Outputs<\/em> tab we can see the ApiURL (in case you forgot to note it down). <\/p>\n<p>Now if you enter <em>S3<\/em> into the search box and go and look at our buckets, you&#8217;ll see the bucket we created and finally if you enter <em>Lambda<\/em> into the search box and go to the <em>Lambda Functions<\/em> page you&#8217;ll see the function name for our Web API.<\/p>\n<p>I&#8217;m not going to dig too much into the <em>serverless.template<\/em> file but note that the <em>Type<\/em><\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">\r\n&quot;Type&quot;: &quot;AWS::Serverless::Function&quot;,\r\n<\/pre>\n<p>Essentially creates the web API as a lamba function, sets up the IAM execution role and adds the HTTP triggers to invoke the function.<\/p>\n<p>Valid types are as followis<\/p>\n<ul>\n<li><strong>AWS::Serverless::Function<\/strong> as already looked at this will create the Lambda function, the execution role and any required triggers<\/li>\n<li><strong>AWS::Serverless::Api<\/strong> denotes a resource type for creating an API Gateway<\/li>\n<li><strong>AWS::Serverless::HttpApi<\/strong> denotes a resource type used to create REST API&#8217;s<\/li>\n<li><strong>AWS::Serverless::SimpleTable<\/strong> denotes a resource type to create a DynamoDB table with a single primary key<\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Disclaimer: This post sat in draft for a while as I&#8217;m not using AWS at the moment I cannot guarantee that all works still or the post is 100% complete, but I&#8217;m going to publish it anyway, in case it&#8217;s of use. AWS CloudFormation is a service that is essentially a way to group together [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[700],"tags":[],"class_list":["post-10353","post","type-post","status-publish","format-standard","hentry","category-aws"],"jetpack_sharing_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/10353","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/comments?post=10353"}],"version-history":[{"count":5,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/10353\/revisions"}],"predecessor-version":[{"id":11251,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/posts\/10353\/revisions\/11251"}],"wp:attachment":[{"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/media?parent=10353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/categories?post=10353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/putridparrot.com\/blog\/wp-json\/wp\/v2\/tags?post=10353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}