Class: SparkleFormation::Resources::Aws

Inherits:
SparkleFormation::Resources show all
Extended by:
Bogo::Memoization
Defined in:
lib/sparkle_formation/resources/aws.rb

Overview

AWS specific resources collection

Constant Summary collapse

PROPERTY_UPDATE_CONDITIONALS =

Conditionals for property updates

Smash.new(
  "AWS::DynamoDB::Table" => {
    "GlobalSecondaryIndexes" => [
      # Updates not really supported here. Set as unknown to
      # prompt user to investigate
      UpdateCausesConditional.new("unknown", true),
    ],
  },
  "AWS::EC2::EIPAssociation" => {
    "AllocationId" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        original.get("Properties", "InstanceId") != final.get("Properties", "InstanceId") ||
          original.get("Properties", "NetworkInterfaceId") != final.get("Properties", "NewtorkInterfaceId")
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "EIP" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        original.get("Properties", "InstanceId") != final.get("Properties", "InstanceId") ||
          original.get("Properties", "NetworkInterfaceId") != final.get("Properties", "NewtorkInterfaceId")
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "InstanceId" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        original.get("Properties", "AllocationId") != final.get("Properties", "AllocationId") ||
          original.get("Properties", "EIP") != final.get("Properties", "EIP")
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "NetworkInterfaceId" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        original.get("Properties", "AllocationId") != final.get("Properties", "AllocationId") ||
          original.get("Properties", "EIP") != final.get("Properties", "EIP")
      }),
      UpdateCausesConditional.new("none", true),
    ],
  },
  "AWS::EC2::Instance" => {
    "AdditionalInfo" => [
      UpdateCausesConditional.new("unknown", true), # EBS AMI dependent
    ],
    "BlockDeviceMappings" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        f_maps = final.fetch("Properties", "BlockDeviceMappings", [])
        o_maps = original.fetch("Properties", "BlockDeviceMappings", [])
        f_maps.map! do |m|
          m.delete("DeleteOnTermination")
          m.to_smash(:sorted)
        end
        o_maps.map! do |m|
          m.delete("DeleteOnTermination")
          m.to_smash(:sorted)
        end
        f_maps.size != o_maps.size ||
          !f_maps.all? { |m| o_maps.include?(m) }
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "EbsOptimized" => [
      UpdateCausesConditional.new("unknown", true), # EBS AMI dependent
    ],
    "InstanceType" => [
      UpdateCausesConditional.new("unknown", true), # EBS AMI dependent
    ],
    "KernelId" => [
      UpdateCausesConditional.new("unknown", true), # EBS AMI dependent
    ],
    "RamdiskId" => [
      UpdateCausesConditional.new("unknown", true), # EBS AMI dependent
    ],
    "SecurityGroupIds" => [
      UpdateCausesConditional.new("none",
                                  lambda { |final, _orig|
        final.get("Properties", "SubnetId") ||
          final.fetch("Properties", "NetworkInterface", {}).values.include?("SubnetId")
      }),
      UpdateCausesConditional.new("replacement", true),
    ],
    "Tenancy" => [
      UpdateCausesConditional.new("none", lambda { |final, original|
        ["host", "dedicated"].any? { |val| final.get("Properties", "Tenancy") == val } &&
          ["host", "dedicated"].any? { |val| original.get("Properties", "Tenancy") == val }
      }),
      UpdateCausesConditional.new("replacement", true),
    ],
    "UserData" => [
      UpdateCausesConditional.new("unknown", true), # EBS AMI dependent
    ],
  },
  "AWS::EC2::NetworkInterface" => {
    "PrivateIpAddresses" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        f_primary = final.fetch("Properties", "PrivateIpAddresses", []).detect do |addr|
          addr["Primary"]
        end || Smash.new
        o_primary = original.fetch("Properties", "PrivateIpAddresses", []).detect do |addr|
          addr["Primary"]
        end || Smash.new
        f_primary.to_smash(:sorted) != o_primary.to_smash(:sorted)
      }),
      UpdateCausesConditional.new("none", true),
    ],
  },
  "AWS::ElastiCache::CacheCluster" => {
    "NumCacheNodes" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        [
          final.get("Properties", "PreferredAvailabilityZone"),
          final.get("Properties", "PreferredAvailabilityZones"),
          original.get("Properties", "PreferredAvailabilityZone"),
          original.get("Properties", "PreferredAvailabilityZones"),
        ].all? { |i| i.nil? || i.empty? }
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "PreferredAvailabilityZones" => [
      UpdateCausesConditional.new("interrupt",
                                  lambda { |final, original|
        original.get("Properties", "PreferredAvailabilityZones") ||
          final.fetch("Properties", "PreferredAvailabilityZones", []).include?(
            original.get("Properties", "PreferredAvailabilityZone")
          )
      }),
      UpdateCausesConditional.new("replacement", true),
    ],
  },
  "AWS::ElasticLoadBalancing::LoadBalancer" => {
    "AvailabilityZones" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        original.fetch("Properties", "AvailabilityZones", []).empty? ||
          final.fetch("Properties", "AvailabilityZones", []).empty?
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "HealthCheck" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        original.fetch("Properties", "HealthCheck", {}).empty? ||
          final.fetch("Properties", "HealthCheck", {}).empty?
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "Subnets" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        original.fetch("Properties", "Subnets", []).empty? ||
          final.fetch("Properties", "Subnets", []).empty?
      }),
      UpdateCausesConditional.new("none", true),
    ],
  },
  "AWS::KinesisFirehose::DeliveryStream" => {
    "ElasticsearchDestinationConfiguration" => [
      UpdateCausesConditional.new("interrupt", lambda { |final, original|
        !!original.get("Properties", "ElasticsearchDestinationConfiguration")
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "ExtendedS3DestinationConfiguration" => [
      UpdateCausesConditional.new("interrupt", lambda { |final, original|
        !!original.get("Properties", "ExtendedS3DestinationConfiguration")
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "RedshiftDestinationConfiguration" => [
      UpdateCausesConditional.new("interrupt", lambda { |final, original|
        !!original.get("Properties", "RedshiftDestinationConfiguration")
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "S3DestinationConfiguration" => [
      UpdateCausesConditional.new("interrupt", lambda { |final, original|
        !!original.get("Properties", "S3DestinationConfiguration")
      }),
      UpdateCausesConditional.new("none", true),
    ],
  },
  "AWS::Neptune::DBCluster" => {
    "BackupRetentionPeriod" => [
      # Not clear within documentation
      UpdateCausesConditional.new("unknown", true),
    ],
    "PreferredMaintenanceWindow" => [
      # Not clear within documentation
      UpdateCausesConditional.new("unknown", true),
    ],
  },
  "AWS::Neptune::DBClusterParameterGroup" => {
    "Parameters" => [
      # dependent on what parameters have been changed. doesn't
      # look like parameter modifications are applied immediately?
      # set as unknown for safety
      UpdateCausesConditional.new("unknown", true),
    ],
  },
  "AWS::Neptune::DBInstance" => {
    "AutoMinorVersionUpgrade" => [
      # Documentation does not indicate condition when no
      # interruption occurs, so set as interrupt for safety
      UpdateCausesConditional.new("interrupt", true),
    ],
    "DBParameterGroupName" => [
      UpdateCausesConditional.new("interrupt", true),
    ],
    "PreferredMaintenanceWindow" => [
      UpdateCausesConditional.new("interrupt", true),
    ],
  },
  "AWS::Neptune::DBParameterGroup" => {
    # Interrupt is only caused when parameters are static
    # values. Dynamic values are applied immediately
    "Parameters" => [
      UpdateCausesConditional.new("interrupt", lambda { |final, original|
        o_params = original.fetch("Properties", "Parameters", {})
        f_params = final.fetch("Properties", "Parameters", {})
        f_params.any? { |key, value|
          o_params[key].nil? ||
            o_params[key].is_a?(Hash)
        }
      }),
      UpdateCausesConditional.new("none", true),
    ],
  },
  "AWS::RDS::DBCluster" => {
    "BackupRetentionPeriod" => [
      UpdateCausesConditional.new("interrupt",
                                  lambda { |final, original|
        fp = final.get("Properties", "BackupRetentionPeriod").to_i
        op = original.get("Properties", "BackupRetentionPeriod").to_i
        (fp == 0 && op != 0) ||
          (op == 0 && fp != 0)
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "PreferredMaintenanceWindow" => [
      # can interrupt if apply immediately is set on api call but
      # no way to know
      UpdateCausesConditional.new("unknown", true),
    ],
  },
  "AWS::RDS::DBClusterParameterGroup" => {
    "Parameters" => [
      # dependent on what parameters have been changed. doesn't
      # look like parameter modifications are applied immediately?
      # set as unknown for safety
      UpdateCausesConditional.new("unknown", true),
    ],
  },
  "AWS::RDS::DBInstance" => {
    "AutoMinorVersionUpgrade" => [
      # can cause interrupts based on future actions (enables
      # auto patching) so leave as unknown for safety
      UpdateCausesConditional.new("unknown", true),
    ],
    "BackupRetentionPeriod" => [
      UpdateCausesConditional.new("interrupt",
                                  lambda { |final, original|
        fp = final.get("Properties", "BackupRetentionPeriod").to_i
        op = original.get("Properties", "BackupRetentionPeriod").to_i
        (fp == 0 && op != 0) ||
          (op == 0 && fp != 0)
      }),
      UpdateCausesConditional.new("none", true),
    ],
    "DBParameterGroupName" => [
      # changes are not applied until reboot, but it could
      # still be considered an interrupt? setting as unknown
      # for safety
      UpdateCausesConditional.new("unknown", true),
    ],
    "MonitoringInterval" => [
      # There can be an interruption or nothing. No clear distinction
      # on when an interrupt so just default to interrupt for safety
      UpdateCausesConditional.new("interrupt", true),
    ],
    "PreferredMaintenanceWindow" => [
      # can interrupt if apply immediately is set on api call but
      # no way to know
      UpdateCausesConditional.new("unknown", true),
    ],
  },
  "AWS::RDS::DBParameterGroup" => {
    "Parameters" => [
      # dependent on what parameters have been changed. doesn't
      # look like parameter modifications are applied immediately?
      # set as unknown for safety
      UpdateCausesConditional.new("unknown", true),
    ],
  },
  "AWS::RDS::EventSubscription" => {
    "SourceType" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        !final.get("Properties", "SourceType")
      }),
      UpdateCausesConditional.new("none", true),
    ],
  },
  "AWS::Route53::HostedZone" => {
    "VPCs" => [
      UpdateCausesConditional.new("replacement",
                                  lambda { |final, original|
        !final.get("Properties", "VPCs") ||
          !original.get("Properties", "VPCs")
      }),
      UpdateCausesConditional.new("none", true),
    ],
  },
)

Constants inherited from SparkleFormation::Resources

RESOURCE_TYPE_NAMESPACE_SPLITTER, RESOURCE_TYPE_TR

Class Method Summary collapse

Methods inherited from SparkleFormation::Resources

base_key, key_loader, load, lookup, register, registry, registry_key, resource, resource_customizer, resource_lookup, resource_type_splitter

Methods included from Utils::AnimalStrings

#camel, #snake

Class Method Details

.included(_klass) ⇒ Object

Auto load data when included



350
351
352
# File 'lib/sparkle_formation/resources/aws.rb', line 350

def included(_klass)
  load!
end

.load!TrueClass

Load the builtin AWS resources

Returns:

  • (TrueClass)


337
338
339
340
341
342
343
344
345
346
347
# File 'lib/sparkle_formation/resources/aws.rb', line 337

def load!
  memoize(:aws_resources, :global) do
    load(
      File.join(
        File.dirname(__FILE__),
        "aws_resources.json"
      )
    )
    true
  end
end