The solution was to switch from Ivy to the Maven Resolver Ant Tasks - much better documented and easier to understand.
I can now load AWS CodeArtifact dependencies from my ant task with something like this (after doing the Maven setup instructions from AWS CodeArtifact). This downloads the Maven resolver jar as part of the process:
<property name="maven.install.version" value="1.3.0"/>
<property name="ant.jar.dir" value="${user.home}/.ant/lib"/>
<property name="maven.jar.file" value="${ant.jar.dir}/maven-resolver-ant-tasks.jar"/>
<target name="load-maven-dependencies" depends="init-maven">
<resolver:resolve>
<dependencies>
<dependency coords="group:artifact:version"/>
</dependencies>
<path refid="main.classpath" classpath="compile"/>
</resolver:resolve>
</target>
<target name="init-maven" depends="download-maven">
<path id="maven.lib.path">
<fileset dir="${ant.jar.dir}" includes="${maven.jar.file}"/>
</path>
<taskdef resource="org/apache/maven/resolver/ant/antlib.xml" uri="antlib:org.apache.maven.resolver.ant" classpathref="maven.lib.path"/>
</target>
<target name="download-maven" unless="offline">
<mkdir dir="${ant.jar.dir}" />
<get src="https://search.maven.org/remotecontent?filepath=org/apache/maven/resolver/maven-resolver-ant-tasks/${maven.install.version}/maven-resolver-ant-tasks-${maven.install.version}-uber.jar" dest="${maven.jar.file}" usetimestamp="true"/>
</target>
You can then use main.claspath in your taskdef, like this:
<taskdef name="customTask" classname="com.prosc.CustomAntTask" classpathref="main.classpath" />