class OpenStax::Aws::DeploymentBase
Constants
- RESERVED_ENV_NAMES
Attributes
dry_run[R]
env_name[R]
name[R]
region[R]
Public Class Methods
inherited(child_class)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 208 def inherited(child_class) # Copy any tags defined in the parent to the child so that it can access them # while not using class variables that are shared across all classes in the # that inherit here child_class.instance_variable_set("@tags", tags.dup) end
logger()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 215 def logger OpenStax::Aws.configuration.logger end
new(env_name: nil, region:, name:, dry_run: true)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 41 def initialize(env_name: nil, region:, name:, dry_run: true) if RESERVED_ENV_NAMES.include?(env_name) raise "#{env_name} is a reserved word and cannot be used as an environment name" end # Allow a blank env_name but normalize it to `nil` @env_name = env_name.blank? ? nil : env_name if @env_name && !@env_name.match(/^[a-zA-Z][a-zA-Z0-9-]*$/) raise "The environment name must consist only of letters, numbers, and hyphens, " \ "and must start with a letter." end @region = region @name = name @dry_run = dry_run end
sam_build_directory(*directory_parts)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 87 def sam_build_directory(*directory_parts) if method_defined?("sam_build_directory") raise "Can only set buisam_build_directoryld_directory once per class definition" end define_method "sam_build_directory" do File.expand_path(File.join(*directory_parts)) end end
secrets(id, &block)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 97 def secrets(id, &block) if id.blank? raise "The first argument to `secrets` must be a non-blank ID" end if !id.to_s.match(/^[a-zA-Z][a-zA-Z0-9_]*$/) raise "The first argument to `secrets` must consist only of letters, numbers, and underscores, " \ "and must start with a letter." end if method_defined?("#{id}_secrets") raise "Can only define the `#{id}` secrets once per class definition" end if method_defined?("#{id}_stack") raise "Cannot define `#{id}` secrets because there is a stack with that ID" end define_method("#{id}_secrets") do |for_create_or_update: false| secrets_factory = SecretsFactory.new( region: region, namespace: [env_name, name], context: self, dry_run: dry_run, for_create_or_update: for_create_or_update, shared_substitutions_block: @shared_secrets_substitutions_block ) secrets_factory.namespace(id) secrets_factory.instance_exec({}, &block) secrets_factory.instance end end
secrets_substitutions(&block)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 192 def secrets_substitutions(&block) define_method("shared_secrets_substitutions_block") do block end end
stack(id, &block)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 135 def stack(id, &block) if id.blank? raise "The first argument to `stack` must be a non-blank ID" end if !id.to_s.match(/^[a-zA-Z][a-zA-Z0-9_]*$/) raise "The first argument to `stack` must consist only of letters, numbers, and underscores, " \ "and must start with a letter." end if method_defined?("#{id}_secrets") raise "Cannot define `#{id}` stack because there are secrets with that ID" end stack_ids.push(id) define_method("#{id}_stack") do instance_variable_get("@#{id}_stack") || begin stack_factory = StackFactory.new(id: id, deployment: self) stack_factory.instance_eval(&block) if block_given? # Fill in missing attributes using deployment variables and conventions if stack_factory.name.blank? stack_factory.name([env_name,name,id].compact.join("-").gsub("_","-")) end if stack_factory.region.blank? stack_factory.region(region) end if stack_factory.dry_run.nil? stack_factory.dry_run(dry_run) end if stack_factory.enable_termination_protection.nil? stack_factory.enable_termination_protection(is_production?) end if stack_factory.absolute_template_path.blank? stack_factory.autoset_absolute_template_path(respond_to?(:template_directory) ? template_directory : "") end # Populate parameter defaults that match convention names if OpenStax::Aws.configuration.infer_parameter_defaults defaults = parameter_defaults_from_template(stack_factory.absolute_template_path) defaults.each{|key,value| stack_factory.parameter_defaults[key] ||= value} end stack_factory.build.tap do |stack| instance_variable_set("@#{id}_stack", stack) end end end end
stack_ids()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 131 def stack_ids @stack_ids ||= [] end
tag(key, value=nil, &block)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 198 def tag(key, value=nil, &block) raise 'The first argument to `tag` must not be blank' if key.blank? raise '`tag` must be given a value or a block' if value.nil? && !block_given? tags[key] = block_given? ? block : value end
template_directory(*directory_parts)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 77 def template_directory(*directory_parts) if method_defined?("template_directory") raise "Can only set template_directory once per class definition" end define_method "template_directory" do File.join(*directory_parts) end end
Public Instance Methods
built_in_parameter_default(parameter_name)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 250 def built_in_parameter_default(parameter_name) case parameter_name when "EnvName" env_name when /(.+)StackName$/ send("#{$1}Stack".underscore).name rescue nil end end
deployed_parameters()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 244 def deployed_parameters stacks.each_with_object({}) do |stack, hash| hash[stack.name] = stack.deployed_parameters end end
env_name!()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 64 def env_name! raise "`env_name` is blank" if env_name.blank? env_name end
name!()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 59 def name! raise "`name` is blank" if name.blank? name end
parameter_defaults_from_template(template_or_absolute_template_path)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 220 def parameter_defaults_from_template(template_or_absolute_template_path) template = template_or_absolute_template_path.is_a?(String) ? Template.from_absolute_file_path(template_or_absolute_template_path) : template_or_absolute_template_path template.parameter_names.each_with_object({}) do |parameter_name, defaults| value = parameter_default(parameter_name) || built_in_parameter_default(parameter_name) if !value.nil? defaults[parameter_name.underscore.to_sym] = value end end end
stacks()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 235 def stacks self.class.stack_ids.map{|id| self.send("#{id}_stack")} end
status(reload: false)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 239 def status(reload: false) @status = nil if reload @status ||= Status.new(self) end
Protected Instance Methods
auto_scaling_client()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 292 def auto_scaling_client @auto_scaling_client ||= ::Aws::AutoScaling::Client.new(region: region) end
auto_scaling_group(name:)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 300 def auto_scaling_group(name:) ::Aws::AutoScaling::AutoScalingGroup.new(name: name, client: auto_scaling_client) end
client()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 288 def client @client ||= ::Aws::CloudFormation::Client.new(region: region) end
cloudfront_client()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 304 def cloudfront_client @cloudfront_client ||= ::Aws::CloudFront::Client.new(region: region) end
configuration()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 284 def configuration OpenStax::Aws.configuration end
get_image_tag(image_id:, key:)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 348 def get_image_tag(image_id:, key:) tag = image(image_id).tags.find{|tag| tag.key == key} raise "No tag with key #{key} on AMI #{image_id}" if tag.nil? tag.value end
image(image_id)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 354 def image(image_id) Aws::EC2::Image.new(image_id, region: region) end
image_sha(image_id)
click to toggle source
Returns the SHA on an AMI
# File lib/openstax/aws/deployment_base.rb, line 359 def image_sha(image_id) get_image_tag(image_id: image_id, key: "sha") end
is_production?()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 269 def is_production? env_name == OpenStax::Aws.configuration.production_env_name end
parameter_default(parameter_name)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 265 def parameter_default(parameter_name) nil end
resource_tag_value(resource:, key:)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 340 def resource_tag_value(resource:, key:) begin resource.tag(key).value rescue NoMethodError => ee nil end end
s3_client()
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 308 def s3_client @s3_client ||= Aws::S3::Client.new(region: region) end
s3_key_exists?(bucket:, key:)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 312 def s3_key_exists?(bucket:, key:) begin s3_client.get_object(bucket: bucket, key: key) true rescue Aws::S3::Errors::NoSuchKey false end end
secrets_namespace(id: 'default')
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 365 def secrets_namespace(id: 'default') raise "Override this method in your deployment class and provide a namespace " \ "for secrets data in the AWS Parameter Store. The key there will be this namespace " \ "prefixed by the environment name and suffixed with the secret name." end
set_desired_capacity(asg_name:, desired_capacity:)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 296 def set_desired_capacity(asg_name:, desired_capacity:) auto_scaling_client.set_desired_capacity(auto_scaling_group_name: asg_name, desired_capacity: desired_capacity) end
subdomain_with_trailing_dot(site_name:)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 273 def subdomain_with_trailing_dot(site_name:) parts = [] parts.push(site_name) if !site_name.blank? parts.push(env_name!) unless is_production? subdomain = parts.join("-") subdomain.blank? ? "" : subdomain + "." end
wait_for_tag_change(resource:, key:, polling_seconds: 20, timeout_seconds: nil)
click to toggle source
# File lib/openstax/aws/deployment_base.rb, line 321 def wait_for_tag_change(resource:, key:, polling_seconds: 20, timeout_seconds: nil) keep_polling = true started_at = Time.now original_value = resource_tag_value(resource: resource, key: key) wait_message = OpenStax::Aws::WaitMessage.new( message: "Waiting for the #{key} tag on #{resource.name} to change from #{original_value}" ) while keep_polling wait_message.say_it sleep(polling_seconds) keep_polling = false if resource_tag_value(resource: resource, key: key) != original_value keep_polling = false if !timeout_seconds.nil? && Time.now - timeout_seconds > started_at end end