diff --git a/executors/docker/machine/terminal.go b/executors/docker/machine/terminal.go
new file mode 100644
index 0000000000000000000000000000000000000000..1e8bbfcb3a6a872e0d0aa05922faecb85551bddc
--- /dev/null
+++ b/executors/docker/machine/terminal.go
@@ -0,0 +1,16 @@
+package machine
+
+import (
+	"errors"
+
+	"gitlab.com/gitlab-org/gitlab-runner/session/terminal"
+	terminalsession "gitlab.com/gitlab-org/gitlab-runner/session/terminal"
+)
+
+func (e *machineExecutor) Connect() (terminalsession.Conn, error) {
+	if term, ok := e.executor.(terminal.InteractiveTerminal); ok {
+		return term.Connect()
+	}
+
+	return nil, errors.New("executor does not have terminal")
+}
diff --git a/executors/docker/machine/terminal_test.go b/executors/docker/machine/terminal_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..0779de64a3e2d73ce54692b66660bdbecdfd3598
--- /dev/null
+++ b/executors/docker/machine/terminal_test.go
@@ -0,0 +1,37 @@
+package machine
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+	"gitlab.com/gitlab-org/gitlab-runner/common"
+	"gitlab.com/gitlab-org/gitlab-runner/session/terminal"
+)
+
+func TestMachineExecutor_Connect_NoTerminal(t *testing.T) {
+	e := machineExecutor{
+		executor: &common.MockExecutor{},
+	}
+
+	conn, err := e.Connect()
+	assert.Error(t, err)
+	assert.Nil(t, conn)
+}
+
+type mockTerminalExecutor struct {
+	common.MockExecutor
+	terminal.MockInteractiveTerminal
+}
+
+func TestMachineExecutor_Connect_Terminal(t *testing.T) {
+	mock := mockTerminalExecutor{}
+	e := machineExecutor{
+		executor: &mock,
+	}
+	mock.MockInteractiveTerminal.On("Connect").Return(&terminal.MockConn{}, nil).Once()
+
+	conn, err := e.Connect()
+	assert.NoError(t, err)
+	assert.NotNil(t, conn)
+	mock.MockInteractiveTerminal.AssertCalled(t, "Connect")
+}