cfn-bridge 0.0.9 → 0.0.10
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +50 -0
- data/lib/cloud_formation/bridge/cli.rb +4 -0
- data/lib/cloud_formation/bridge/executor.rb +10 -1
- data/lib/cloud_formation/bridge/names.rb +10 -0
- data/lib/cloud_formation/bridge/request.rb +7 -1
- data/lib/cloud_formation/bridge/resources/base.rb +14 -3
- data/lib/cloud_formation/bridge/resources/base_elasti_cache_resource.rb +58 -0
- data/lib/cloud_formation/bridge/resources/elasti_cache_node_urls.rb +35 -0
- data/lib/cloud_formation/bridge/resources/elasti_cache_replica_cluster.rb +66 -0
- data/lib/cloud_formation/bridge/resources/elasti_cache_replication_group.rb +67 -0
- data/lib/cloud_formation/bridge/util.rb +6 -0
- data/lib/cloud_formation/bridge/version.rb +1 -1
- data/spec/files/create-cache-node-urls-message.json +12 -0
- data/spec/files/create-redis-cache-node-urls-message.json +12 -0
- data/spec/files/create-replica-cluster-message.json +13 -0
- data/spec/files/create-replication-group-message.json +14 -0
- data/spec/files/delete-replica-cluster-message.json +14 -0
- data/spec/files/delete-replication-group-message.json +15 -0
- data/spec/files/describe-cache-cluster-primary.json +57 -0
- data/spec/files/describe-cache-cluster-replica-done.json +68 -0
- data/spec/files/describe-cache-cluster-replica.json +46 -0
- data/spec/files/describe-memcached-cluster.json +73 -0
- data/spec/files/describe-replication-group-primary-and-replica.json +49 -0
- data/spec/files/describe-replication-group-primary-only.json +38 -0
- data/spec/files/outputs-formation.json +0 -4
- data/spec/files/sample-replica-cluster.json +51 -0
- data/spec/files/sample-replication-group.json +34 -0
- data/spec/lib/cloud_formation/bridge/executor_spec.rb +1 -1
- data/spec/lib/cloud_formation/bridge/request_spec.rb +17 -5
- data/spec/lib/cloud_formation/bridge/resources/elasti_cache_node_urls_spec.rb +61 -0
- data/spec/lib/cloud_formation/bridge/resources/elasti_cache_replica_cluster_spec.rb +67 -0
- data/spec/lib/cloud_formation/bridge/resources/elasti_cache_replication_group_spec.rb +65 -0
- data/spec/support/file_support.rb +6 -0
- metadata +40 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 937f3058f2f853584b9d5340292cc7a9d188dea8
|
4
|
+
data.tar.gz: d5f84fe245dce34c6f46e095cb03a338c1d4c97c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4177d8b32ce517c52807ec0cff6d762a9ed4eb63ad327bd65779ece2d99af33d3fa04ac1741228b8fd8322bf371c915182c6359553cd0a9dae3313ad899adcd2
|
7
|
+
data.tar.gz: 5d0caaf158b0175de5159055a25b8bde177eec8605d82da9dbd0d90077e2d60800b3dfcbe83f776efb76a1c132e821e684700713e321aac82932bf0116f6b6dc
|
data/README.md
CHANGED
@@ -13,6 +13,9 @@
|
|
13
13
|
- [Current custom resources](#current-custom-resources)
|
14
14
|
- [Custom::SubscribeSQSQueueToSNSTopic](#customsubscribesqsqueuetosnstopic)
|
15
15
|
- [Custom::CloudFormationOutputs](#customcloudformationoutputs)
|
16
|
+
- [Custom::Custom::ElastiCacheReplicationGroup](#customcustomelasticachereplicationgroup)
|
17
|
+
- [Custom::ElastiCacheReplicaCluster](#customelasticachereplicacluster)
|
18
|
+
- [Custom::ElastiCacheNodeURLs](#customelasticachenodeurls)
|
16
19
|
- [Contributing](#contributing)
|
17
20
|
|
18
21
|
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
@@ -194,6 +197,12 @@ It is declared just like any other custom resource with the name you have regist
|
|
194
197
|
|
195
198
|
And with this you should be able to start creating your own custom cloud formation resources.
|
196
199
|
|
200
|
+
Gotchas you should be aware:
|
201
|
+
|
202
|
+
* Do not return `nil` on `Data` fields, your resource will not be created and you will not get any error message about this;
|
203
|
+
* Make sure all messages are logged somewhere (I'd recommend an email) so even if the service fails to create resources for some reason you can still work with the cloud formation manually;
|
204
|
+
* Direct your logs somewhere where you can easily look at, the command line interface will print everything to `STDOUT`, make sure you send this data to a file so you can look at what's going on;
|
205
|
+
|
197
206
|
## Current custom resources
|
198
207
|
|
199
208
|
### Custom::SubscribeSQSQueueToSNSTopic
|
@@ -214,6 +223,47 @@ Parameters:
|
|
214
223
|
|
215
224
|
* `Name` - the name of the cloud formation you want to get the outputs from - *required*;
|
216
225
|
|
226
|
+
|
227
|
+
### Custom::Custom::ElastiCacheReplicationGroup
|
228
|
+
|
229
|
+
Creates an `ElastiCache` replication group from an already available cache cluster (that will be configured as the primary).
|
230
|
+
|
231
|
+
Parameters:
|
232
|
+
|
233
|
+
* `ClusterId` - the name of the primary ElastiCache cluster for this replication group;
|
234
|
+
* `ReplicationGroupId` - the name of this replication group - this field follows the same `ElastiCache` naming requirements, 20 alphanumeric characters or `-`;
|
235
|
+
* `Description` - the group description;
|
236
|
+
|
237
|
+
Produced `Fn::GetAtt` values:
|
238
|
+
|
239
|
+
* `ReplicationGroupId` - the replication group id;
|
240
|
+
|
241
|
+
### Custom::ElastiCacheReplicaCluster
|
242
|
+
|
243
|
+
Creates an `ElastiCache` replica cluster for an already existing replication group.
|
244
|
+
|
245
|
+
Parameters:
|
246
|
+
|
247
|
+
* `ReplicationGroupId` - the id of the replication group where this replica cluster will register itself;
|
248
|
+
* `ReplicaClusterId` - the id for this replication group;
|
249
|
+
|
250
|
+
Produced `Fn::GetAtt` values:
|
251
|
+
|
252
|
+
* `ReplicaClusterId` - the id of this replica cluster;
|
253
|
+
* `NodeURLs` - list of `host:port` values (separated by `,`) for the nodes in the cluster if it is a redis cluster or the configuration URL for a memcached cluster;
|
254
|
+
|
255
|
+
### Custom::ElastiCacheNodeURLs
|
256
|
+
|
257
|
+
Produces pairs of `host:port` separated by `,` for all nodes in the cluster if it's a Redis cluster or the configuration `host:port` if it is a Memcached cluster.
|
258
|
+
|
259
|
+
Parameters:
|
260
|
+
|
261
|
+
* `ClusterId` - the name of the primary ElastiCache cluster for this replication group;
|
262
|
+
|
263
|
+
Produced `Fn::GetAtt` values:
|
264
|
+
|
265
|
+
* `NodeURLs` - list of `host:port` values (separated by `,`) for the nodes in the cluster if it is a Redis cluster or the configuration `host:port` for a Memcached cluster;
|
266
|
+
|
217
267
|
## Contributing
|
218
268
|
|
219
269
|
1. [Fork it](https://github.com/TheNeatCompany/cfn-bridge/fork)
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'thor'
|
2
2
|
require 'cloud_formation/bridge/poller'
|
3
3
|
require 'cloud_formation/bridge/util'
|
4
|
+
require 'cloud_formation/bridge/version'
|
4
5
|
|
5
6
|
module CloudFormation
|
6
7
|
module Bridge
|
@@ -9,6 +10,9 @@ module CloudFormation
|
|
9
10
|
desc "start QUEUE_NAME", "Starts watching this specific SQS queue"
|
10
11
|
def start(queue_name)
|
11
12
|
STDOUT.sync = true
|
13
|
+
|
14
|
+
Util::LOGGER.info("Starting cfn-bridge with queue #{queue_name} - version #{CloudFormation::Bridge::VERSION}")
|
15
|
+
|
12
16
|
poller = CloudFormation::Bridge::Poller.new(queue_name)
|
13
17
|
poller.start
|
14
18
|
end
|
@@ -2,6 +2,9 @@ require 'cloud_formation/bridge/exception_notifier'
|
|
2
2
|
require 'cloud_formation/bridge/names'
|
3
3
|
require 'cloud_formation/bridge/resources/subscribe_queue_to_topic'
|
4
4
|
require 'cloud_formation/bridge/resources/cloud_formation_outputs'
|
5
|
+
require 'cloud_formation/bridge/resources/elasti_cache_replication_group'
|
6
|
+
require 'cloud_formation/bridge/resources/elasti_cache_replica_cluster'
|
7
|
+
require 'cloud_formation/bridge/resources/elasti_cache_node_urls'
|
5
8
|
|
6
9
|
module CloudFormation
|
7
10
|
module Bridge
|
@@ -14,6 +17,12 @@ module CloudFormation
|
|
14
17
|
CloudFormation::Bridge::Resources::SubscribeQueueToTopic.new,
|
15
18
|
"Custom::CloudFormationOutputs" =>
|
16
19
|
CloudFormation::Bridge::Resources::CloudFormationOutputs.new,
|
20
|
+
"Custom::ElastiCacheReplicationGroup" =>
|
21
|
+
CloudFormation::Bridge::Resources::ElastiCacheReplicationGroup.new,
|
22
|
+
"Custom::ElastiCacheReplicaCluster" =>
|
23
|
+
CloudFormation::Bridge::Resources::ElastiCacheReplicaCluster.new,
|
24
|
+
"Custom::ElastiCacheNodeURLs" =>
|
25
|
+
CloudFormation::Bridge::Resources::ElastiCacheNodeUrls.new,
|
17
26
|
}
|
18
27
|
|
19
28
|
attr_reader :registry
|
@@ -40,7 +49,7 @@ module CloudFormation
|
|
40
49
|
end
|
41
50
|
rescue Exception => ex
|
42
51
|
ExceptionNotifier.report_exception(ex, request.request)
|
43
|
-
request.fail!(ex.message)
|
52
|
+
request.fail!("#{ex.class.name} - #{ex.message}")
|
44
53
|
end
|
45
54
|
|
46
55
|
end
|
@@ -29,6 +29,16 @@ module CloudFormation
|
|
29
29
|
DATA = 'Data'
|
30
30
|
end
|
31
31
|
|
32
|
+
module ELASTI_CACHE
|
33
|
+
AVAILABLE = 'available'
|
34
|
+
CLUSTER_ID = 'ClusterId'
|
35
|
+
REPLICA_CLUSTER_ID = 'ReplicaClusterId'
|
36
|
+
DESCRIPTION = 'Description'
|
37
|
+
NODE_URLS = 'NodeURLs'
|
38
|
+
REPLICA = 'replica'
|
39
|
+
REPLICATION_GROUP_ID = 'ReplicationGroupId'
|
40
|
+
end
|
41
|
+
|
32
42
|
end
|
33
43
|
end
|
34
44
|
end
|
@@ -74,7 +74,13 @@ module CloudFormation
|
|
74
74
|
end
|
75
75
|
|
76
76
|
def succeed!(response)
|
77
|
-
actual_response =
|
77
|
+
actual_response = case response
|
78
|
+
when Hash
|
79
|
+
build_response(response)
|
80
|
+
else
|
81
|
+
build_response
|
82
|
+
end
|
83
|
+
|
78
84
|
HttpBridge.put(request_url, actual_response)
|
79
85
|
end
|
80
86
|
|
@@ -1,4 +1,6 @@
|
|
1
|
+
require 'timeout'
|
1
2
|
require 'cloud_formation/bridge/names'
|
3
|
+
require 'cloud_formation/bridge/util'
|
2
4
|
|
3
5
|
module CloudFormation
|
4
6
|
module Bridge
|
@@ -7,8 +9,8 @@ module CloudFormation
|
|
7
9
|
class Base
|
8
10
|
include CloudFormation::Bridge::Names
|
9
11
|
|
10
|
-
def require_fields(request, fields)
|
11
|
-
empty_fields = fields.select do |field|
|
12
|
+
def require_fields(request, *fields)
|
13
|
+
empty_fields = fields.flatten.select do |field|
|
12
14
|
request.resource_properties[field].nil? ||
|
13
15
|
request.resource_properties[field].strip.empty?
|
14
16
|
end
|
@@ -21,7 +23,16 @@ module CloudFormation
|
|
21
23
|
|
22
24
|
def update(request)
|
23
25
|
raise CloudFormation::Bridge::OperationNotImplementedError.new(
|
24
|
-
|
26
|
+
"The resource #{self.class.name} does not implement the update operation - #{request.inspect}")
|
27
|
+
end
|
28
|
+
|
29
|
+
def wait_until(description, seconds = 5, max_wait = 600, &block)
|
30
|
+
Timeout.timeout(max_wait) do
|
31
|
+
while !block.call
|
32
|
+
Util.logger.info("Waiting for #{description}")
|
33
|
+
sleep(seconds)
|
34
|
+
end
|
35
|
+
end
|
25
36
|
end
|
26
37
|
|
27
38
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'aws/elasticache'
|
2
|
+
require 'cloud_formation/bridge/names'
|
3
|
+
|
4
|
+
module CloudFormation
|
5
|
+
module Bridge
|
6
|
+
module Resources
|
7
|
+
module BaseElastiCacheResource
|
8
|
+
|
9
|
+
UnknownCacheEngineError = Class.new(StandardError)
|
10
|
+
|
11
|
+
include CloudFormation::Bridge::Names
|
12
|
+
|
13
|
+
def replication_group_available?(replication_group_id)
|
14
|
+
replication_group = client.describe_replication_groups(replication_group_id: replication_group_id)[:replication_groups][0]
|
15
|
+
replication_group[:status] == ELASTI_CACHE::AVAILABLE
|
16
|
+
end
|
17
|
+
|
18
|
+
def find_cluster(cluster_id)
|
19
|
+
client.describe_cache_clusters(
|
20
|
+
cache_cluster_id: cluster_id,
|
21
|
+
show_cache_node_info: true
|
22
|
+
)[:cache_clusters][0]
|
23
|
+
end
|
24
|
+
|
25
|
+
def node_urls(cluster_id)
|
26
|
+
cluster = client.describe_cache_clusters(
|
27
|
+
cache_cluster_id: cluster_id,
|
28
|
+
show_cache_node_info: true
|
29
|
+
)[:cache_clusters][0]
|
30
|
+
|
31
|
+
case cluster[:engine]
|
32
|
+
when 'redis'
|
33
|
+
cluster[:cache_nodes].map do |node|
|
34
|
+
"#{node[:endpoint][:address]}:#{node[:endpoint][:port]}"
|
35
|
+
end.join(",")
|
36
|
+
when 'memcached'
|
37
|
+
"#{cluster[:configuration_endpoint][:address]}:#{cluster[:configuration_endpoint][:port]}"
|
38
|
+
else
|
39
|
+
UnknownCacheEngineError.new("Don't know what to do with cache engine #{cluster[:engine]} - #{cluster.inspect}")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def wait_until_cluster_is_available(cluster_id)
|
44
|
+
wait_until("replica #{cluster_id} to be available") do
|
45
|
+
cluster = find_cluster(cluster_id)
|
46
|
+
Util.logger.info("Cluster info is #{cluster.inspect}")
|
47
|
+
cluster[:cache_cluster_status] == ELASTI_CACHE::AVAILABLE
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def client
|
52
|
+
@client ||= AWS::ElastiCache.new.client
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'cloud_formation/bridge/resources/base'
|
2
|
+
require 'cloud_formation/bridge/resources/base_elasti_cache_resource'
|
3
|
+
|
4
|
+
module CloudFormation
|
5
|
+
module Bridge
|
6
|
+
module Resources
|
7
|
+
|
8
|
+
class ElastiCacheNodeUrls < Base
|
9
|
+
|
10
|
+
include BaseElastiCacheResource
|
11
|
+
|
12
|
+
def create(request)
|
13
|
+
require_fields(request, ELASTI_CACHE::CLUSTER_ID)
|
14
|
+
|
15
|
+
cluster_id = request.resource_properties[ELASTI_CACHE::CLUSTER_ID]
|
16
|
+
|
17
|
+
wait_until_cluster_is_available(cluster_id)
|
18
|
+
|
19
|
+
{
|
20
|
+
FIELDS::DATA => {
|
21
|
+
ELASTI_CACHE::REPLICA_CLUSTER_ID => cluster_id,
|
22
|
+
ELASTI_CACHE::NODE_URLS => node_urls(cluster_id),
|
23
|
+
},
|
24
|
+
FIELDS::PHYSICAL_RESOURCE_ID => cluster_id,
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
def delete(request)
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'aws/elasticache'
|
2
|
+
require 'cloud_formation/bridge/util'
|
3
|
+
require 'cloud_formation/bridge/resources/base'
|
4
|
+
require 'cloud_formation/bridge/resources/base_elasti_cache_resource'
|
5
|
+
|
6
|
+
module CloudFormation
|
7
|
+
module Bridge
|
8
|
+
module Resources
|
9
|
+
|
10
|
+
class ElastiCacheReplicaCluster < Base
|
11
|
+
include BaseElastiCacheResource
|
12
|
+
|
13
|
+
REQUIRED_FIELDS = [
|
14
|
+
ELASTI_CACHE::REPLICATION_GROUP_ID,
|
15
|
+
ELASTI_CACHE::REPLICA_CLUSTER_ID,
|
16
|
+
]
|
17
|
+
|
18
|
+
def create(request)
|
19
|
+
require_fields(request, REQUIRED_FIELDS)
|
20
|
+
|
21
|
+
cluster_id = request.resource_properties[ELASTI_CACHE::REPLICA_CLUSTER_ID]
|
22
|
+
replication_id = request.resource_properties[ELASTI_CACHE::REPLICATION_GROUP_ID]
|
23
|
+
|
24
|
+
client.create_cache_cluster(cache_cluster_id: cluster_id, replication_group_id: replication_id)
|
25
|
+
|
26
|
+
wait_until_cluster_is_available(cluster_id)
|
27
|
+
|
28
|
+
{
|
29
|
+
FIELDS::DATA => {
|
30
|
+
ELASTI_CACHE::REPLICA_CLUSTER_ID => cluster_id,
|
31
|
+
ELASTI_CACHE::NODE_URLS => node_urls(cluster_id),
|
32
|
+
},
|
33
|
+
FIELDS::PHYSICAL_RESOURCE_ID => cluster_id,
|
34
|
+
}
|
35
|
+
end
|
36
|
+
|
37
|
+
def delete(request)
|
38
|
+
require_fields(request, ELASTI_CACHE::REPLICA_CLUSTER_ID)
|
39
|
+
|
40
|
+
cluster_id = request.resource_properties[ELASTI_CACHE::REPLICA_CLUSTER_ID]
|
41
|
+
|
42
|
+
begin
|
43
|
+
wait_until_cluster_is_available(cluster_id)
|
44
|
+
|
45
|
+
client.delete_cache_cluster(cache_cluster_id: cluster_id)
|
46
|
+
|
47
|
+
wait_until("cluster #{cluster_id} to be gone") do
|
48
|
+
begin
|
49
|
+
find_cluster(cluster_id)
|
50
|
+
false
|
51
|
+
rescue AWS::ElastiCache::Errors::CacheClusterNotFound
|
52
|
+
true
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
rescue AWS::ElastiCache::Errors::CacheClusterNotFound
|
57
|
+
# no cache cluster? ignore
|
58
|
+
Util.logger.info("Could not find cache cluster for #{cluster_id}, ignoring")
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'aws/elasticache'
|
2
|
+
require 'cloud_formation/bridge/util'
|
3
|
+
require 'cloud_formation/bridge/resources/base'
|
4
|
+
require 'cloud_formation/bridge/resources/base_elasti_cache_resource'
|
5
|
+
|
6
|
+
module CloudFormation
|
7
|
+
module Bridge
|
8
|
+
module Resources
|
9
|
+
|
10
|
+
class ElastiCacheReplicationGroup < Base
|
11
|
+
|
12
|
+
include BaseElastiCacheResource
|
13
|
+
|
14
|
+
REQUIRED_FIELDS = [
|
15
|
+
ELASTI_CACHE::CLUSTER_ID,
|
16
|
+
ELASTI_CACHE::REPLICATION_GROUP_ID,
|
17
|
+
ELASTI_CACHE::DESCRIPTION,
|
18
|
+
]
|
19
|
+
|
20
|
+
def create(request)
|
21
|
+
require_fields(request, REQUIRED_FIELDS)
|
22
|
+
|
23
|
+
replication_id = request.resource_properties[ELASTI_CACHE::REPLICATION_GROUP_ID]
|
24
|
+
|
25
|
+
client.create_replication_group(
|
26
|
+
replication_group_id: replication_id,
|
27
|
+
primary_cluster_id: request.resource_properties[ELASTI_CACHE::CLUSTER_ID],
|
28
|
+
replication_group_description: request.resource_properties[ELASTI_CACHE::DESCRIPTION],
|
29
|
+
)
|
30
|
+
|
31
|
+
wait_until("replication group #{replication_id} to be available") do
|
32
|
+
replication_group_available?(replication_id)
|
33
|
+
end
|
34
|
+
|
35
|
+
{
|
36
|
+
FIELDS::DATA => {
|
37
|
+
ELASTI_CACHE::REPLICATION_GROUP_ID => replication_id
|
38
|
+
},
|
39
|
+
FIELDS::PHYSICAL_RESOURCE_ID => replication_id,
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def delete(request)
|
44
|
+
require_fields(request, ELASTI_CACHE::REPLICATION_GROUP_ID)
|
45
|
+
|
46
|
+
begin
|
47
|
+
replication_id = request.resource_properties[ELASTI_CACHE::REPLICATION_GROUP_ID]
|
48
|
+
|
49
|
+
wait_until("replication group #{replication_id} to be available") do
|
50
|
+
replication_group_available?(replication_id)
|
51
|
+
end
|
52
|
+
|
53
|
+
client.delete_replication_group(
|
54
|
+
replication_group_id: replication_id,
|
55
|
+
retain_primary_cluster: true,
|
56
|
+
)
|
57
|
+
rescue AWS::ElastiCache::Errors::ReplicationGroupNotFoundFault
|
58
|
+
# main cluster does not exist, ignore
|
59
|
+
Util.logger.info("Replication group #{replication_id} does not exist, ignoring")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{ "LogicalResourceId": "ReplicaClusterNodeUrls",
|
2
|
+
"RequestId": "f9103cf1-5e1a-4597-a233-5838a7528126",
|
3
|
+
"RequestType": "Create",
|
4
|
+
"ResourceProperties": {
|
5
|
+
"ClusterId": "samplecache",
|
6
|
+
"ServiceToken": "arn:aws:sns:us-east-1:123456:sns-topic"
|
7
|
+
},
|
8
|
+
"ResourceType": "Custom::ElastiCacheNodeURLs",
|
9
|
+
"ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A123456%3Astack/sample-replica-cluster/ce7bd340-393c-11e4-962c-50fa1dbb2c64%7CRedisReplicaCluster%7Cf9103cf1-5e1a-4597-a233-5838a7528126",
|
10
|
+
"StackId": "arn:aws:cloudformation:us-east-1:123456:stack/sample-replica-cluster/ce7bd340-393c-11e4-962c-50fa1dbb2c64",
|
11
|
+
"TopicArn": "arn:aws:sns:us-east-1:123456:sns-topic"
|
12
|
+
}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
{ "LogicalResourceId": "ReplicaClusterNodeUrls",
|
2
|
+
"RequestId": "f9103cf1-5e1a-4597-a233-5838a7528126",
|
3
|
+
"RequestType": "Create",
|
4
|
+
"ResourceProperties": {
|
5
|
+
"ClusterId": "dev-redis-replica",
|
6
|
+
"ServiceToken": "arn:aws:sns:us-east-1:123456:sns-topic"
|
7
|
+
},
|
8
|
+
"ResourceType": "Custom::ElastiCacheNodeURLs",
|
9
|
+
"ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A123456%3Astack/sample-replica-cluster/ce7bd340-393c-11e4-962c-50fa1dbb2c64%7CRedisReplicaCluster%7Cf9103cf1-5e1a-4597-a233-5838a7528126",
|
10
|
+
"StackId": "arn:aws:cloudformation:us-east-1:123456:stack/sample-replica-cluster/ce7bd340-393c-11e4-962c-50fa1dbb2c64",
|
11
|
+
"TopicArn": "arn:aws:sns:us-east-1:123456:sns-topic"
|
12
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
{ "LogicalResourceId": "RedisReplicaCluster",
|
2
|
+
"RequestId": "f9103cf1-5e1a-4597-a233-5838a7528126",
|
3
|
+
"RequestType": "Create",
|
4
|
+
"ResourceProperties": {
|
5
|
+
"ReplicaClusterId": "dev-redis-replica",
|
6
|
+
"ReplicationGroupId": "dev-redis-rep-group",
|
7
|
+
"ServiceToken": "arn:aws:sns:us-east-1:123456:sns-topic"
|
8
|
+
},
|
9
|
+
"ResourceType": "Custom::ElastiCacheReplicaCluster",
|
10
|
+
"ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A123456%3Astack/sample-replica-cluster/ce7bd340-393c-11e4-962c-50fa1dbb2c64%7CRedisReplicaCluster%7Cf9103cf1-5e1a-4597-a233-5838a7528126",
|
11
|
+
"StackId": "arn:aws:cloudformation:us-east-1:123456:stack/sample-replica-cluster/ce7bd340-393c-11e4-962c-50fa1dbb2c64",
|
12
|
+
"TopicArn": "arn:aws:sns:us-east-1:123456:sns-topic"
|
13
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{ "LogicalResourceId": "RedisClusterReplicationGroup",
|
2
|
+
"RequestId": "b2fcc8a6-3f25-4e91-8aad-8d0b2f62e352",
|
3
|
+
"RequestType": "Create",
|
4
|
+
"ResourceProperties": {
|
5
|
+
"ClusterId": "cluster-id-here",
|
6
|
+
"Description": "Sample replication group for the redis instances",
|
7
|
+
"ReplicationGroupId": "dev-redis-rep",
|
8
|
+
"ServiceToken": "arn:aws:sns:us-east-1:12345567:test-stack-sns"
|
9
|
+
},
|
10
|
+
"ResourceType": "Custom::ElastiCacheReplicationGroup",
|
11
|
+
"ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A04%3Astack/replica-cluster/1a98e2b0-390e-11e4-a5f9-50e2416294e0%7CRedisClusterReplicationGroup%7Cb2fcc8a6-3f25-4e91-8aad-8d0b2f62e352",
|
12
|
+
"StackId": "arn:aws:cloudformation:us-east-1:12345567:stack/mauricio-replica-cluster/1a98e2b0-390e-11e4-a5f9-50e2416294e0",
|
13
|
+
"TopicArn": "arn:aws:sns:us-east-1:12345567:test-stack-sns"
|
14
|
+
}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
{ "LogicalResourceId": "RedisReplicaCluster",
|
2
|
+
"PhysicalResourceId": "dev-redis-rep-group",
|
3
|
+
"RequestId": "ebaf8396-72f3-43b1-b58f-a808d952e688",
|
4
|
+
"RequestType": "Delete",
|
5
|
+
"ResourceProperties": {
|
6
|
+
"ReplicaClusterId": "dev-redis-replica",
|
7
|
+
"ReplicationGroupId": "dev-redis-rep-group",
|
8
|
+
"ServiceToken": "arn:aws:sns:us-east-1:123456:sns-topic"
|
9
|
+
},
|
10
|
+
"ResourceType": "Custom::ElastiCacheReplicaCluster",
|
11
|
+
"ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A047170177871%3Astack/sample-replica-cluster/ce7bd340-393c-11e4-962c-50fa1dbb2c64%7CRedisReplicaCluster%7Cebaf8396-72f3-43b1-b58f-a808d952e688",
|
12
|
+
"StackId": "arn:aws:cloudformation:us-east-1:123456:stack/sample-replica-cluster/ce7bd340-393c-11e4-962c-50fa1dbb2c64",
|
13
|
+
"TopicArn": "arn:aws:sns:us-east-1:123456:sns-topic"
|
14
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
{ "LogicalResourceId": "RedisClusterReplicationGroup",
|
2
|
+
"PhysicalResourceId": "sample-replica-cluster",
|
3
|
+
"RequestId": "11214fd4-f6d6-4be0-87de-a1fa3b215990",
|
4
|
+
"RequestType": "Delete",
|
5
|
+
"ResourceProperties": {
|
6
|
+
"ClusterId": "cluster-id-here",
|
7
|
+
"Description": "Sample replication group for the redis instances",
|
8
|
+
"ReplicationGroupId": "dev-redis-rep",
|
9
|
+
"ServiceToken": "arn:aws:sns:us-east-1:12345567:test-stack-sns"
|
10
|
+
},
|
11
|
+
"ResourceType": "Custom::ElastiCacheReplicationGroup",
|
12
|
+
"ResponseURL": "https://cloudformation-custom-resource-response-useast1.s3.amazonaws.com/arn%3Aaws%3Acloudformation%3Aus-east-1%3A01234578%3Astack/sample-replica-cluster/1a98e2b0-390e-11e4-a5f9-50e2416294e0%7CRedisClusterReplicationGroup%7C11214fd4-f6d6-4be0-87de-a1fa3b215990",
|
13
|
+
"StackId": "arn:aws:cloudformation:us-east-1:1234578:stack/mauricio-replica-cluster/1a98e2b0-390e-11e4-a5f9-50e2416294e0",
|
14
|
+
"TopicArn": "arn:aws:sns:us-east-1:1234578:test-stack-sns"
|
15
|
+
}
|
@@ -0,0 +1,57 @@
|
|
1
|
+
{
|
2
|
+
"cache_clusters": [
|
3
|
+
{
|
4
|
+
"cache_security_groups": [
|
5
|
+
{
|
6
|
+
"cache_security_group_name": "redis-redis-srkbp24vmwfr",
|
7
|
+
"status": "active"
|
8
|
+
}
|
9
|
+
],
|
10
|
+
"cache_nodes": [
|
11
|
+
{
|
12
|
+
"parameter_group_status": "in-sync",
|
13
|
+
"cache_node_status": "available",
|
14
|
+
"cache_node_create_time": "2014-08-04 12:56:26 UTC",
|
15
|
+
"cache_node_id": "0001",
|
16
|
+
"customer_availability_zone": "us-east-1c",
|
17
|
+
"endpoint": {
|
18
|
+
"port": 6379,
|
19
|
+
"address": "red-re-1uptio9f2ytdi.mzufvw.0001.use1.cache.amazonaws.com"
|
20
|
+
}
|
21
|
+
}
|
22
|
+
],
|
23
|
+
"security_groups": [
|
24
|
+
|
25
|
+
],
|
26
|
+
"cache_cluster_id": "red-re-1uptio9f2ytdi",
|
27
|
+
"cache_parameter_group": {
|
28
|
+
"cache_node_ids_to_reboot": [
|
29
|
+
|
30
|
+
],
|
31
|
+
"parameter_apply_status": "in-sync",
|
32
|
+
"cache_parameter_group_name": "default.redis2.8"
|
33
|
+
},
|
34
|
+
"cache_cluster_status": "available",
|
35
|
+
"replication_group_id": "rg-redisclu-2ffb4776",
|
36
|
+
"cache_node_type": "cache.m1.small",
|
37
|
+
"engine": "redis",
|
38
|
+
"pending_modified_values": {
|
39
|
+
"cache_node_ids_to_remove": [
|
40
|
+
|
41
|
+
]
|
42
|
+
},
|
43
|
+
"preferred_availability_zone": "us-east-1c",
|
44
|
+
"cache_cluster_create_time": "2014-08-04 12:56:26 UTC",
|
45
|
+
"engine_version": "2.8.6",
|
46
|
+
"auto_minor_version_upgrade": true,
|
47
|
+
"preferred_maintenance_window": "thu:10:00-thu:11:00",
|
48
|
+
"client_download_landing_page": "https://console.aws.amazon.com/elasticache/home#client-download:",
|
49
|
+
"snapshot_retention_limit": 0,
|
50
|
+
"num_cache_nodes": 1,
|
51
|
+
"snapshot_window": "09:00-10:00"
|
52
|
+
}
|
53
|
+
],
|
54
|
+
"response_metadata": {
|
55
|
+
"request_id": "1ab3c5f5-3891-11e4-9cb8-252ab83f5b14"
|
56
|
+
}
|
57
|
+
}
|