Having had a Nicolas Tagliafico goal disallowed in the first half after a review, Ajax found themselves behind through Karim Benzema's 60th goal in the tournament.
Hakim Ziyech thought he had secured a deserved draw for the home side at Johan Cruijff ArenA, but Marco Asensio struck late on to put Madrid in control of the tie.
Ajax started strongly, Dusan Tadic collecting Lasse Schone's headed pass and smacking the outside of the left-hand post with a bending effort from 18 yards out.
Another fine passing move saw Tagliafico, David Neres and Tadic combine to set up Ziyech in clear space in the box, but Courtois raced off his line to save.
It looked like Courtois had gifted Ajax a deserved lead when he fumbled Matthijs de Ligt's header and allowed Tagliafico to nod in the rebound, but the goal was disallowed after a VAR review, seemingly because Tadic was blocking the keeper from an offside position.
Neres spurned another presentable chance when one-on-one with Courtois, but Madrid were beginning to offer a greater threat of their own, Benzema forcing a good low stop from Andre Onana with a half-volley.
With an hour gone, Madrid found the breakthrough. Vinicius Junior raced onto a ball over the top from Sergio Reguilon, skipped his way across the box and teed up Benzema to fire into the top-left corner of the net.
Substitute Kasper Dolberg blasted another good opening over the bar, but Ajax finally found the net when Ziyech side-footed past Courtois from Neres' precise cross.
But with three minutes of normal time remaining, Dani Carvajal raced down the left and curled a cross into the box that escaped Onana and was tapped in by Asensio.
What does it mean? Unconvincing Madrid have the edge
While the disallowed goal will be particularly tough to swallow for Ajax, they created enough opportunities to have given themselves a real chance of springing a shock in this tie.
As it is, Madrid survived the pressure and were clinical with their own opportunities, meaning they need only avoid defeat in the return match to go through.
They were not entirely convincing, especially in the first half, but there is a growing stubbornness about them under Santiago Solari that makes them very difficult to beat.
Benzema fills Ronaldo void
Plenty has been made about who would score the knockout goals without Cristiano Ronaldo, but Benzema's clinical finish, which takes him to 60 goals in the competition, showed he can be relied upon when it matters. Only his former team-mate, Lionel Messi and Madrid icon Raul have scored more times in Champions League history.
Ajax targeted the right of Madrid's defence throughout, with Nacho looking particularly shaky. It was no surprise to see Ziyech's goal set up by a Neres cross from that side.
Key Opta Facts:
- Ajax have lost their last seven games in European competition against Real Madrid, scoring only three goals and conceding 22.
- Ziyech scored his first Champions League goal with his 30th shot in the competition.
- Benzema has either scored or assisted a goal in each of his six Champions League matches against Ajax (4 goals, 4 assists).
- No other LaLiga player has scored more goals than Benzema in 2019 in all competitions (8, level with Messi).
- Vinicius has provided eight assists in all competitions for Madrid - more than any of his team-mates.
- Sergio Ramos made his 600th appearance for Real Madrid in all competitions against Ajax – the seventh different player to achieve this landmark.
The second leg takes place in the Spanish capital on March 5. More immediately, Madrid host Girona in LaLiga on Sunday, the same day Ajax meet NAC Breda in the Eredivisie.