@@ -203,8 +203,42 @@ func (d *AWSDriver) generateBlockDevices(blockDevices []v1alpha1.AWSBlockDeviceM
203203 return blkDeviceMappings , nil
204204}
205205
206+ // checkBlockDevices returns instanceBlockDevices whose DeleteOnTermination
207+ // field is nil on machineAPIs and resets the values to true,
208+ // to allow deletion on termination of instance
209+ func (d * AWSDriver ) checkBlockDevices (instanceID string , rootDeviceName * string ) ([]* ec2.InstanceBlockDeviceMappingSpecification , error ) {
210+ blockDevices := d .AWSMachineClass .Spec .BlockDevices
211+ var instanceBlkDeviceMappings []* ec2.InstanceBlockDeviceMappingSpecification
212+
213+ for _ , disk := range d .AWSMachineClass .Spec .BlockDevices {
214+
215+ deviceName := disk .DeviceName
216+ if disk .DeviceName == "/root" || len (blockDevices ) == 1 {
217+ deviceName = * rootDeviceName
218+ }
219+
220+ deleteOnTermination := disk .Ebs .DeleteOnTermination
221+
222+ if deleteOnTermination == nil {
223+ blkDeviceMapping := ec2.InstanceBlockDeviceMappingSpecification {
224+ DeviceName : aws .String (deviceName ),
225+ Ebs : & ec2.EbsInstanceBlockDeviceSpecification {
226+ DeleteOnTermination : aws .Bool (true ),
227+ },
228+ }
229+ instanceBlkDeviceMappings = append (instanceBlkDeviceMappings , & blkDeviceMapping )
230+ }
231+
232+ }
233+
234+ return instanceBlkDeviceMappings , nil
235+ }
236+
206237// Delete method is used to delete a AWS machine
207238func (d * AWSDriver ) Delete (machineID string ) error {
239+ var imageIds []* string
240+ imageID := aws .String (d .AWSMachineClass .Spec .AMI )
241+ imageIds = append (imageIds , imageID )
208242
209243 result , err := d .GetVMs (machineID )
210244 if err != nil {
@@ -216,12 +250,57 @@ func (d *AWSDriver) Delete(machineID string) error {
216250 }
217251
218252 instanceID := d .decodeMachineID (machineID )
219-
220253 svc , err := d .createSVC ()
221254 if err != nil {
222255 return err
223256 }
224257
258+ describeImagesRequest := ec2.DescribeImagesInput {
259+ ImageIds : imageIds ,
260+ }
261+ describeImageOutput , err := svc .DescribeImages (& describeImagesRequest )
262+ if err != nil {
263+ metrics .APIFailedRequestCount .With (prometheus.Labels {"provider" : "aws" , "service" : "ecs" }).Inc ()
264+ return err
265+ }
266+ metrics .APIRequestCount .With (prometheus.Labels {"provider" : "aws" , "service" : "ecs" }).Inc ()
267+
268+ if len (describeImageOutput .Images ) < 1 {
269+ klog .Errorf ("Image %s not found" , * imageID )
270+ return fmt .Errorf ("Image %s not found" , * imageID )
271+ }
272+
273+ // returns instanceBlockDevices whose DeleteOnTermination field is nil on machineAPIs
274+ instanceBlkDeviceMappings , err := d .checkBlockDevices (instanceID , describeImageOutput .Images [0 ].RootDeviceName )
275+ if err != nil {
276+ klog .Errorf ("Could not Default deletionOnTermination while terminating machine: %s" , err .Error ())
277+ return err
278+ }
279+
280+ // Default deletionOnTermination to true when unset on API field
281+ if len (instanceBlkDeviceMappings ) > 0 {
282+ input := & ec2.ModifyInstanceAttributeInput {
283+ InstanceId : aws .String (instanceID ),
284+ BlockDeviceMappings : instanceBlkDeviceMappings ,
285+ }
286+ _ , err = svc .ModifyInstanceAttribute (input )
287+ if err != nil {
288+ if aerr , ok := err .(awserr.Error ); ok {
289+ switch aerr .Code () {
290+ default :
291+ klog .Error (aerr .Error ())
292+ }
293+ } else {
294+ klog .Error (err .Error ())
295+ }
296+ metrics .APIFailedRequestCount .With (prometheus.Labels {"provider" : "aws" , "service" : "ecs" }).Inc ()
297+ return err
298+ }
299+ metrics .APIRequestCount .With (prometheus.Labels {"provider" : "aws" , "service" : "ecs" }).Inc ()
300+ klog .V (2 ).Infof ("Successfully defaulted deletionOnTermination to true for disks (with nil pointer) for instanceID: %q" , instanceID )
301+ }
302+
303+ // Terminate instance call
225304 input := & ec2.TerminateInstancesInput {
226305 InstanceIds : []* string {
227306 aws .String (instanceID ),
0 commit comments