First of all, don't use int 0x80 in 64-bit code; use the syscall interface instead.
The write() system call requires a pointer to the data to be written.  If you put 0x41 in that register (rcx in your code but should be rsi with syscall), it will attempt to write whatever data is at address 0x41, which of course will fail because that page is not mapped.  If you check the return value from the system call, which is always a good idea, you'll see -EFAULT.
This might seem slightly inefficient for writing a single byte.  You might wish there were a separate system call similar to C's putc which writes just a single character, passed in a register.  But this is a rare enough case that it likely wouldn't be worth the trouble of implementing it; most applications will buffer their writes so as not to have to make a system call for each byte.  Anyway, the overhead of using memory is negligible compared to the much greater overhead of making a system call in the first place.
So your letter A has to be in memory somewhere.  But it doesn't necessarily have to be in the .data section. Any other section of static data would be fine: .rodata or .bss if you initialize it at runtime, or even in .text if you're careful not to execute it.
Another perfectly good option is to put it on the stack.
    push 0x41       ; actually pushes 8 bytes but that's okay,
                    ; `0x41` is the low byte because x86 is little-endian
    mov rsi, rsp    ; `rsp` points at what was most recently pushed
    mov edi, 1      ; file descriptor
                    ; it's ok to use edi instead of rdi because writes to 32-bit
                    ; registers are zero extended
    mov edx, 1      ; number of bytes to write
    mov eax, 1      ; system call number for write()
                    ; syscall uses different numbers than int 0x80
    syscall
    add rsp, 8      ; clean up the stack.  
                    ; pop rdi or any other unneeded register would work too, and be shorter