How can I programmatically place blocks?
I was able to accomplish what I wanted using theme config, as described in How to assign blocks to particular regions on theme install? . This solution works for me, because my site will only ever use one (custom) theme, and I don't mind configuring all blocks this way.

I created a config file (this one is for a language switcher, provided by language module) and put it in MYTHEME/config/install/block.block.MYTHEME_BLOCKNAME.yml. It's just what you would export from configuration management, without uuid.

langcode: en
status: true
dependencies:
  module:
    - language
  theme:
    - MYTHEME
id: MYTHEME_BLOCKNAME
theme: MYTHEME
region: header
weight: -6
provider: null
plugin: 'language_block:language_interface'
settings:
  id: 'language_block:language_interface'
  label: 'Language switcher'
  provider: language
  label_display: '0'
visibility: {  }