From the docs:
// The Contract interface
let abi = [ ... ];
// Connect to the network
let provider = ethers.getDefaultProvider();
// The address from the above deployment example
let contractAddress = "...";
// We connect to the Contract using a Provider, so we will only
// have read-only access to the Contract
let contract = new ethers.Contract(contractAddress, abi, provider);
I understand how this works, but I'm curious if you need the ABI at all? In web3.js, you don't, thanks to the ability to pass a contract method as a string:
// in web3.js
contract.methods["someMethod()"]()