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



283
284
285
# File 'lib/sparkle_formation/resources/aws.rb', line 283

def included(_klass)
  load!
end

.load!TrueClass

Load the builtin AWS resources

Returns:

  • (TrueClass)


270
271
272
273
274
275
276
277
278
279
280
# File 'lib/sparkle_formation/resources/aws.rb', line 270

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