示例#1
0
        static string CreateStack(StackBase stack)
        {
            Console.WriteLine(
                "Creating {0} stack for build {1}",
                stack.StackType,
                stack.Version
                );

            //string template = CreateBuildTemplate(stackName, commit);
            //string outFile = String.Format("debug-{0}-{1}-template.json", stack.StackType, stack.Environment);
            //File.WriteAllText(outFile, template);
            Console.WriteLine("    Creating stack {0}", stack.Name);

            CreateStackResponse response = cloudFormationClient.CreateStackAsync(
                new CreateStackRequest
            {
                OnFailure        = OnFailure.DELETE,
                StackName        = stack.Name,
                Parameters       = stack.Parameters,
                TemplateBody     = stack.GetTemplate(),
                TimeoutInMinutes = 20,
                Tags             = stack.Tags,
            }
                ).Result;

            string stackId = response.StackId;

            Console.WriteLine("Created {0}", stackId);
            return(stackId);
        }
示例#2
0
        public async Task <string> CreateStack(string path, string stackName,
                                               string templateContent, List <KeyValuePair <string, string> > saParameters)
        {
            List <Parameter> awsParameters = new List <Parameter>();

            foreach (var saParam in saParameters)
            {
                Parameter awsParam = new Parameter();
                awsParam.ParameterKey   = saParam.Key;
                awsParam.ParameterValue = saParam.Value;
                awsParameters.Add(awsParam);
            }
            var request = new CreateStackRequest()
            {
                StackName    = stackName,
                TemplateBody = templateContent,
                Parameters   = awsParameters
            };
            var response = await client.CreateStackAsync(request);

            if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
            {
                return(response.StackId);
            }
            else
            {
                return(response.HttpStatusCode.ToString());
            }
        }
示例#3
0
        public async Task CreateFullStack()
        {
            var ec2Client = new AmazonEC2Client(RegionEndpoint.EUWest1);
            var keyResult = await ec2Client.CreateKeyPairAsync(new CreateKeyPairRequest($"comformation-{Guid.NewGuid()}"));

            try
            {
                // Generate template
                var template = CreateFullTemplate();

                var request = new CreateStackRequest
                {
                    StackName    = $"ComformationTestInfraTemplate-{Guid.NewGuid()}",
                    TemplateBody = template.ToString(),
                    Parameters   = new List <Amazon.CloudFormation.Model.Parameter>
                    {
                        new Amazon.CloudFormation.Model.Parameter
                        {
                            ParameterKey   = "KeyPairName",
                            ParameterValue = keyResult.KeyPair.KeyName
                        }
                    }
                };

                try
                {
                    // Create stack
                    var createResponse = await _cloudformation.CreateStackAsync(request);

                    try
                    {
                        // Get created stack details
                        var stack = await _cloudformation.GetCreatedStack(createResponse.StackId);

                        // Validate created stack
                        AssertCreatedStuck(stack, keyResult.KeyPair);
                    }
                    finally
                    {
                        // cleanup
                        var deleteResponse =
                            await _cloudformation.DeleteStackAsync(new DeleteStackRequest
                        {
                            StackName = createResponse.StackId
                        });
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    throw;
                }
            }
            finally
            {
                await ec2Client.DeleteKeyPairAsync(new DeleteKeyPairRequest(keyResult.KeyPair.KeyName));
            }
        }
        public static async Task CreateCloudformationStack(string stackName, string templatePath, List <Parameter> parameters, bool disableRollBack = false)
        {
            var client = new AmazonCloudFormationClient();
            await client.CreateStackAsync(new CreateStackRequest
            {
                StackName       = stackName,
                TemplateBody    = File.ReadAllText(templatePath),
                Parameters      = parameters,
                Capabilities    = DefaultCapabilities,
                DisableRollback = disableRollBack
            });

            await WaitForStackStatus(stackName, StackStatus.CREATE_COMPLETE);
        }
示例#5
0
        public async Task CreateSimpleStack()
        {
            // Generate template
            var template = CreateSimpleTemplate();

            var request = new CreateStackRequest
            {
                StackName    = "ComformationTestSimpleTemplate",
                TemplateBody = template.ToString(),
                Parameters   = new List <Amazon.CloudFormation.Model.Parameter>
                {
                    new Amazon.CloudFormation.Model.Parameter
                    {
                        ParameterKey   = "Param2",
                        ParameterValue = "2"
                    }
                },
            };

            try
            {
                // Create stack
                var createResponse = await _cloudformation.CreateStackAsync(request);

                try
                {
                    // Get created stack details
                    var stack = await GetCreatedStack(createResponse.StackId);

                    // Validate created stack
                    await AssertCreatedStuck(stack, template);
                }
                finally
                {
                    // cleanup
                    var deleteResponse =
                        await _cloudformation.DeleteStackAsync(new DeleteStackRequest
                    {
                        StackName = createResponse.StackId
                    });
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                throw;
            }
        }
示例#6
0
        public async Task <string> FunctionHandler(S3EventNotification evnt, ILambdaContext context)
        {
            // S3 Client and the associated Call Variables
            IAmazonS3 S3Client = new AmazonS3Client();

            S3EventNotification.S3Entity s3Event = new S3EventNotification.S3Entity();
            GetObjectRequest             ParameterFileRequest  = new GetObjectRequest();
            GetObjectResponse            ParameterFileResponse = new GetObjectResponse();
            GetPreSignedUrlRequest       PresignedKeyRequest   = new GetPreSignedUrlRequest();
            GetObjectResponse            CommitInfoResponse    = new GetObjectResponse();

            // Cloudformation Client and associated Variables
            AmazonCloudFormationClient CloudformationClient  = new AmazonCloudFormationClient();
            List <Parameter>           Parameters            = new List <Parameter>();
            DescribeStacksRequest      CurrentStacksRequest  = new DescribeStacksRequest();
            DescribeStacksResponse     CurrentStacksResponse = new DescribeStacksResponse();

            // A flag to determine if I want to create a new stack or update an existing one
            bool newstack = new bool();

            // The name of the stack which will be generated by the deployment process.
            string TargetStackName;

            // The fixed file name values the deployment process will require. If all three files are not present no deployment will take place.
            string DeploymentFileName = "master.template";
            string ParameterFileName  = "Parameters.txt";
            string CommitInfoFileName = "commitinfo.txt";


            // Write details of the s3 event to my logger
            s3Event = evnt.Records?[0].S3;
            context.Logger.Log("S3 Cloudformation Template Upload Event Recieved. Processing potential deployment.");
            context.Logger.Log("Bucket: " + s3Event.Bucket.Name);
            context.Logger.Log("Key: " + s3Event.Object.Key);

            // Preform a check to make sure the filename matches the standard required.
            if (s3Event.Object.Key.EndsWith(DeploymentFileName))
            {
                context.Logger.Log("S3 Event corresponds to a properly formatted master.template CloudFormation document. Commencing deployment.");
            }
            else
            {
                context.Logger.Log("S3 Event does not match deployment requirements. Candidates for deployment must contain the primary CloudFormation template in a master.template file.");
                return("Impropper filename. No deployment processed");
            }

            // Display the commitinfo from the deployment
            string CommitInfoKeyName = s3Event.Object.Key.Replace(DeploymentFileName, CommitInfoFileName);

            context.Logger.Log($"Looking for accompanying commitinfo file: {CommitInfoKeyName}");
            try
            {
                CommitInfoResponse = await S3Client.GetObjectAsync(s3Event.Bucket.Name, CommitInfoKeyName);

                using (StreamReader reader = new StreamReader(CommitInfoResponse.ResponseStream))
                {
                    string contents = reader.ReadToEnd();
                    context.Logger.Log(contents);
                }
            }
            catch (Exception e)
            {
                context.Logger.Log(e.Message);
                context.Logger.Log("No commitinfo.txt file detected. Aborting Deployment");
                return("No accompanying commitinfo.txt. No deployment Processed");
            }

            // Get and set associated parameters
            string ParameterKeyName = s3Event.Object.Key.Replace(DeploymentFileName, ParameterFileName);

            context.Logger.Log($"Looking for accompanying parameter file: {ParameterKeyName}");
            try
            {
                ParameterFileResponse = await S3Client.GetObjectAsync(s3Event.Bucket.Name, ParameterKeyName);

                StreamReader reader    = new StreamReader(ParameterFileResponse.ResponseStream);
                string       paramline = reader.ReadLine();
                context.Logger.Log("Parameter file line being processed: " + paramline);
                while (!string.IsNullOrWhiteSpace(paramline))
                {
                    string[] paramstrings = paramline.Split(':');
                    if (paramstrings.Length == 2)
                    {
                        Parameters.Add(new Parameter()
                        {
                            ParameterKey   = paramstrings[0],
                            ParameterValue = paramstrings[1]
                        });
                    }
                    paramline = reader.ReadLine();
                    context.Logger.Log("Parameter file line being processed: " + paramline);
                }
            }
            catch (Exception e)
            {
                context.Logger.Log(e.Message);
                context.Logger.Log("No parameter file detected. Aborting Deployment.");
                return("No accompanying commitinfo.txt.No deployment Processed");
            }

            // The name of the stack will be based on the folder structure containing the master.template document.
            // As an example, a template deployed to the S3 key Knect/RCC/master.template would generate the stack Knect-RCC
            TargetStackName = s3Event.Object.Key.Replace("/", "-");
            TargetStackName = TargetStackName.Replace("-" + DeploymentFileName, "");
            context.Logger.Log("Cloudformation Stack Name: " + TargetStackName);

            // Gets a presigned url for the cloudformation client so it can access the master.template document.
            PresignedKeyRequest.BucketName = s3Event.Bucket.Name;
            PresignedKeyRequest.Key        = s3Event.Object.Key;
            PresignedKeyRequest.Expires    = DateTime.Now.AddMinutes(5);
            string PresignedS3Key = S3Client.GetPreSignedURL(PresignedKeyRequest);

            // If a stack with the target name already exists I want to update it. Otherwise I want to create a new stack.
            try
            {
                CurrentStacksRequest.StackName = TargetStackName;
                CurrentStacksResponse          = await CloudformationClient.DescribeStacksAsync(CurrentStacksRequest);

                context.Logger.Log("A stack for the target name already exists. The existing stack will be updated.");

                newstack = false;
            }
            catch
            {
                context.Logger.Log("No stack with the target name exists. A new stack will be created.");

                newstack = true;
            }

            foreach (Parameter param in Parameters)
            {
                context.Logger.Log($"Parameter is set Key: {param.ParameterKey} with value {param.ParameterValue}");
            }

            // If there is an existing stack I will update it. Otherwise I will create a new stack
            if (newstack == true)
            {
                // Create a new stack
                CreateStackRequest CreateStack = new CreateStackRequest();
                CreateStack.StackName   = TargetStackName;
                CreateStack.TemplateURL = PresignedS3Key;
                CreateStack.Parameters  = Parameters;
                CreateStack.Capabilities.Add("CAPABILITY_NAMED_IAM");

                await CloudformationClient.CreateStackAsync(CreateStack);

                return("A stack creation request was successfully generated");
            }
            else
            {
                UpdateStackRequest updatereq = new UpdateStackRequest();
                updatereq.StackName   = TargetStackName;
                updatereq.TemplateURL = PresignedS3Key;
                updatereq.Parameters  = Parameters;
                updatereq.Capabilities.Add("CAPABILITY_NAMED_IAM");

                await CloudformationClient.UpdateStackAsync(updatereq);

                return("A stack update request was successfully generated");
            }
        }
        static async Task Main(string[] args)
        {
            var region    = RegionEndpoint.EUWest1;
            var sandboxId = Guid.NewGuid().ToString();

            var backendBucket = new S3.Bucket.BucketResource
            {
                LogicalId  = "BackendBucket",
                Properties =
                {
                    BucketName = $"stan-test-{sandboxId}",
                }
            };

            var runService1 = new CodeBuildRunTerraformResource
            {
                LogicalId  = "RunService1",
                DependsOn  = backendBucket.LogicalId,
                Properties = new StartCodeBuildProperties <RunTerraformRequest>
                {
                    ServiceToken = "arn:aws:lambda:eu-west-1:394351388697:function:CustomResourceSampleLambda",
                    ProjectArn   = "<service1 codebuild project arn>",
                    Environment  = new RunTerraformRequest
                    {
                        Version = "0.12.2",
                        Backend = new Backend
                        {
                            Bucket = "stan-test-{sandboxId}",
                            Key    = "Service1",
                            Region = region.SystemName
                        },
                        Vars = new Dictionary <string, string>
                        {
                            { "sandbox_id", sandboxId },
                            { "owner", "Stan" },
                            { "key_name", "" }
                        },
                        VarFile    = null,
                        FromModule = "https://github.com/stanb/terraform-samples/tree/master/aws/single-instance"
                    }
                }
            };

            //var runService2 = new StartCodeBuildResource
            //{
            //    LogicalId = "RunService2",
            //    DependsOn = runService1.LogicalId,
            //    Properties = new StartCodeBuildProperties<RunTerraform>
            //    {
            //        ServiceToken = "arn:aws:lambda:eu-west-1:394351388697:function:CustomResourceSampleLambda",
            //        ProjectArn = "<service2 codebuild project arn>",
            //        //Environment = new Dictionary<string, Union<string, Comformation.IntrinsicFunctions.IntrinsicFunction>>
            //        //{
            //        //    { "TF_VERSION", "0.12.0" },
            //        //    { "TF_SERVICE", "Service2" },
            //        //}
            //    }
            //};

            var template = new Template
            {
                Resources = new Resources
                {
                    runService1,
                    //runService2
                }
            };

            var request = new Amazon.CloudFormation.Model.CreateStackRequest
            {
                StackName    = $"test-lambda-{sandboxId}",
                TemplateBody = template.ToString(),
                Capabilities = new List <string> {
                    "CAPABILITY_NAMED_IAM"
                }
            };

            var cloudformation = new AmazonCloudFormationClient(region);
            var createResponse = await cloudformation.CreateStackAsync(request);
        }
示例#8
0
        public async Task <string> CreateDockerVM(string stackName, string json, List <Parameter> parameters, Guid credentialsId)
        {
            Guard.Against.NullOrEmpty(stackName, nameof(stackName));
            Guard.Against.JsonIsNotValid(json, nameof(json));
            Guard.Against.Null(parameters, nameof(parameters));
            Guard.Against.GuidNullOrDefault(credentialsId, nameof(credentialsId));

            var creds = await _credsRepo.GetByIdAsync(credentialsId);

            Guard.Against.Null(creds, nameof(creds));

            CreateClient(creds);

            Guard.Against.Null(_client, nameof(_client));

            var request = new CreateStackRequest
            {
                StackName    = stackName,
                TemplateBody = json,
                Parameters   = parameters,
                Capabilities = new List <string>
                {
                    "CAPABILITY_IAM",
                }
            };

            var createResponse = await _client.CreateStackAsync(request);

            if (createResponse.HttpStatusCode == System.Net.HttpStatusCode.OK)
            {
                bool hascompleted = false;
                int  maxTries     = 200;
                int  tries        = 0;

                while (hascompleted == false)
                {
                    if (maxTries == tries)
                    {
                        throw new Exception("StackStatus Checking Failed");
                    }

                    var results = await _client.DescribeStacksAsync(new DescribeStacksRequest
                    {
                        StackName = stackName
                    });

                    if (results.HttpStatusCode == System.Net.HttpStatusCode.OK)
                    {
                        var stack = results.Stacks.SingleOrDefault(c => c.StackName == stackName);
                        if (stack != null)
                        {
                            if (stack.StackStatus == StackStatus.CREATE_COMPLETE)
                            {
                                return(stack.Outputs.SingleOrDefault(c => c.OutputKey == DockerHostParameterName).OutputValue);
                            }

                            if (stack.StackStatus == StackStatus.CREATE_FAILED)
                            {
                                throw new Exception("Stack Failed Due To: " + stack.StackStatusReason);
                            }

                            if (stack.StackStatus == StackStatus.ROLLBACK_COMPLETE)
                            {
                                throw new Exception("Stack Failed Due To: " + stack.StackStatusReason);
                            }

                            await Task.Delay(10000);

                            tries++;
                        }
                    }
                }
            }

            //TODO: Add Logging
            throw new Exception("Error creating stack, HTTPStatusCode: " + createResponse.HttpStatusCode);
        }