How to make cannon not TILT? (Minigame)

Hello! Currently working on minigames for my project. I encountered this issue in my code where the cannon can tilt. As you can see in the video below. Moving W,A,S,D is perfectly fine. But once you move Right / Left then go UP the cannon starts to tilt when you move back the opposing way. This can throw players off and make the minigame more complicated and have a wonky feeling to it. I tried coming up with a fix myself by only allowing one input per movement. Here is the video and i will give the cannon moving script.

local function moveCannon(key)
	while isMoving[key] do
		updateIndicator() -- This is just a the red ball you see. Where target is going to land.

		local currentCFrame = Cannon.PrimaryPart.CFrame  
		local newCFrame = currentCFrame  

		if key == "W" then
			newCFrame = currentCFrame * CFrame.Angles(math.rad(VERTICAL_MOVEMENT_SPEED), 0, 0)  
		elseif key == "A" then
			newCFrame = currentCFrame * CFrame.Angles(0, math.rad(HORIZONTAL_MOVEMENT_SPEED), 0)  
		elseif key == "S" then
			newCFrame = currentCFrame * CFrame.Angles(math.rad(-VERTICAL_MOVEMENT_SPEED), 0, 0)  
		elseif key == "D" then

			newCFrame = currentCFrame * CFrame.Angles(0, math.rad(-HORIZONTAL_MOVEMENT_SPEED), 0)  
		end

		newCFrame = CFrame.new(Cannon.PrimaryPart.Position) * newCFrame.Rotation

		TweenService:Create(Cannon.PrimaryPart, TweenInfo.new(.1), {CFrame = newCFrame}):Play()

		task.wait(0.1)  
	end
	isMovingFlag = false
end

local function moveCannon(key)
	while isMoving[key] do
		updateIndicator()

		local currentCFrame = Cannon.PrimaryPart.CFrame
		local newCFrame = currentCFrame.Position

		if key == "W" then
			newCFrame = newCFrame * CFrame.Angles(math.rad(VERTICAL_MOVEMENT_SPEED), 0, 0)
		elseif key == "A" then
			newCFrame = newCFrame * CFrame.Angles(0, math.rad(HORIZONTAL_MOVEMENT_SPEED), 0)
		elseif key == "S" then
			newCFrame = newCFrame * CFrame.Angles(math.rad(-VERTICAL_MOVEMENT_SPEED), 0, 0)
		elseif key == "D" then
			newCFrame = newCFrame * CFrame.Angles(0, math.rad(-HORIZONTAL_MOVEMENT_SPEED), 0)
		end

		local forwardVector = newCFrame.LookVector
		local upVector = Vector3.new(0, 1, 0)
		newCFrame = CFrame.fromMatrix(Cannon.PrimaryPart.Position, forwardVector, upVector)

		TweenService:Create(Cannon.PrimaryPart, TweenInfo.new(0.1), {CFrame = newCFrame}):Play()

		task.wait(0.1)
	end
	isMovingFlag = false
end

maybe you could try this but might not work not been coding for some time

Hmmmm still not working. Im trying to use your approach with the Matrix, and i am reading the document so im still messing with it. I will keep you posted if I can come up with anything.