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); }
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()); } }
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); }
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; } }
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); }
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); }