Here is an answer that uses the async library. It's very useful when you have to perform a chain of asynchronous operations.
In order to use it, you have to include async.js or async.min.js in yout HTML code. You may find script links on CDNJS.
Here I only use the async.map() function. The idea is that it executes the load_candidate function (2nd argument) for each item in the position_ids array. So all AJAX requests are fired at the same time. But it waits for all of them to complete, and gets all requests results in an array.
I'm aware using this kind of library might look a bit scary, but honestly, if you ever have to do some kind of complex code, with many asynchronous calls, some depending on the results of previous ones, this is worth looking into.
I took the liberty to refactor your code into smaller, more specific functions. I tested it in my browser and it works, just remember that your id variable must be defined somewhere before you call load_candidates().
function load_position(id, cbSuccess, cbError) {
  $.ajax({
    url: 'admin/requests/Get-Positions.php',
    method: 'POST',
    data: {
      id: id
    },
    dataType: 'json',
    success: cbSuccess,
    error: cbError
  });  
}
function load_candidate(position_id, callback) {
  $.ajax({
    url: 'admin/requests/Get-Candidate_Per_Position.php',
    method: 'POST',
    data: {
      position_id: position_id
    },
    dataType: 'json',
    success: function(result) {
      callback(null, result);
    },
    error: function(xhr, status, error) {
      callback(new Error('Error in 2nd request: ' + xhr.responseText));
    }
  });
}
function ajax_error_handler(xhr, status, error) {
  console.log(xhr.responseText);
}
function load_candidates(id) {
  // Fires the 1st request
  load_position(id, function(result1) {
    // This extracts all position ids from the result of 1st request
    var position_ids = result1.map(function(value) {
      return value.id;
    });
    async.map(position_ids, load_candidate, function(err, result2) {
      // Abort on error
      // This will be called if ANY of the individual load_candidate() request fails
      if(err) {
        console.log(err);
        return;
      }
      // result2 is now an array of results of each AJAX request
      result1.forEach(function(value1, index1) {
        // Create your outer div
        var textToInsert = '';
        textToInsert += '<div class="card bg-primary text-center"><div class="card-body"><h4 class="text-white m-0" id="position">' + value1['position'] + '</h4></div></div><br><div class="row">';
        // append each result of 2nd request to that div 
        result2[index1].forEach(function(value2, key) {
          textToInsert += '<div class="col-lg-4 col-sm-6 text-center mb-4"><h3>' + value2['name'] + '</h3><p>' + value2['candidate_number'] + '</p></div>';
        });
        // then close it and append it to your list
        textToInsert += '</div>';
        $('#candidate_list').append(textToInsert);
      });
    });
  },
  ajax_error_handler);
}
// Your id variable has to be defined somewhere
load_candidates(id);