### Description

It is impossible to create a follower index with a `$` character in its name (please note, it is possible to create a regular index with `$` in its name).

This could be reproduced by rest request:
```
PUT /my-index/_ccr/follow
{
    "remote_cluster": "my-remote-cluster",
    "leader_index": "my-index$follower"
}
```

or `CcrIntegTestCase`:

```
    public void testFollowIndex() throws Exception {
        assertAcked(leaderClient().admin().indices().prepareCreate("my$index"));
        setupRemoteCluster();
        final PutFollowAction.Request followRequest = putFollow("my$index", "my$index");
        followerClient().execute(PutFollowAction.INSTANCE, followRequest).get();
    }
```

This is happening as during initial follow phase we restore the leader cluster from the remote using a snapshot restore.
Corresponding request is created with index name added to `RestoreSnapshotRequest#renamePattern` (regexp) without escaping `$`.

x-pack/plugin/ccr/src/internalClusterTest/java/org/elasticsearch/xpack/ccr/IndexFollowingIT.java
IndexMetadata.builder(indexMetadata)
                            .settingsVersion(indexMetadata.getSettingsVersion() + 1)
                            .settings(settings)
                            .build(),
                        true
                    );
                return ClusterState.builder(currentState).metadata(metadata).build();
            }
            @Override
            public void onFailure(Exception e) {
                throw new AssertionError(e);
            }
        });
        assertBusy(() -> {
            GetSettingsResponse resp = followerClient().admin().indices().prepareGetSettings("follower").get();
            assertThat(resp.getSetting("follower", "index.max_ngram_diff"), equalTo("2"));
            assertThat(resp.getSetting("follower", PrivateSettingPlugin.INDEX_INTERNAL_SETTING.getKey()), nullValue());
            assertThat(resp.getSetting("follower", PrivateSettingPlugin.INDEX_PRIVATE_SETTING.getKey()), nullValue());
        });
    }
    /**
     * This test verifies that data tier preference is copied over to follower. This may not be desired, but demonstrates current
     * behavior and ensures we keep this until we decide to break it.
     */
    public void testReplicateDataTierPreference() throws Exception {
        String tier = randomFrom(DataTier.DATA_HOT, DataTier.DATA_WARM, DataTier.DATA_COLD);
        assertAcked(
            leaderClient().admin()
                .indices()
                .prepareCreate("leader")