1# frozen_string_literal: true 2 3module Clusters 4 module Aws 5 class ProvisionService 6 attr_reader :provider 7 8 def execute(provider) 9 @provider = provider 10 11 configure_provider_credentials 12 provision_cluster 13 14 if provider.make_creating 15 WaitForClusterCreationWorker.perform_in( 16 Clusters::Aws::VerifyProvisionStatusService::INITIAL_INTERVAL, 17 provider.cluster_id 18 ) 19 else 20 provider.make_errored!("Failed to update provider record; #{provider.errors.full_messages}") 21 end 22 rescue Clusters::Aws::FetchCredentialsService::MissingRoleError 23 provider.make_errored!('Amazon role is not configured') 24 rescue ::Aws::Errors::MissingCredentialsError 25 provider.make_errored!('Amazon credentials are not configured') 26 rescue ::Aws::STS::Errors::ServiceError => e 27 provider.make_errored!("Amazon authentication failed; #{e.message}") 28 rescue ::Aws::CloudFormation::Errors::ServiceError => e 29 provider.make_errored!("Amazon CloudFormation request failed; #{e.message}") 30 end 31 32 private 33 34 def provision_role 35 provider.created_by_user&.aws_role 36 end 37 38 def credentials 39 @credentials ||= Clusters::Aws::FetchCredentialsService.new( 40 provision_role, 41 provider: provider 42 ).execute 43 end 44 45 def configure_provider_credentials 46 provider.update!( 47 access_key_id: credentials.access_key_id, 48 secret_access_key: credentials.secret_access_key, 49 session_token: credentials.session_token 50 ) 51 end 52 53 def provision_cluster 54 provider.api_client.create_stack( 55 stack_name: provider.cluster.name, 56 template_body: stack_template, 57 parameters: parameters, 58 capabilities: ["CAPABILITY_IAM"] 59 ) 60 end 61 62 def parameters 63 [ 64 parameter('ClusterName', provider.cluster.name), 65 parameter('ClusterRole', provider.role_arn), 66 parameter('KubernetesVersion', provider.kubernetes_version), 67 parameter('ClusterControlPlaneSecurityGroup', provider.security_group_id), 68 parameter('VpcId', provider.vpc_id), 69 parameter('Subnets', provider.subnet_ids.join(',')), 70 parameter('NodeAutoScalingGroupDesiredCapacity', provider.num_nodes.to_s), 71 parameter('NodeInstanceType', provider.instance_type), 72 parameter('KeyName', provider.key_name) 73 ] 74 end 75 76 def parameter(key, value) 77 { parameter_key: key, parameter_value: value } 78 end 79 80 def stack_template 81 File.read(Rails.root.join('vendor', 'aws', 'cloudformation', 'eks_cluster.yaml')) 82 end 83 end 84 end 85end 86