static Snapshot CreateSnapshot(string VolumeID, string name) { AmazonEC2 ec2 = GetEC2Client(); var request = new CreateSnapshotRequest() .WithVolumeId(VolumeID) .WithDescription(name); var response = ec2.CreateSnapshot(request); var snapshot = response.CreateSnapshotResult.Snapshot; ec2.CreateTags(new CreateTagsRequest() .WithResourceId(snapshot.SnapshotId) .WithTag(new Tag { Key = "Name", Value = name }) .WithTag(new Tag { Key = "BackupDate", Value = DateTime.Today.ToShortDateString() })); while (CheckSnapshotCompletion(snapshot.SnapshotId) == false) { System.Threading.Thread.Sleep(5000); Console.WriteLine("Checking Status"); } return(snapshot); }
/// <summary> /// This method will look up the current VPC NAT ami in the region and create an instance in the subnet specified. /// </summary> /// <param name="ec2Client">The ec2client used to create the NAT instance</param> /// <param name="request">The properties used to launch the NAT instance.</param> /// <returns></returns> public static RunningInstance LaunchNATInstance(AmazonEC2 ec2Client, LaunchNATInstanceRequest request) { if (ec2Client == null) { throw new ArgumentNullException("ec2Client"); } if (request == null) { throw new ArgumentNullException("request"); } if (string.IsNullOrEmpty(request.SubnetId)) { throw new ArgumentNullException("request.SubnetId"); } if (string.IsNullOrEmpty(request.InstanceType)) { throw new ArgumentNullException("request.InstanceType"); } List <Filter> filters = new List <Filter>() { new Filter() { Name = "architecture", Value = new List <string>() { "x86_64" } }, new Filter() { Name = "name", Value = new List <string>() { "ami-vpc-nat-*.x86_64-ebs" } } }; DescribeImagesResponse imageResponse = ec2Client.DescribeImages(new DescribeImagesRequest() { Filter = filters }); var image = ImageUtilities.FindImage(ec2Client, ImageUtilities.VPC_NAT); if (image == null) { throw new AmazonEC2Exception("No NAT image found in this region"); } RunInstancesRequest runRequest = new RunInstancesRequest() { InstanceType = request.InstanceType, KeyName = request.KeyName, ImageId = image.ImageId, MinCount = 1, MaxCount = 1, SubnetId = request.SubnetId }; RunInstancesResponse runResponse = ec2Client.RunInstances(runRequest); string instanceId = runResponse.RunInstancesResult.Reservation.RunningInstance[0].InstanceId; // Can't associated elastic IP address until the instance is available WaitForInstanceToStartUp(ec2Client, instanceId); ModifyInstanceAttributeRequest modifyRequest = new ModifyInstanceAttributeRequest() { InstanceId = instanceId, Attribute = "sourceDestCheck", Value = "false" }; ec2Client.ModifyInstanceAttribute(modifyRequest); ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List <string>() { instanceId }, Tag = new List <Tag>() { new Tag() { Key = "Name", Value = "NAT" } } }); var allocationId = ec2Client.AllocateAddress(new AllocateAddressRequest() { Domain = "vpc" }).AllocateAddressResult.AllocationId; ec2Client.AssociateAddress(new AssociateAddressRequest() { InstanceId = instanceId, AllocationId = allocationId }); var instance = ec2Client.DescribeInstances(new DescribeInstancesRequest() { InstanceId = new List <string>() { instanceId } }).DescribeInstancesResult.Reservation[0].RunningInstance[0]; return(instance); }
/// <summary> /// This method will create a VPC, a public subnet, private subnet and a NAT EC2 instance to allow EC2 instances in the private /// subnet to establish outbound connections to the internet. /// </summary> /// <param name="ec2Client">The ec2client used to create the VPC</param> /// <param name="request">The properties used to create the VPC.</param> /// <returns>The response contains all the VPC objects that were created.</returns> public static LaunchVPCWithPublicAndPrivateSubnetsResponse LaunchVPCWithPublicAndPrivateSubnets(AmazonEC2 ec2Client, LaunchVPCWithPublicAndPrivateSubnetsRequest request) { LaunchVPCWithPublicAndPrivateSubnetsResponse response = new LaunchVPCWithPublicAndPrivateSubnetsResponse(); LaunchVPCWithPublicSubnet(ec2Client, request, response); response.PrivateSubnet = ec2Client.CreateSubnet(new CreateSubnetRequest() { AvailabilityZone = request.PrivateSubnetAvailabilityZone ?? response.PublicSubnet.AvailabilityZone, CidrBlock = request.PrivateSubnetCiderBlock, VpcId = response.VPC.VpcId }).CreateSubnetResult.Subnet; WriteProgress(request.ProgressCallback, "Created private subnet {0}", response.PublicSubnet.SubnetId); WaitTillTrue(((Func <bool>)(() => (ec2Client.DescribeSubnets(new DescribeSubnetsRequest() { SubnetId = new List <string>() { response.PrivateSubnet.SubnetId } }).DescribeSubnetsResult.Subnet.Count == 1)))); ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List <string>() { response.PrivateSubnet.SubnetId }, Tag = new List <Tag>() { new Tag() { Key = "Name", Value = "Private" } } }); WriteProgress(request.ProgressCallback, "Launching NAT instance"); response.NATInstance = LaunchNATInstance(ec2Client, new LaunchNATInstanceRequest() { InstanceType = request.InstanceType, KeyName = request.KeyName, SubnetId = response.PublicSubnet.SubnetId }); WriteProgress(request.ProgressCallback, "NAT instance is available"); var defaultRouteTable = GetDefaultRouteTable(ec2Client, response.VPC.VpcId); if (defaultRouteTable == null) { throw new AmazonEC2Exception("No default route table found for VPC"); } ec2Client.CreateRoute(new CreateRouteRequest() { RouteTableId = defaultRouteTable.RouteTableId, DestinationCidrBlock = "0.0.0.0/0", InstanceId = response.NATInstance.InstanceId }); WriteProgress(request.ProgressCallback, "Added route to the NAT instance in the default route table"); if (request.ConfigureDefaultVPCGroupForNAT) { var defaultSecurityGroup = GetDefaultSecurityGroup(ec2Client, response.VPC.VpcId); var groupId = ec2Client.CreateSecurityGroup(new CreateSecurityGroupRequest() { VpcId = response.VPC.VpcId, GroupName = "NATGroup", GroupDescription = "Give EC2 Instances access through the NAT" }).CreateSecurityGroupResult.GroupId; WriteProgress(request.ProgressCallback, "Created security group for NAT configuration"); IpPermissionSpecification spec = new IpPermissionSpecification() { IpProtocol = "-1", IpRanges = new List <string>() { "0.0.0.0/0" }, Groups = new List <UserIdGroupPair>() { new UserIdGroupPair() { GroupId = groupId } } }; ec2Client.AuthorizeSecurityGroupIngress(new AuthorizeSecurityGroupIngressRequest() { IpPermissions = new List <IpPermissionSpecification>() { spec }, GroupId = defaultSecurityGroup.GroupId }); WriteProgress(request.ProgressCallback, "Added permission to the default security group {0} to allow traffic from security group {1}", defaultSecurityGroup.GroupId, groupId); response.NATSecurityGroup = ec2Client.DescribeSecurityGroups(new DescribeSecurityGroupsRequest() { GroupId = new List <string>() { groupId } }).DescribeSecurityGroupsResult.SecurityGroup[0]; } return(response); }
/// <summary> /// This method will create a VPC with a subnet that will have an internet gateway attached making instances available to the internet. /// </summary> /// <param name="ec2Client">The ec2client used to create the VPC</param> /// <param name="request">The properties used to create the VPC.</param> /// <param name="response">The response contains all the VPC objects that were created.</param> private static void LaunchVPCWithPublicSubnet(AmazonEC2 ec2Client, LaunchVPCWithPublicSubnetRequest request, LaunchVPCWithPublicSubnetResponse response) { response.VPC = ec2Client.CreateVpc(new CreateVpcRequest() { CidrBlock = request.VPCCidrBlock, InstanceTenancy = request.InstanceTenancy }).CreateVpcResult.Vpc; WriteProgress(request.ProgressCallback, "Created vpc {0}", response.VPC.VpcId); var describeVPCRequest = new DescribeVpcsRequest() { VpcId = new List <string>() { response.VPC.VpcId } }; WaitTillTrue(((Func <bool>)(() => ec2Client.DescribeVpcs(describeVPCRequest).DescribeVpcsResult.Vpc.Count == 1))); if (!string.IsNullOrEmpty(request.VPCName)) { ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List <string>() { response.VPC.VpcId }, Tag = new List <Tag>() { new Tag() { Key = "Name", Value = request.VPCName } } }); } response.PublicSubnet = ec2Client.CreateSubnet(new CreateSubnetRequest() { AvailabilityZone = request.PublicSubnetAvailabilityZone, CidrBlock = request.PublicSubnetCiderBlock, VpcId = response.VPC.VpcId }).CreateSubnetResult.Subnet; WriteProgress(request.ProgressCallback, "Created public subnet {0}", response.PublicSubnet.SubnetId); WaitTillTrue(((Func <bool>)(() => (ec2Client.DescribeSubnets(new DescribeSubnetsRequest() { SubnetId = new List <string>() { response.PublicSubnet.SubnetId } }).DescribeSubnetsResult.Subnet.Count == 1)))); ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List <string>() { response.PublicSubnet.SubnetId }, Tag = new List <Tag>() { new Tag() { Key = "Name", Value = "Public" } } }); response.InternetGateway = ec2Client.CreateInternetGateway(new CreateInternetGatewayRequest() { }).CreateInternetGatewayResult.InternetGateway; WriteProgress(request.ProgressCallback, "Created internet gateway {0}", response.InternetGateway.InternetGatewayId); ec2Client.AttachInternetGateway(new AttachInternetGatewayRequest() { InternetGatewayId = response.InternetGateway.InternetGatewayId, VpcId = response.VPC.VpcId }); WriteProgress(request.ProgressCallback, "Attached internet gateway to vpc"); response.PublicSubnetRouteTable = ec2Client.CreateRouteTable(new CreateRouteTableRequest() { VpcId = response.VPC.VpcId }).CreateRouteTableResult.RouteTable; WriteProgress(request.ProgressCallback, "Created route table {0}", response.PublicSubnetRouteTable.RouteTableId); var describeRouteTableRequest = new DescribeRouteTablesRequest() { RouteTableId = new List <string>() { response.PublicSubnetRouteTable.RouteTableId } }; WaitTillTrue(((Func <bool>)(() => (ec2Client.DescribeRouteTables(describeRouteTableRequest).DescribeRouteTablesResult.RouteTables.Count == 1)))); ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List <string>() { response.PublicSubnetRouteTable.RouteTableId }, Tag = new List <Tag>() { new Tag() { Key = "Name", Value = "Public" } } }); ec2Client.AssociateRouteTable(new AssociateRouteTableRequest() { RouteTableId = response.PublicSubnetRouteTable.RouteTableId, SubnetId = response.PublicSubnet.SubnetId }); WriteProgress(request.ProgressCallback, "Associated route table to public subnet"); ec2Client.CreateRoute(new CreateRouteRequest() { DestinationCidrBlock = "0.0.0.0/0", GatewayId = response.InternetGateway.InternetGatewayId, RouteTableId = response.PublicSubnetRouteTable.RouteTableId }); WriteProgress(request.ProgressCallback, "Added route for internet gateway to route table {0}", response.PublicSubnetRouteTable.RouteTableId); response.PublicSubnetRouteTable = ec2Client.DescribeRouteTables(describeRouteTableRequest).DescribeRouteTablesResult.RouteTables[0]; }
/// <summary> /// This method will look up the current VPC NAT ami in the region and create an instance in the subnet specified. /// </summary> /// <param name="ec2Client">The ec2client used to create the NAT instance</param> /// <param name="request">The properties used to launch the NAT instance.</param> /// <returns></returns> public static RunningInstance LaunchNATInstance(AmazonEC2 ec2Client, LaunchNATInstanceRequest request) { if (ec2Client == null) throw new ArgumentNullException("ec2Client"); if (request == null) throw new ArgumentNullException("request"); if (string.IsNullOrEmpty(request.SubnetId)) throw new ArgumentNullException("request.SubnetId"); if (string.IsNullOrEmpty(request.InstanceType)) throw new ArgumentNullException("request.InstanceType"); List<Filter> filters = new List<Filter>() { new Filter(){Name = "architecture", Value = new List<string>(){"x86_64"}}, new Filter(){Name = "name", Value = new List<string>(){"ami-vpc-nat-*.x86_64-ebs"}} }; DescribeImagesResponse imageResponse = ec2Client.DescribeImages(new DescribeImagesRequest() { Filter = filters }); var image = ImageUtilities.FindImage(ec2Client, ImageUtilities.VPC_NAT); if (image == null) { throw new AmazonEC2Exception("No NAT image found in this region"); } RunInstancesRequest runRequest = new RunInstancesRequest() { InstanceType = request.InstanceType, KeyName = request.KeyName, ImageId = image.ImageId, MinCount = 1, MaxCount = 1, SubnetId = request.SubnetId }; RunInstancesResponse runResponse = ec2Client.RunInstances(runRequest); string instanceId = runResponse.RunInstancesResult.Reservation.RunningInstance[0].InstanceId; // Can't associated elastic IP address until the instance is available WaitForInstanceToStartUp(ec2Client, instanceId); ModifyInstanceAttributeRequest modifyRequest = new ModifyInstanceAttributeRequest() { InstanceId = instanceId, Attribute = "sourceDestCheck", Value = "false" }; ec2Client.ModifyInstanceAttribute(modifyRequest); ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List<string>() { instanceId }, Tag = new List<Tag>() { new Tag() { Key = "Name", Value = "NAT" } } }); var allocationId = ec2Client.AllocateAddress(new AllocateAddressRequest() { Domain = "vpc" }).AllocateAddressResult.AllocationId; ec2Client.AssociateAddress(new AssociateAddressRequest() { InstanceId = instanceId, AllocationId = allocationId }); var instance = ec2Client.DescribeInstances(new DescribeInstancesRequest() { InstanceId = new List<string>() { instanceId } }).DescribeInstancesResult.Reservation[0].RunningInstance[0]; return instance; }
/// <summary> /// This method will create a VPC with a subnet that will have an internet gateway attached making instances available to the internet. /// </summary> /// <param name="ec2Client">The ec2client used to create the VPC</param> /// <param name="request">The properties used to create the VPC.</param> /// <param name="response">The response contains all the VPC objects that were created.</param> private static void LaunchVPCWithPublicSubnet(AmazonEC2 ec2Client, LaunchVPCWithPublicSubnetRequest request, LaunchVPCWithPublicSubnetResponse response) { response.VPC = ec2Client.CreateVpc(new CreateVpcRequest() { CidrBlock = request.VPCCidrBlock, InstanceTenancy = request.InstanceTenancy }).CreateVpcResult.Vpc; WriteProgress(request.ProgressCallback, "Created vpc {0}", response.VPC.VpcId); var describeVPCRequest = new DescribeVpcsRequest() { VpcId = new List<string>() { response.VPC.VpcId } }; WaitTillTrue(((Func<bool>)(() => ec2Client.DescribeVpcs(describeVPCRequest).DescribeVpcsResult.Vpc.Count == 1))); if(!string.IsNullOrEmpty(request.VPCName)) { ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List<string>(){ response.VPC.VpcId}, Tag = new List<Tag>(){new Tag(){Key = "Name", Value = request.VPCName}} }); } response.PublicSubnet = ec2Client.CreateSubnet(new CreateSubnetRequest() { AvailabilityZone = request.PublicSubnetAvailabilityZone, CidrBlock = request.PublicSubnetCiderBlock, VpcId = response.VPC.VpcId }).CreateSubnetResult.Subnet; WriteProgress(request.ProgressCallback, "Created public subnet {0}", response.PublicSubnet.SubnetId); WaitTillTrue(((Func<bool>)(() => (ec2Client.DescribeSubnets(new DescribeSubnetsRequest() { SubnetId = new List<string>() { response.PublicSubnet.SubnetId } }).DescribeSubnetsResult.Subnet.Count == 1)))); ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List<string>() { response.PublicSubnet.SubnetId }, Tag = new List<Tag>() { new Tag() { Key = "Name", Value = "Public" } } }); response.InternetGateway = ec2Client.CreateInternetGateway(new CreateInternetGatewayRequest() { }).CreateInternetGatewayResult.InternetGateway; WriteProgress(request.ProgressCallback, "Created internet gateway {0}", response.InternetGateway.InternetGatewayId); ec2Client.AttachInternetGateway(new AttachInternetGatewayRequest() { InternetGatewayId = response.InternetGateway.InternetGatewayId, VpcId = response.VPC.VpcId }); WriteProgress(request.ProgressCallback, "Attached internet gateway to vpc"); response.PublicSubnetRouteTable = ec2Client.CreateRouteTable(new CreateRouteTableRequest() { VpcId = response.VPC.VpcId }).CreateRouteTableResult.RouteTable; WriteProgress(request.ProgressCallback, "Created route table {0}", response.PublicSubnetRouteTable.RouteTableId); var describeRouteTableRequest = new DescribeRouteTablesRequest() { RouteTableId = new List<string>() { response.PublicSubnetRouteTable.RouteTableId } }; WaitTillTrue(((Func<bool>)(() => (ec2Client.DescribeRouteTables(describeRouteTableRequest).DescribeRouteTablesResult.RouteTables.Count == 1)))); ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List<string>() { response.PublicSubnetRouteTable.RouteTableId }, Tag = new List<Tag>() { new Tag() { Key = "Name", Value = "Public" } } }); ec2Client.AssociateRouteTable(new AssociateRouteTableRequest() { RouteTableId = response.PublicSubnetRouteTable.RouteTableId, SubnetId = response.PublicSubnet.SubnetId }); WriteProgress(request.ProgressCallback, "Associated route table to public subnet"); ec2Client.CreateRoute(new CreateRouteRequest() { DestinationCidrBlock = "0.0.0.0/0", GatewayId = response.InternetGateway.InternetGatewayId, RouteTableId = response.PublicSubnetRouteTable.RouteTableId }); WriteProgress(request.ProgressCallback, "Added route for internet gateway to route table {0}", response.PublicSubnetRouteTable.RouteTableId); response.PublicSubnetRouteTable = ec2Client.DescribeRouteTables(describeRouteTableRequest).DescribeRouteTablesResult.RouteTables[0]; }
/// <summary> /// This method will create a VPC, a public subnet, private subnet and a NAT EC2 instance to allow EC2 instances in the private /// subnet to establish outbound connections to the internet. /// </summary> /// <param name="ec2Client">The ec2client used to create the VPC</param> /// <param name="request">The properties used to create the VPC.</param> /// <returns>The response contains all the VPC objects that were created.</returns> public static LaunchVPCWithPublicAndPrivateSubnetsResponse LaunchVPCWithPublicAndPrivateSubnets(AmazonEC2 ec2Client, LaunchVPCWithPublicAndPrivateSubnetsRequest request) { LaunchVPCWithPublicAndPrivateSubnetsResponse response = new LaunchVPCWithPublicAndPrivateSubnetsResponse(); LaunchVPCWithPublicSubnet(ec2Client, request, response); response.PrivateSubnet = ec2Client.CreateSubnet(new CreateSubnetRequest() { AvailabilityZone = request.PrivateSubnetAvailabilityZone ?? response.PublicSubnet.AvailabilityZone, CidrBlock = request.PrivateSubnetCiderBlock, VpcId = response.VPC.VpcId }).CreateSubnetResult.Subnet; WriteProgress(request.ProgressCallback, "Created private subnet {0}", response.PublicSubnet.SubnetId); WaitTillTrue(((Func<bool>)(() => (ec2Client.DescribeSubnets(new DescribeSubnetsRequest(){SubnetId = new List<string>(){response.PrivateSubnet.SubnetId}}).DescribeSubnetsResult.Subnet.Count == 1)))); ec2Client.CreateTags(new CreateTagsRequest() { ResourceId = new List<string>() { response.PrivateSubnet.SubnetId }, Tag = new List<Tag>() { new Tag() { Key = "Name", Value = "Private" } } }); WriteProgress(request.ProgressCallback, "Launching NAT instance"); response.NATInstance = LaunchNATInstance(ec2Client, new LaunchNATInstanceRequest() { InstanceType = request.InstanceType, KeyName = request.KeyName, SubnetId = response.PublicSubnet.SubnetId }); WriteProgress(request.ProgressCallback, "NAT instance is available"); var defaultRouteTable = GetDefaultRouteTable(ec2Client, response.VPC.VpcId); if (defaultRouteTable == null) throw new AmazonEC2Exception("No default route table found for VPC"); ec2Client.CreateRoute(new CreateRouteRequest() { RouteTableId = defaultRouteTable.RouteTableId, DestinationCidrBlock = "0.0.0.0/0", InstanceId = response.NATInstance.InstanceId }); WriteProgress(request.ProgressCallback, "Added route to the NAT instance in the default route table"); if (request.ConfigureDefaultVPCGroupForNAT) { var defaultSecurityGroup = GetDefaultSecurityGroup(ec2Client, response.VPC.VpcId); var groupId = ec2Client.CreateSecurityGroup(new CreateSecurityGroupRequest() { VpcId = response.VPC.VpcId, GroupName = "NATGroup", GroupDescription = "Give EC2 Instances access through the NAT" }).CreateSecurityGroupResult.GroupId; WriteProgress(request.ProgressCallback, "Created security group for NAT configuration"); IpPermissionSpecification spec = new IpPermissionSpecification() { IpProtocol = "-1", IpRanges = new List<string>(){"0.0.0.0/0"}, Groups = new List<UserIdGroupPair>() { new UserIdGroupPair() { GroupId = groupId } } }; ec2Client.AuthorizeSecurityGroupIngress(new AuthorizeSecurityGroupIngressRequest() { IpPermissions = new List<IpPermissionSpecification>(){spec}, GroupId = defaultSecurityGroup.GroupId }); WriteProgress(request.ProgressCallback, "Added permission to the default security group {0} to allow traffic from security group {1}", defaultSecurityGroup.GroupId, groupId); response.NATSecurityGroup = ec2Client.DescribeSecurityGroups(new DescribeSecurityGroupsRequest() { GroupId = new List<string>(){ groupId } }).DescribeSecurityGroupsResult.SecurityGroup[0]; } return response; }
public static void Backup(string name, string description, string volumeid, string volumename, string instancename, string expires) { Console.WriteLine("Creating snapshot of " + volumeid + " / " + volumename + " / " + instancename); AmazonEC2 ec2 = Ec2Helper.CreateClient(); CreateSnapshotRequest rq = new CreateSnapshotRequest(); rq.VolumeId = volumeid; rq.Description = description; CreateSnapshotResponse rs = ec2.CreateSnapshot(rq); string snapshotid = rs.CreateSnapshotResult.Snapshot.SnapshotId; // build tags for snapshot List <Tag> tags = new List <Tag>(); tags.Add(new Tag { Key = "Name", Value = name }); tags.Add(new Tag { Key = "source", Value = "scheduler" }); tags.Add(new Tag { Key = "instance", Value = instancename }); tags.Add(new Tag { Key = "volume", Value = volumename }); tags.Add(new Tag { Key = "expires", Value = expires.ToString() }); // get tags from volume to be applied to snapshot DescribeTagsRequest trq = new DescribeTagsRequest(); trq.WithFilter(new Filter() { Name = "resource-id", Value = new List <string>() { volumeid } }); DescribeTagsResponse trs = ec2.DescribeTags(trq); foreach (ResourceTag t in trs.DescribeTagsResult.ResourceTag) { if (t.Key != "nextSnapshot" && t.Key != "lastSnapshot" && t.Key != "Name") { tags.Add(new Tag { Key = t.Key, Value = t.Value }); } } // apply tags to snapshopt CreateTagsRequest rqq = new CreateTagsRequest(); rqq.WithResourceId(snapshotid); rqq.WithTag(tags.ToArray()); var createTagResponse = ec2.CreateTags(rqq); }
/// <summary> /// Check for any volumes that have a snapshot scheduled based on the schedule in the snapshotSchedule tag key. /// </summary> public static void CheckForScheduledSnapshots() { Console.WriteLine("Checking for scheduled snapshots..."); AmazonEC2 ec2 = Ec2Helper.CreateClient(); DescribeVolumesRequest rq = new DescribeVolumesRequest(); rq.WithFilter(new Filter() { Name = "tag-key", Value = new List <string>() { "snapshotSchedule" } }); DescribeVolumesResponse rs = ec2.DescribeVolumes(rq); foreach (Volume v in rs.DescribeVolumesResult.Volume) { string[] sch2 = Ec2Helper.GetTagValue(v.Tag, "snapshotSchedule").Split(' '); string volumename = Ec2Helper.GetTagValue(v.Tag, "Name"); DateTime lastSnap; // date of last snapshot DateTime nextSnap; // the next backup that should have occured based on last backup DateTime nextNextSnap; // the next backup that should occur assuming a backup runs now or ran at the last proper time DateTime now = DateTime.UtcNow; if (!DateTime.TryParse(Ec2Helper.GetTagValue(v.Tag, "lastSnapshot"), out lastSnap)) { lastSnap = Convert.ToDateTime("1/1/2010"); } Console.WriteLine("Checking " + v.VolumeId + " / " + volumename + "..."); //sch2 = ("hourly 4 :30 x30days").Split(' '); //lastSnap = Convert.ToDateTime("2/29/2012 6:00:15pm"); //now = Convert.ToDateTime("2/29/2012 10:00:14pm"); switch (sch2[0]) { case "hourly": // hourly, hourly 1 :15, hourly :30, hourly 4 (pass it hours between backups & when on the hour to do it, any order; defaults to every hour on the hour) int ah = GetAfterTheHour(sch2, 0); int hi = GetInt(sch2, 1); nextSnap = lastSnap.AddMinutes(-lastSnap.Minute).AddSeconds(-lastSnap.Second).AddMilliseconds(-lastSnap.Millisecond); nextSnap = nextSnap.AddHours(hi).AddMinutes(ah); // this is not right nextNextSnap = now.AddMinutes(-now.Minute).AddSeconds(-now.Second).AddMilliseconds(-now.Millisecond); nextNextSnap = nextNextSnap.AddMinutes(ah).AddHours(hi); break; case "daily": // daily, 3pm, daily 15:15, daily 3:30pm (times are UTC; defaults to midnight UTC) DateTime hour = GetTime(sch2, Convert.ToDateTime("0:00")); nextSnap = lastSnap.Date.AddDays(1).AddTicks(hour.TimeOfDay.Ticks); nextNextSnap = now.Date.AddDays(1).AddTicks(hour.TimeOfDay.Ticks); break; case "weekly": // weekly, weekly sunday, weekly thursday 3pm (times are UTC; defaults to sunday midnight UTC) DateTime whour = GetTime(sch2, Convert.ToDateTime("0:00")); DayOfWeek dow = GetDow(sch2, DayOfWeek.Sunday); if (lastSnap.DayOfWeek >= dow) { nextSnap = lastSnap.Date.AddDays(-(int)lastSnap.DayOfWeek).AddDays(7 + (int)dow).AddTicks(whour.TimeOfDay.Ticks); } else { nextSnap = lastSnap.Date.AddDays(-(int)lastSnap.DayOfWeek).AddDays((int)dow).AddTicks(whour.TimeOfDay.Ticks); } nextNextSnap = now.Date.AddDays(-(int)now.DayOfWeek).AddDays(7 + (int)dow).AddTicks(whour.TimeOfDay.Ticks); if (nextSnap == nextNextSnap) { nextNextSnap = nextNextSnap.AddDays(7); } break; default: lastSnap = now.AddYears(1); nextSnap = lastSnap; nextNextSnap = lastSnap; break; } //Console.WriteLine("last=" + lastSnap.ToString()); //Console.WriteLine("now=" + now); //Console.WriteLine("next=" + nextSnap.ToString()); //Console.WriteLine("nextNext=" + nextNextSnap.ToString()); //Console.ReadKey(); //return; if (nextSnap <= now) { // create snapshot of volume string expires = ""; int expireHours = GetExpireHours(sch2, 0); if (expireHours > 0) { expires = now.AddHours(expireHours).ToString(); } Backup(volumename, "automatic", v.VolumeId, volumename, Ec2Helper.GetInstanceName(v.Attachment[0].InstanceId), expires); // update volume tags CreateTagsRequest rqq = new CreateTagsRequest(); rqq.WithResourceId(v.VolumeId); nextSnap = nextSnap.AddSeconds(-nextSnap.Second).AddMilliseconds(-nextSnap.Millisecond); rqq.WithTag(new Tag[] { new Tag { Key = "lastSnapshot", Value = now.ToString() }, new Tag { Key = "nextSnapshot", Value = nextNextSnap.ToString() } }); var createTagResponse = ec2.CreateTags(rqq); } else { Console.WriteLine(" Next scheduled " + nextSnap.ToString()); } } }