/// <summary> /// <para> Creates a stack as specified in the template. After the call completes successfully, the stack creation starts. You can check the /// status of the stack via the DescribeStacks API. </para> <para><b>NOTE:</b> Currently, the limit for stacks is 20 stacks per account per /// region. </para> /// </summary> /// /// <param name="createStackRequest">Container for the necessary parameters to execute the CreateStack service method on /// AmazonCloudFormation.</param> /// /// <returns>The response from the CreateStack service method, as returned by AmazonCloudFormation.</returns> /// /// <exception cref="AlreadyExistsException"/> /// <exception cref="LimitExceededException"/> public CreateStackResponse CreateStack(CreateStackRequest createStackRequest) { IRequest <CreateStackRequest> request = new CreateStackRequestMarshaller().Marshall(createStackRequest); CreateStackResponse response = Invoke <CreateStackRequest, CreateStackResponse> (request, this.signer, CreateStackResponseUnmarshaller.GetInstance()); return(response); }
public static string CreateStack(this Func <IAmazonCloudFormation> clientFactory, CreateStackRequest request) { try { return(clientFactory() .Map(client => client.CreateStack(request)) // Narrow the response to the stack ID .Map(response => response.StackId)); } catch (AmazonCloudFormationException ex) { if (ex.ErrorCode == "AccessDenied") { throw new PermissionException( "AWS-CLOUDFORMATION-ERROR-0007: The AWS account used to perform the operation does not have " + "the required permissions to create the stack.\n" + ex.Message + "\n" + "For more information visit https://g.octopushq.com/AwsCloudFormationDeploy#aws-cloudformation-error-0007"); } throw new UnknownException( "AWS-CLOUDFORMATION-ERROR-0008: An unrecognised exception was thrown while creating a CloudFormation stack.\n" + "For more information visit https://g.octopushq.com/AwsCloudFormationDeploy#aws-cloudformation-error-0008", ex); } }
/// <summary> /// Initiates the asynchronous execution of the CreateStack operation. /// <seealso cref="Amazon.CloudFormation.IAmazonCloudFormation.CreateStack"/> /// </summary> /// /// <param name="request">Container for the necessary parameters to execute the CreateStack operation.</param> /// <param name="cancellationToken"> /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// </param> /// <returns>The task object representing the asynchronous operation.</returns> public Task <CreateStackResponse> CreateStackAsync(CreateStackRequest request, CancellationToken cancellationToken = default(CancellationToken)) { var marshaller = new CreateStackRequestMarshaller(); var unmarshaller = CreateStackResponseUnmarshaller.GetInstance(); return(Invoke <IRequest, CreateStackRequest, CreateStackResponse>(request, marshaller, unmarshaller, signer, cancellationToken)); }
internal CreateStackResponse CreateStack(CreateStackRequest request) { var marshaller = new CreateStackRequestMarshaller(); var unmarshaller = CreateStackResponseUnmarshaller.Instance; return(Invoke <CreateStackRequest, CreateStackResponse>(request, marshaller, unmarshaller)); }
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()); } }
/// <summary> /// Create a Stack /// <para>For detailed information, see online documentation at: "http://apidocs.cloudfoundry.org/250/stacks/create_a_stack.html"</para> /// </summary> public async Task <CreateStackResponse> CreateStack(CreateStackRequest value) { UriBuilder uriBuilder = new UriBuilder(this.Client.CloudTarget); uriBuilder.Path = "/v2/stacks"; var client = this.GetHttpClient(); client.Uri = uriBuilder.Uri; client.Method = HttpMethod.Post; var authHeader = await BuildAuthenticationHeader(); if (!string.IsNullOrWhiteSpace(authHeader.Key)) { if (client.Headers.ContainsKey(authHeader.Key)) { client.Headers[authHeader.Key] = authHeader.Value; } else { client.Headers.Add(authHeader); } } client.ContentType = "application/x-www-form-urlencoded"; client.Content = ((string)JsonConvert.SerializeObject(value)).ConvertToStream(); var expectedReturnStatus = 201; var response = await this.SendAsync(client, expectedReturnStatus); return(Utilities.DeserializeJson <CreateStackResponse>(await response.ReadContentAsStringAsync())); }
public FoundationTemplateUtil(Amazon.Runtime.AWSCredentials credentials) { //IAmazonCloudFormation stackbuilder = new AmazonCloudFormationClient(credentials); IAmazonCloudFormation stackbuilder = new AmazonCloudFormationClient(); AmazonCloudFormationRequest request = new DescribeStacksRequest(); var response = stackbuilder.DescribeStacks(new DescribeStacksRequest()); foreach (var stack in response.Stacks) { Console.WriteLine("Stack: {0}", stack.StackName); Console.WriteLine(" Status: {0}", stack.StackStatus); Console.WriteLine(" Created: {0}", stack.CreationTime); var ps = stack.Parameters; if (ps.Any()) { Console.WriteLine(" Parameters:"); foreach (var p in ps) { Console.WriteLine(" {0} = {1}", p.ParameterKey, p.ParameterValue); } } } //AWSRegion euWest1 = AWSRegion.SetRegionFromName(RegionEndpoint.EUWest1); Console.WriteLine("==========================================="); Console.WriteLine("Getting Started with AWS CloudFormation"); Console.WriteLine("===========================================\n"); String stackName = "CloudFormationSampleStack"; String logicalResourceName = "SampleNotificationTopic"; //C:\Bitbucket\Analytics\MetaDataStore\F2B\main-bastion-json.template\main-bastion-json.template try { // Create a stack CreateStackRequest createRequest = new CreateStackRequest(); createRequest.StackName = stackName; //createRequest.StackPolicyBody = ; //createRequest. //Clou //createRequest.StackPolicyBody = convertStreamToString(CloudFormationSample.class.getResourceAsStream("CloudFormationSample.template")); //Console.WriteLine("Creating a stack called " + createRequest.getStackName() + "."); //stackbuilder.createStack(createRequest); //// Wait for stack to be created //// Note that you could use SNS notifications on the CreateStack call to track the progress of the stack creation //Console.WriteLine("Stack creation completed, the stack " + stackName + " completed with " + waitForCompletion(stackbuilder, stackName); } catch { } }
public static CreateStackResponse CreateStack(string templateUri, string awsCredentialsAccessKey, string awsCredentialsSecretKey) { AmazonCloudFormationClient client = new AmazonCloudFormationClient(RegionEndpoint.USEast1); CreateStackRequest request = new CreateStackRequest { DisableRollback = true, TemplateURL = templateUri, StackName = new Uri(templateUri).Segments[new Uri(templateUri).Segments.Length - 1].Replace(".template", string.Empty).Replace('.', '-'), }; request.Capabilities.Add("CAPABILITY_IAM"); try { var response = client.CreateStack(request); if (response.HttpStatusCode < HttpStatusCode.OK || response.HttpStatusCode >= HttpStatusCode.MultipleChoices) { throw new Exception(response.ToString()); } return(response); } catch (Amazon.Runtime.Internal.HttpErrorResponseException ex) { throw new Exception(ex.Message); } }
/// <summary> /// Initiates the asynchronous execution of the CreateStack operation. /// </summary> /// /// <param name="request">Container for the necessary parameters to execute the CreateStack operation.</param> /// <param name="cancellationToken"> /// A cancellation token that can be used by other objects or threads to receive notice of cancellation. /// </param> /// <returns>The task object representing the asynchronous operation.</returns> public Task <CreateStackResponse> CreateStackAsync(CreateStackRequest request, System.Threading.CancellationToken cancellationToken = default(CancellationToken)) { var marshaller = new CreateStackRequestMarshaller(); var unmarshaller = CreateStackResponseUnmarshaller.Instance; return(InvokeAsync <CreateStackRequest, CreateStackResponse>(request, marshaller, unmarshaller, cancellationToken)); }
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 async Task TestCreateStack() { string stackName = "test-stack-" + DateTime.Now.Ticks; try { CreateStackRequest createRequest = new CreateStackRequest { StackName = stackName, TemplateBody = TEMPLATE_TEXT }; createRequest.Parameters.Add(new Parameter { ParameterKey = "TopicName", ParameterValue = "MyTopic" + DateTime.Now.Ticks }); createRequest.Parameters.Add(new Parameter { ParameterKey = "QueueName", ParameterValue = "MyQueue" + DateTime.Now.Ticks }); await Client.CreateStackAsync(createRequest); await WaitTillStackNotInProcess(stackName); var stack = (await Client.DescribeStacksAsync(new DescribeStacksRequest { StackName = stackName })).Stacks[0]; Assert.Equal(StackStatus.CREATE_COMPLETE, stack.StackStatus); var resources = (await Client.DescribeStackResourcesAsync(new DescribeStackResourcesRequest { StackName = stackName })).StackResources; Assert.Equal(2, resources.Count); GetTemplateSummaryResponse templateSummaryResponse = await Client.GetTemplateSummaryAsync(new GetTemplateSummaryRequest { StackName = stackName }); VerifyTemplateSummary(templateSummaryResponse); } finally { await WaitTillStackNotInProcess(stackName); await Client.DeleteStackAsync(new DeleteStackRequest() { StackName = stackName }); } }
static void TestParentChildTemplates() { string bucket_Name = QSS3BucketName; string templateName = QSS3KeyPrefix + TdwUtils.cfClassPathParentSubnet.Replace("tdw_cf_template\\", ""); string stack_name = templateName.Replace("-", ""); stack_name = stack_name.Replace(".template", ""); string dataPath = null; byte[] dataBytes = null; PutObjectRequest request = null; PutObjectResponse response = null; AmazonS3Client s3Client = new AmazonS3Client(); bucket_Name = TdwUtils.CreateBucket(s3Client, QSS3BucketName); GetObjectRequest getObjectRequest = new GetObjectRequest { BucketName = bucket_Name, Key = templateName, }; string data = null; using (GetObjectResponse getObjectResponse = s3Client.GetObject(getObjectRequest)) { using (var stream = getObjectResponse.ResponseStream) using (var reader = new StreamReader(stream)) { data = reader.ReadToEnd(); } } Amazon.CloudFormation.AmazonCloudFormationClient cfClient = new AmazonCloudFormationClient(); try { DeleteStackRequest deleteRequest = new DeleteStackRequest() { StackName = stack_name }; cfClient.DeleteStack(deleteRequest); } catch (Exception ex) { ex = null; } List <string> CfCapabilities = new List <string>(); CfCapabilities.Add("CAPABILITY_IAM"); CreateStackRequest stackRequest = new CreateStackRequest() { StackName = stack_name, TemplateBody = data, Capabilities = CfCapabilities }; CreateStackResponse stackResponse = cfClient.CreateStack(stackRequest); }
public static async Task CreateQueuesForEndpoint(string endpointName, string templatePath, TimeSpan?maxTimeToLive = null, string queueNamePrefix = null, bool includeRetries = false, string delayedDeliveryMethod = "Native") { using (var client = ClientFactory.CreateCloudFormationClient()) { var endpointNameWithPrefix = QueueNameHelper.GetSqsQueueName(endpointName, queueNamePrefix); var request = new CreateStackRequest { StackName = endpointNameWithPrefix, Parameters = new List <Parameter> { new Parameter { ParameterKey = "EndpointName", ParameterValue = endpointNameWithPrefix }, new Parameter { ParameterKey = "MaxTimeToLive", ParameterValue = Convert.ToInt32((maxTimeToLive ?? QueueCreationUtils.DefaultTimeToLive).TotalSeconds).ToString() }, new Parameter { ParameterKey = "IncludeRetries", ParameterValue = includeRetries.ToString() }, new Parameter { ParameterKey = "DelayedDeliveryMethod", ParameterValue = delayedDeliveryMethod }, }, TemplateBody = CloudFormationHelper.ConvertToValidJson(templatePath) }; await client.CreateStackAsync(request) .ConfigureAwait(false); var describeRequest = new DescribeStacksRequest { StackName = endpointNameWithPrefix }; StackStatus currentStatus = string.Empty; while (currentStatus != StackStatus.CREATE_COMPLETE) { var response = await client.DescribeStacksAsync(describeRequest) .ConfigureAwait(false); var stack = response.Stacks.SingleOrDefault(); currentStatus = stack?.StackStatus; await Task.Delay(1000); } } }
public void TestCreateStackRequest() { string json = @"{""name"":""example_stack"",""description"":""Description for the example stack""}"; CreateStackRequest request = new CreateStackRequest(); request.Name = "example_stack"; request.Description = "Description for the example stack"; string result = JsonConvert.SerializeObject(request, Formatting.None); Assert.AreEqual(TestUtil.ToUnformatedJsonString(json), result); }
/// <summary> /// <para>Creates a stack as specified in the template. After the call completes successfully, the stack creation starts. You can check the /// status of the stack via the DescribeStacks API.</para> <para><b>NOTE:</b> Currently, the limit for stacks is 20 stacks per account per /// region. </para> /// </summary> /// /// <param name="request">Container for the necessary parameters to execute the CreateStack service method on /// AmazonCloudFormation.</param> /// /// <returns>The response from the CreateStack service method, as returned by AmazonCloudFormation.</returns> /// /// <exception cref="T:Amazon.CloudFormation.Model.AlreadyExistsException" /> /// <exception cref="T:Amazon.CloudFormation.Model.LimitExceededException" /> /// <exception cref="T:Amazon.CloudFormation.Model.InsufficientCapabilitiesException" /> public CreateStackResponse CreateStack(CreateStackRequest request) { var task = CreateStackAsync(request); try { return(task.Result); } catch (AggregateException e) { ExceptionDispatchInfo.Capture(e.InnerException).Throw(); return(null); } }
/// <summary> /// 本接口(CreateStack)用于通过传递一个COS的terraform zip模版URL来创建一个资源栈。创建资源栈后仍需要用户调用对应的plan, apply, destory执行对应的事件。 /// </summary> /// <param name="req"><see cref="CreateStackRequest"/></param> /// <returns><see cref="CreateStackResponse"/></returns> public CreateStackResponse CreateStackSync(CreateStackRequest req) { JsonResponseModel <CreateStackResponse> rsp = null; try { var strResp = this.InternalRequestSync(req, "CreateStack"); rsp = JsonConvert.DeserializeObject <JsonResponseModel <CreateStackResponse> >(strResp); } catch (JsonSerializationException e) { throw new TencentCloudSDKException(e.Message); } return(rsp.Response); }
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 void TestCreateStack() { string stackName = "test-stack-" + DateTime.Now.Ticks; try { CreateStackRequest createRequest = new CreateStackRequest { StackName = stackName, TemplateBody = TEMPLATE_TEXT }; createRequest.Parameters.Add(new Parameter { ParameterKey = "TopicName", ParameterValue = "MyTopic" + DateTime.Now.Ticks }); createRequest.Parameters.Add(new Parameter { ParameterKey = "QueueName", ParameterValue = "MyQueue" + DateTime.Now.Ticks }); Client.CreateStack(createRequest); WaitTillStackNotInProcess(stackName); var stack = Client.DescribeStacks(new DescribeStacksRequest { StackName = stackName }).Stacks[0]; Assert.AreEqual(StackStatus.CREATE_COMPLETE, stack.StackStatus); var resources = Client.DescribeStackResources(new DescribeStackResourcesRequest { StackName = stackName }).StackResources; Assert.AreEqual(2, resources.Count); } finally { Client.DeleteStack(new DeleteStackRequest() { StackName = stackName }); } }
/// <summary> /// Create a Stack /// <para>For detailed information, see online documentation at: "http://apidocs.cloudfoundry.org/250/stacks/create_a_stack.html"</para> /// </summary> public async Task <CreateStackResponse> CreateStack(CreateStackRequest value) { UriBuilder uriBuilder = new UriBuilder(this.Client.CloudTarget); uriBuilder.Path = "/v2/stacks"; var client = this.GetHttpClient(); client.Uri = uriBuilder.Uri; client.Method = HttpMethod.Post; client.Content = ((string)JsonConvert.SerializeObject(value)).ConvertToStream(); var expectedReturnStatus = 201; var response = await this.SendAsync(client, expectedReturnStatus); return(Utilities.DeserializeJson <CreateStackResponse>(await response.Content.ReadAsStringAsync())); }
public static async Task <string> CreateStackAsync(this Func <IAmazonCloudFormation> clientFactory, CreateStackRequest request) { try { var response = await clientFactory().CreateStackAsync(request); return(response.StackId); } catch (AmazonCloudFormationException ex) when(ex.ErrorCode == "AccessDenied") { throw new PermissionException( "The AWS account used to perform the operation does not have the required permissions to create the stack.\n" + "Please ensure the current account has permission to perform action 'cloudformation:CreateStack'.\n" + ex.Message ); } }
public static async Task CreateQueue(string queueName, string templatePath, TimeSpan?maxTimeToLive = null, string queueNamePrefix = null) { using (var client = ClientFactory.CreateCloudFormationClient()) { var sqsQueueName = QueueNameHelper.GetSqsQueueName(queueName, queueNamePrefix); var request = new CreateStackRequest { StackName = sqsQueueName, Parameters = new List <Parameter> { new Parameter { ParameterKey = "QueueName", ParameterValue = sqsQueueName }, new Parameter { ParameterKey = "MaxTimeToLive", ParameterValue = Convert.ToInt32((maxTimeToLive ?? DefaultTimeToLive).TotalSeconds).ToString() } }, TemplateBody = CloudFormationHelper.ConvertToValidJson(templatePath) }; await client.CreateStackAsync(request) .ConfigureAwait(false); var describeRequest = new DescribeStacksRequest { StackName = sqsQueueName }; StackStatus currentStatus = string.Empty; while (currentStatus != StackStatus.CREATE_COMPLETE) { var response = await client.DescribeStacksAsync(describeRequest) .ConfigureAwait(false); var stack = response.Stacks.SingleOrDefault(); currentStatus = stack?.StackStatus; await Task.Delay(1000); } } }
public void CreateStack(string stackName, string configurationTemplate) { var key = string.Format("{0}-{1}", stackName, Guid.NewGuid()); // The configuration template is trimmed of the trailing slash because the slash is necessary // creating a lifecycle rule (which was actually the purpose of the convention in the first place) // but will result in a blank-named folder when uploading a file to AWS. var prefixedBucket = string.Format("{0}/{1}", _bucket, Conventions.ConfigurationTemplateBucketPrefix.TrimEnd(new [] { '/' })); var url = _storageService.UploadFile(prefixedBucket, key, Encoding.UTF8.GetBytes(configurationTemplate)); var request = new CreateStackRequest { StackName = stackName, TemplateURL = url, DisableRollback = true }; _cloudFormationClient.CreateStack(request); }
protected override void ProcessRecord() { base.ProcessRecord(); CreateStackRequest request; try { request = new CreateStackRequest { CreateStackDetails = CreateStackDetails, OpcRequestId = OpcRequestId, OpcRetryToken = OpcRetryToken }; response = client.CreateStack(request).GetAwaiter().GetResult(); WriteOutput(response, response.Stack); FinishProcessing(response); } catch (Exception ex) { TerminatingErrorDuringExecution(ex); } }
public void CreateStackTest() { using (ShimsContext.Create()) { MockClients clients = new MockClients(); string json = @"{ ""metadata"": { ""guid"": ""b53cfbc1-88ef-4bf5-8279-f85b999f60d8"", ""url"": ""/v2/stacks/e29a62e8-55ac-4af6-bfcf-9d8b174f7ceb"", ""created_at"": ""2016-09-02T11:52:26Z"", ""updated_at"": null }, ""entity"": { ""name"": ""example_stack"", ""description"": ""Description for the example stack"" } }"; clients.JsonResponse = json; clients.ExpectedStatusCode = (HttpStatusCode)201; var cfClient = clients.CreateCloudFoundryClient(); CreateStackRequest value = new CreateStackRequest(); var obj = cfClient.Stacks.CreateStack(value).Result; Assert.AreEqual("b53cfbc1-88ef-4bf5-8279-f85b999f60d8", TestUtil.ToTestableString(obj.EntityMetadata.Guid), true); Assert.AreEqual("/v2/stacks/e29a62e8-55ac-4af6-bfcf-9d8b174f7ceb", TestUtil.ToTestableString(obj.EntityMetadata.Url), true); Assert.AreEqual("2016-09-02T11:52:26Z", TestUtil.ToTestableString(obj.EntityMetadata.CreatedAt), true); Assert.AreEqual("", TestUtil.ToTestableString(obj.EntityMetadata.UpdatedAt), true); Assert.AreEqual("example_stack", TestUtil.ToTestableString(obj.Name), true); Assert.AreEqual("Description for the example stack", TestUtil.ToTestableString(obj.Description), true); } }
//--- Methods --- public async Task <bool> Deploy(Module module, string template, bool allowDataLoss, bool protectStack) { var stackName = $"{module.Settings.Tier}-{module.Name}"; Console.WriteLine($"Deploying stack: {stackName}"); // upload function packages var transferUtility = new TransferUtility(module.Settings.S3Client); foreach (var function in module.Functions) { await UploadPackage( module.Settings.DeploymentBucketName, function.PackageS3Key, function.Package, "Lambda function" ); } // upload data packages (NOTE: packages are cannot be nested, so just enumerate the top level parameters) foreach (var package in module.Parameters.OfType <PackageParameter>()) { await UploadPackage( module.Settings.DeploymentBucketName, package.PackageS3Key, package.Package, "package" ); } // check if cloudformation stack already exists string mostRecentStackEventId = null; try { var response = await module.Settings.CfClient.DescribeStackEventsAsync(new DescribeStackEventsRequest { StackName = stackName }); var mostRecentStackEvent = response.StackEvents.First(); // make sure the stack is not already in an update operation if (!IsFinalStackEvent(mostRecentStackEvent)) { module.Settings.AddError("stack appears to be undergoing an update operation"); return(false); } mostRecentStackEventId = mostRecentStackEvent.EventId; } catch (AmazonCloudFormationException) { } // set optional notification topics for cloudformation operations var notificationArns = new List <string>(); if (module.Settings.NotificationTopicArn != null) { notificationArns.Add(module.Settings.NotificationTopicArn); } // upload cloudformation template string templateUrl = null; if (module.Settings.DeploymentBucketName != null) { var templateFile = Path.GetTempFileName(); var templateSuffix = module.Settings.GitSha ?? ("UTC" + DateTime.UtcNow.ToString("yyyyMMddhhmmss")); var templateS3Key = $"{module.Name}/cloudformation-{templateSuffix}.json"; templateUrl = $"https://s3.amazonaws.com/{module.Settings.DeploymentBucketName}/{templateS3Key}"; try { Console.WriteLine($"=> Uploading CloudFormation template: s3://{module.Settings.DeploymentBucketName}/{templateS3Key}"); File.WriteAllText(templateFile, template); await transferUtility.UploadAsync(templateFile, module.Settings.DeploymentBucketName, templateS3Key); } finally { try { File.Delete(templateFile); } catch { } } } // default stack policy denies all updates var stackPolicyBody = @"{ ""Statement"": [{ ""Effect"": ""Allow"", ""Action"": ""Update:*"", ""Principal"": ""*"", ""Resource"": ""*"" }, { ""Effect"": ""Deny"", ""Action"": [ ""Update:Replace"", ""Update:Delete"" ], ""Principal"": ""*"", ""Resource"": ""*"", ""Condition"": { ""StringEquals"": { ""ResourceType"": [ ""AWS::ApiGateway::RestApi"", ""AWS::AppSync::GraphQLApi"", ""AWS::DynamoDB::Table"", ""AWS::EC2::Instance"", ""AWS::EMR::Cluster"", ""AWS::Kinesis::Stream"", ""AWS::KinesisFirehose::DeliveryStream"", ""AWS::KMS::Key"", ""AWS::Neptune::DBCluster"", ""AWS::Neptune::DBInstance"", ""AWS::RDS::DBInstance"", ""AWS::Redshift::Cluster"", ""AWS::S3::Bucket"" ] } } }] }"; var stackDuringUpdatePolicyBody = @"{ ""Statement"": [{ ""Effect"": ""Allow"", ""Action"": ""Update:*"", ""Principal"": ""*"", ""Resource"": ""*"" }] }"; // create/update cloudformation stack var success = false; if (mostRecentStackEventId != null) { try { Console.WriteLine($"=> Stack update initiated"); var request = new UpdateStackRequest { StackName = stackName, Capabilities = new List <string> { "CAPABILITY_NAMED_IAM" }, NotificationARNs = notificationArns, StackPolicyBody = stackPolicyBody, StackPolicyDuringUpdateBody = allowDataLoss ? stackDuringUpdatePolicyBody : null, TemplateURL = templateUrl, TemplateBody = (templateUrl == null) ? template : null }; var response = await module.Settings.CfClient.UpdateStackAsync(request); var outcome = await TrackStackUpdate(module, response.StackId, mostRecentStackEventId); if (outcome.Success) { Console.WriteLine($"=> Stack update finished (finished: {DateTime.Now:yyyy-MM-dd HH:mm:ss})"); ShowStackResult(outcome.Stack); success = true; } else { Console.WriteLine($"=> Stack update FAILED (finished: {DateTime.Now:yyyy-MM-dd HH:mm:ss})"); } } catch (AmazonCloudFormationException e) when(e.Message == "No updates are to be performed.") { // this error is thrown when no required updates where found Console.WriteLine($"=> No stack update required (finished: {DateTime.Now:yyyy-MM-dd HH:mm:ss})"); success = true; } } else { Console.WriteLine($"=> Stack creation initiated"); var request = new CreateStackRequest { StackName = stackName, Capabilities = new List <string> { "CAPABILITY_NAMED_IAM" }, OnFailure = OnFailure.DELETE, NotificationARNs = notificationArns, StackPolicyBody = stackPolicyBody, EnableTerminationProtection = protectStack, TemplateURL = templateUrl, TemplateBody = (templateUrl == null) ? template : null }; var response = await module.Settings.CfClient.CreateStackAsync(request); var outcome = await TrackStackUpdate(module, response.StackId, mostRecentStackEventId); if (outcome.Success) { Console.WriteLine($"=> Stack creation finished (finished: {DateTime.Now:yyyy-MM-dd HH:mm:ss})"); ShowStackResult(outcome.Stack); success = true; } else { Console.WriteLine($"=> Stack creation FAILED (finished: {DateTime.Now:yyyy-MM-dd HH:mm:ss})"); } } return(success); // local function void ShowStackResult(Stack stack) { var outputs = stack.Outputs; if (outputs.Any()) { Console.WriteLine("Stack output values:"); foreach (var output in outputs) { Console.WriteLine($"{output.OutputKey}{(output.Description != null ? $" ({output.Description})" : "")}: {output.OutputValue}"); } } } async Task UploadPackage(string bucket, string key, string package, string description) { // check if a matching package file already exists in the bucket var found = false; try { await module.Settings.S3Client.GetObjectMetadataAsync(new GetObjectMetadataRequest { BucketName = bucket, Key = key }); found = true; } catch { } // only upload files that don't exist if (!found) { Console.WriteLine($"=> Uploading {description}: s3://{bucket}/{key} "); await transferUtility.UploadAsync(package, bucket, key); } // always delete the source zip file when there is no failure try { File.Delete(package); } catch { } } }
/// <summary> /// 创建资源栈 /// </summary> /// <param name="request">请求参数信息</param> /// <returns>请求结果信息</returns> public CreateStackResponse CreateStack(CreateStackRequest request) { return(new CreateStackExecutor().Client(this).Execute <CreateStackResponse, CreateStackResult, CreateStackRequest>(request)); }
/// <summary> /// 创建资源栈 /// </summary> /// <param name="request">请求参数信息</param> /// <returns>请求结果信息</returns> public async Task <CreateStackResponse> CreateStack(CreateStackRequest request) { return(await new CreateStackExecutor().Client(this).Execute <CreateStackResponse, CreateStackResult, CreateStackRequest>(request).ConfigureAwait(false)); }
/// <summary>Creates a new stack.</summary> /// <returns><see cref="Task"/> object so we can await task return.</returns> public async Task <CloudFormationResult> CreateStackAsync() { try { var stack = await this.stackOperations.GetStackAsync(this.stackName); if (stack != null) { throw new StackOperationException(stack, StackOperationalState.Exists); } } catch (StackOperationException e) { if (e.OperationalState != StackOperationalState.NotFound) { throw; } } var req = new CreateStackRequest { Capabilities = this.capabilities.Select(c => c.Value).ToList(), ClientRequestToken = this.clientToken, DisableRollback = this.disableRollback, EnableTerminationProtection = this.terminationProtection, NotificationARNs = this.notificationARNs, OnFailure = this.onFailure, Parameters = this.parameters.Select( p => new Parameter { ParameterKey = p.Key, ParameterValue = p.Value }).ToList(), ResourceTypes = this.resourceType != null && this.resourceType.Any() ? this.resourceType : null, RollbackConfiguration = this.rollbackConfiguration, RoleARN = this.roleArn, StackName = this.stackName, Tags = this.tags, TemplateBody = this.templateResolver.ArtifactContent, TemplateURL = this.templateResolver.ArtifactUrl }; if (this.timeoutInMinutes > 0) { req.TimeoutInMinutes = this.timeoutInMinutes; } var resolved = await new StackPolicyResolver(this.clientFactory, this.context).ResolveArtifactLocationAsync( this.context, this.stackPolicyLocation, this.stackName); req.StackPolicyBody = resolved.ArtifactBody; req.StackPolicyURL = resolved.ArtifactUrl; this.context.Logger.LogInformation($"Creating {this.GetStackNameWithDescription()}\n"); var stackId = (await this.client.CreateStackAsync(req)).StackId; if (this.followOperation) { await this.WaitStackOperationAsync(stackId, true); return(new CloudFormationResult { StackArn = stackId, StackOperationResult = StackOperationResult.StackCreated }); } return(new CloudFormationResult { StackArn = stackId, StackOperationResult = StackOperationResult.StackCreateInProgress }); }
public virtual async Task Deploy(DeployStackContext context) { var cloudformationClient = await cloudformationFactory.Create(context.RoleArn); var notificationArns = GetNotificationArns(context); var stackExists = await DoesStackExist(context, cloudformationClient); var parameters = (List <Parameter>)context.Parameters ?? new List <Parameter> { }; var capabilities = (List <string>)context.Capabilities ?? new List <string> { }; var tags = (List <Tag>)context.Tags ?? new List <Tag> { }; if (!stackExists) { var createStackRequest = new CreateStackRequest { StackName = context.StackName, TemplateBody = context.Template, Parameters = parameters, Capabilities = capabilities, Tags = tags, NotificationARNs = notificationArns, RoleARN = context.PassRoleArn, ClientRequestToken = context.ClientRequestToken, OnFailure = DELETE }; var createStackResponse = await cloudformationClient.CreateStackAsync(createStackRequest); logger.LogInformation($"Got create stack response: {Serialize(createStackResponse)}"); } else { var updateStackRequest = new UpdateStackRequest { StackName = context.StackName, TemplateBody = context.Template, Parameters = parameters, Capabilities = capabilities, Tags = tags, NotificationARNs = notificationArns, ClientRequestToken = context.ClientRequestToken, RoleARN = context.PassRoleArn }; try { var updateStackResponse = await cloudformationClient.UpdateStackAsync(updateStackRequest); logger.LogInformation($"Got update stack response: {Serialize(updateStackResponse)}"); } catch (Exception e) { if (e.Message == "No updates are to be performed.") { throw new NoUpdatesException(e.Message); } else { throw e; } } } }
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"); } }