All Projects → jakejscott → Humidifier

jakejscott / Humidifier

Licence: BSD-2-Clause license
AWS Cloudformation using C#

Programming Languages

C#
18002 projects
powershell
5483 projects

Projects that are alternatives of or similar to Humidifier

cfn-tf-custom-types
CloudFormation Custom Types for Terraform resources.
Stars: ✭ 53 (+17.78%)
Mutual labels:  cloudformation
cfn-deploy
A useful GitHub Action to help you deploy cloudformation templates
Stars: ✭ 14 (-68.89%)
Mutual labels:  cloudformation
go-localstack
Go Wrapper for using localstack
Stars: ✭ 56 (+24.44%)
Mutual labels:  cloudformation
cfn-ami-to-mapping
Generate your CloudFormation RegionMap automatically
Stars: ✭ 34 (-24.44%)
Mutual labels:  cloudformation
WazeCCPProcessor
Waze WARP takes your CCP data feed and processes it into your cloud provider for access, analysis, and visualization. An Open Government Coalition (OGC) project. @GovInTheOpen
Stars: ✭ 80 (+77.78%)
Mutual labels:  cloudformation
eks-deep-dive-2019
Amazon EKS Deep Dive 2019
Stars: ✭ 61 (+35.56%)
Mutual labels:  cloudformation
collector-backend
Back-end collector API and publishers for Desole
Stars: ✭ 64 (+42.22%)
Mutual labels:  cloudformation
Hands-On-Serverless-Applications-with-Go
Hands-On Serverless Applications with Go, published by Packt.
Stars: ✭ 92 (+104.44%)
Mutual labels:  cloudformation
eks-cluster
Quickly spin up an AWS EKS Kubernetes cluster using AWS CloudFormation
Stars: ✭ 41 (-8.89%)
Mutual labels:  cloudformation
cfoo
CloudFormation master
Stars: ✭ 22 (-51.11%)
Mutual labels:  cloudformation
StackJanitor
StackJanitor is a serverless, event-driven stack cleanup tool.
Stars: ✭ 37 (-17.78%)
Mutual labels:  cloudformation
quickstart-microsoft-sql
AWS Quick Start Team
Stars: ✭ 60 (+33.33%)
Mutual labels:  cloudformation
aws-autoscaling-gitlab-runner
CloudFormation template to deploy a GitLab Runner with auto-scaling on AWS.
Stars: ✭ 44 (-2.22%)
Mutual labels:  cloudformation
cfn101-workshop
AWS CloudFormation Workshop
Stars: ✭ 114 (+153.33%)
Mutual labels:  cloudformation
aws-cfn-ses-domain
AWS CloudFormation resources for Amazon SES domain and email identities
Stars: ✭ 45 (+0%)
Mutual labels:  cloudformation
data-transfer-hub
Seamless User Interface for replicating data into AWS.
Stars: ✭ 102 (+126.67%)
Mutual labels:  cloudformation
wolkenkratzer
Javascript library for generating CloudFormation templates
Stars: ✭ 13 (-71.11%)
Mutual labels:  cloudformation
atlantis
GitOps for Teams (experimental hard fork of atlantis)
Stars: ✭ 13 (-71.11%)
Mutual labels:  cloudformation
ecs-mesh-workshop
This handy workshop help the customers to quickly launch ECS with service mesh support on top of mixed type of instance in all commercial regions (include China), and also provides hands-on tutorials with best practices. It can be customized easily as per need.
Stars: ✭ 17 (-62.22%)
Mutual labels:  cloudformation
aloisius
A Python library to create/update/delete AWS CloudFormation stacks in parallel
Stars: ✭ 16 (-64.44%)
Mutual labels:  cloudformation

Humidifier Build status NuGet

Humidifier allows you to build AWS CloudFormation templates programmatically. Stacks and resources are represented as C# objects with accessors for all their supported properties.

The code is automatically generated by parsing the official Cloudformation specification.

Similar Projects

New feature: Project templates

To get up and running with Humidifier quickly, we've included a production ready template for deploying and managing your AWS Cloudformation/Serverless projects. The template is installed using the dotnet new cli command. Your can view the code here.

Features:

  • Cross platform deploy tool (Windows/Mac OSX/Linux) built using dotnet core.
  • Cloudformation stacks are defined in strongly typed C# using Humidifer of course.
  • A README that has a quickstart with commands generated for you to get up and running quickly.
  • Includes a simple Lambda function that can be deployed in seconds, configured with Serilog and Cloudwatch metrics.
  • Includes code for invoking the Lambda function, tailing the log and viewing the response.
  • Config using .env files and environment variables for CI/CD.
  • Secrets management using .aes files (encrypt/decrypt) and sync to parameter store.
  • Unit test project

Step 1: Install the template

dotnet new -i Humidifier.Templates::*

This will download the template from https://www.nuget.org/packages/Humidifier.Templates and install it into the dotnet cli template cache.

Step 2: Check to see the template is installed

dotnet new --list

You should see output similar to this:

Templates Short Name Language Tags
Humidifier Solution Template humidifier.sln [C#] AWS/Lambda/Serverless
Console Application console [C#], F#, VB Common/Console
Class library classlib [C#], F#, VB Common/Library
Unit Test Project mstest [C#], F#, VB Test/MSTest
xUnit Test Project xunit [C#], F#, VB Test/xUnit
global.json file globaljson Config
NuGet Config nugetconfig Config
Web Config webconfig Config
Solution File sln Solution

Step 3: Create your project

dotnet new humidifier.sln --name Example --output Example --env test --region us-west-2 --stack example --profile default

This will generate the solution in the --output folder. The --profile flag is your AWS credential profile. To setup a AWS profile, follow the docs on how to configure the AWS Cli here.

Step 3: Read the generated README.

The template generates a README that has a quickstart with all the commands for building, testing, deploying and destroying your stacks. If your reading this on Github, browse to the template README to see what's included.


Getting started

Nuget:

dotnet add package Humidifier
dotnet add package Humidifier.Json

Stacks are represented by the Humidifier.Stack class. Resources are represented by an exact mapping from AWS resource names to Humidifier resources names (e.g. AWS::EC2::Instance becomes Humidifier.EC2.Instance). Resources have properties for each JSON attribute.

There's also a demo application which creates a template and writes it out to a file using JSON.

Example usage

using System.Collections.Generic;
using System.IO;
using Humidifier.Json;

namespace Humidifier.ConsoleTest
{
    public static class Program
    {
        public static void Main(string[] args)
        {
            Stack stack = BuildStack();

            var serializer = new JsonStackSerializer();
            var template = serializer.Serialize(stack);

            File.WriteAllText("cloudformation.template", template);
        }

        private static Stack BuildStack()
        {
            var stack = new Stack
            {
                AWSTemplateFormatVersion = "2010-09-09",
                Description = "Description"
            };

            stack.Add("Environment", new Parameter
            {
                Type = "String",
                Description = "Deployment environment",
                MinLength = 3,
                MaxLength = 4,
                AllowedValues = new List<string> { "test", "uat", "prod" },
                ConstraintDescription = "Allowed values: [test, uat, prod]"
            });

            stack.Add("AutomationStack", new Parameter
            {
                Type = "String",
                Description = "Automation stack name",
                MinLength = 1,
                MaxLength = 255,
                AllowedPattern = "^[a-zA-Z][-a-zA-Z0-9]*$",
                ConstraintDescription = "Must be a valid Cloudformation Stack name"
            });

            stack.Add("CodeS3Key", new Parameter
            {
                Type = "String",
                MinLength = 3
            });

            stack.Add("VPC", new EC2.VPC
            {
                CidrBlock = "10.0.0.0/16",
                EnableDnsSupport = false,
                EnableDnsHostnames = false,
                InstanceTenancy = "dedicated",
                Tags = new List<Tag>
                {
                    new Tag { Key = "foo", Value = "bar" }
                }
            });

            stack.Add("Subnet", new EC2.Subnet
            {
                VpcId = Fn.Ref("VPC"),
                CidrBlock = "10.0.0.0/24",
                AvailabilityZone = Fn.Select("0", Fn.GetAZs(Fn.Ref("AWS::Region")))
            });

            stack.Add("Ec2Instance", new EC2.Instance
            {
                ImageId = Fn.FindInMap("RegionMap", Fn.Ref("AWS::Region"), "64"),
                InstanceType = "m1.small",
                UserData = Fn.Base64(
                    @"#!/bin/bash -e
                    wget https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.6.2-1.ubuntu.12.04_amd64.deb
                    dpkg -i chef_11.6.2-1.ubuntu.12.04_amd64.deb"
                )
            });

            stack.Add("AutomationServiceRole", new IAM.Role
            {
                AssumeRolePolicyDocument = new PolicyDocument
                {
                    Statement = new List<Statement>
                    {
                        new Statement
                        {
                            Effect = "Allow",
                            Principal = new { Service = "cloudformation.amazonaws.com" },
                            Action = "sts:AssumeRole"
                        }
                    }
                }
            });

            stack.Add("DeploymentBucket", new S3.Bucket { BucketName = Fn.Ref("AWS::StackName") });
            stack.Add("DeploymentBucketPolicy", new S3.BucketPolicy
            {
                Bucket = Fn.Ref("DeploymentBucket"),
                PolicyDocument = new PolicyDocument
                {
                    Version = "2012-10-17",
                    Statement = new List<Statement>
                    {
                        new Statement
                        {
                            Effect = "Allow",
                            Principal = new
                            {
                               AWS = Fn.GetAtt("AutomationServiceRole", IAM.Role.Attributes.Arn)
                            },
                            Action = "s3:*",
                            Resource = new[]
                            {
                                Fn.Join("", "arn:aws:s3:::", Fn.Ref("DeploymentBucket")),
                                Fn.Join("", "arn:aws:s3:::", Fn.Ref("DeploymentBucket"), "/*")
                            }
                        }
                    }
                }
            });

            stack.Add("LambdaFunction", new Lambda.Function
            {
                Timeout = 30,
                FunctionName = new { Ref = "AWS::StackName" },
                Runtime = "dotnetcore1.0",
                Description = "",
                Handler = "SomeProject::SomeProject.SomeFunction::FunctionHandler",
                MemorySize = 256,
                Code = new Code
                {
                    S3Bucket = Fn.ImportValue(Fn.Sub("${AutomationStack}-DeploymentBucket")),
                    S3Key = new { Ref = "CodeS3Key" },
                },
                Environment = new Environment
                {
                    Variables = new Dictionary<string, dynamic>
                    {
                        ["EnvironmentName"] = Fn.Ref("Environment")
                    }
                },
            });

            stack.Add("MonitoringSnsTopic", new SNS.Topic
            {
                DisplayName = Fn.Ref("AWS::StackName"),
                Subscription = new List<SNS.Subscription>
                {
                    new SNS.Subscription { Endpoint = "[email protected]", Protocol = "email" }
                }
            });

            stack.Add("KmsKey", new KMS.Key
            {
                Description = "A Key",
                KeyPolicy = new PolicyDocument
                {
                    Id = "key-default-1",
                    Version = "2012-10-17",
                    Statement = new List<Statement>
                    {
                        new Statement
                        {
                            Sid = "Allow the administration of the key",
                            Effect = "Allows",
                            Principal = new {AWS = "arn:aws:iam::123456789012:user/Alice"},
                            Action = new[]
                            {
                                "kms:Create*",
                                "kms:Describe*",
                                "kms:Enable*",
                                "kms:List*",
                                "kms:Put*",
                                "kms:Update*",
                                "kms:Revoke*",
                                "kms:Disable*",
                                "kms:Get*",
                                "kms:Delete*",
                                "kms:ScheduleKeyDeletion",
                                "kms:CancelKeyDeletion"
                            },
                            Resource = "*"
                        }
                    }
                }
            });

            var regionMap = new Mapping
            {
                ["us-east-1"] = new Dictionary<string, string> { ["32"] = "ami-6411e20d", ["64"] = "ami-7a11e213" },
                ["us-west-1"] = new Dictionary<string, string> { ["32"] = "ami-c9c7978c", ["64"] = "ami-cfc7978a" },
                ["ue-west-1"] = new Dictionary<string, string> { ["32"] = "ami-37c2f643", ["64"] = "ami-31c2f645" },
                ["ap-southeast-1"] = new Dictionary<string, string> { ["32"] = "ami-66f28c34", ["64"] = "ami-60f28c32" },
                ["ap-northeast-1"] = new Dictionary<string, string> { ["32"] = "ami-9c03a89d", ["64"] = "ami-a003a8a1" }
            };

            stack.Mappings.Add("RegionMap", regionMap);

            return stack;
        }
    }
}

Functions

You can use CFN intrinsic functions and references using Fn.[name]. Those will build appropriate structures that know how to be dumped to CFN syntax appropriately.

Fn.FindInMap("RegionMap", Fn.Ref("AWS::Region"), "64");
Fn.GetAtt("MyElb", ElasticLoadBalancing.LoadBalancer.Attributes.DNSName);
Fn.GetAZs("us-east-2");
Fn.ImportValue(Fn.Sub("${NetworkStackNameParameter}-SubnetID"));
Fn.Join("", "arn:aws:s3:::", Fn.Ref("DeployBucket"), "/*");
Fn.Ref("BucketName");
Fn.Select("1", new[] { "a", "b", "c" });
Fn.Split("|", "a|b|c");
Fn.Sub("${AWS::StackName}-${AWS::Region}-bucket");
Fn.Select("1", Fn.Split("|", "a|b|c"));

NOTE: Because JSON doesn't allow newlines, there's a known hack where you can join multiple lines together using Fn::Join

Fn.Base64(Fn.Join("",
  "#!/bin/bash -e\n",
  "wget https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.6.2-1.ubuntu.12.04_amd64.deb\n",
  "dpkg -i chef_11.6.2-1.ubuntu.12.04_amd64.deb\n"
));

But that's gross and unreadable when outputted as JSON. Instead use a multiline C# string, and let the library take care of encoding it for you:

  • Whitespace on the start of the line is trimmed, which means you can indent your code nicely (Like you can in YAML).
  • Newlines are encoded as \r\n automatically by NewtonSoft.Json.
Fn.Base64(
  @"#!/bin/bash -e
  wget https://opscode-omnibus-packages.s3.amazonaws.com/ubuntu/12.04/x86_64/chef_11.6.2-1.ubuntu.12.04_amd64.deb
  dpkg -i chef_11.6.2-1.ubuntu.12.04_amd64.deb"
);

Conditions

stack.Add("CreateProdResources", new Condition(Fn.Equals(Fn.Ref("Environment"), "prod")));
stack.Add("CreateDevResources", new Condition(Fn.Equals(Fn.Ref("Environment"), "dev")));
stack.Add("NotCondition", new Condition(Fn.Not(Fn.Equals(Fn.Ref("Environment"), "prod"))));
stack.Add("AndCondition", 
    new Condition(
        Fn.And(
            Fn.Equals("sg-mysqgroup", Fn.Ref("SecurityGroup")),
            new { Condition = "NotCondition" }
        )
    )
);
stack.Add("OrCondition",
    new Condition(
        Fn.Or(
            Fn.Equals("sg-mysqgroup", Fn.Ref("SecurityGroup")),
            new { Condition = "NotCondition" }
        )
    )
);

To specify a condition on a resource use the overload to stack.Add and pass in the condition parameter.

stack.Add("Volume", new EC2.Volume
{
    Size = 100,
    AvailabilityZone = Fn.GetAtt("Ec2Instance", EC2.Instance.Attributes.AvailabilityZone)
},
condition: "CreateProdResources");
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].