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),
    ],
    '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::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),
    ],
    '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, 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



266
267
268
# File 'lib/sparkle_formation/resources/aws.rb', line 266

def included(_klass)
  load!
end

.load!TrueClass

Load the builtin AWS resources

Returns:

  • (TrueClass)


253
254
255
256
257
258
259
260
261
262
263
# File 'lib/sparkle_formation/resources/aws.rb', line 253

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